【Go程序】爬虫获取豆瓣Top250

之前在网上下载了一个minigame的开源项目,就是电影日历。里面有一项使用了豆瓣的API,获取豆瓣的Top250的电影。但是由于豆瓣的OpenAPI改版了,又不好申请到OpenAPI的资格,想想也不是什么非法的事情,就稍微搞几部电影名字嘛。

一般来讲,我们经常用Python写爬虫来解析数据,主要是因为request库和beautifulsoup4库过于好用了点,每次都会忘记怎么用,每次看个例子又能用起来了。今天想想要不用Go来实现把,毕竟现在的程序用go写起来也很顺手了。

这里需要用到一个库,goquery,功能和bs4一样,用于解析获取到的xml,然后net/http方法用于替代python的request库。动手把。

Go 复制代码
package main

import (
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"time"

	"github.com/PuerkitoBio/goquery"
)

// randomUserAgent 返回一个随机的 User-Agent 字符串
func randomUserAgent() string {
	userAgents := []string{
		"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
		"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
		"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36",
		"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0",
		"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0",
	}

	rand.Seed(time.Now().UnixNano())
	return userAgents[rand.Intn(len(userAgents))]
}

func fetch(url string) (*goquery.Document, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	userAgent := randomUserAgent()
	req.Header.Set("User-Agent", userAgent)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("request failed with status code: %d", resp.StatusCode)
	}
	defer resp.Body.Close()
	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		return nil, err
	}

	return doc, nil
}

func main() {
	baseURL := "https://movie.douban.com/top250"
	for page := 1; page <= 10; page++ { // 假设每页25部电影,共10页
		url := fmt.Sprintf("%s?start=%d&filter=", baseURL, (page-1)*25)
		doc, err := fetch(url)
		if err != nil {
			log.Fatal(err)
		}

		doc.Find(".item").Each(func(i int, s *goquery.Selection) {
			title := s.Find(".title").First().Text()
			rating := s.Find(".rating_num").First().Text()
			votes := s.Find(".star .pl").First().Prev().Text()

			fmt.Printf("Movie %d: %s, Rating: %s, Votes: %s\n", i+(page-1)*25+1, title, rating, votes)
		})
	}
}

得到结果如下

Go 复制代码
Movie 1: 肖申克的救赎, Rating: 9.7, Votes: 
Movie 2: 霸王别姬, Rating: 9.6, Votes: 
Movie 3: 阿甘正传, Rating: 9.5, Votes: 
Movie 4: 泰坦尼克号, Rating: 9.5, Votes: 
Movie 5: 千与千寻, Rating: 9.4, Votes: 
Movie 6: 这个杀手不太冷, Rating: 9.4, Votes: 
Movie 7: 美丽人生, Rating: 9.5, Votes: 
............

我们对代码解释一下:

这段 Go 代码是一个简单的网页爬虫,用于抓取豆瓣电影 Top 250 列表中的电影标题、评分和投票数。下面是代码的详细解释:

  1. 导入包:

main:主包。

fmt, log, math/rand, net/http, time:标准库包,分别用于格式化输出、日志记录、生成随机数、处理 HTTP 请求和时间操作。

"github.com/PuerkitoBio/goquery":一个用于解析 HTML 文档的第三方库。

  1. randomUserAgent 函数:

定义了一个字符串切片 userAgents,其中包含了多个不同的 User-Agent 字符串。

使用 rand.Seed(time.Now().UnixNano()) 初始化随机数生成器。

函数返回 userAgents 切片中的一个随机元素作为 User-Agent。

  1. fetch 函数:
  • 创建一个新的 HTTP GET 请求。
  • 设置请求头的 User-Agent 字段为一个随机值。
  • 使用 http.Client 发送请求并获取响应。
  • 检查 HTTP 响应状态码,如果不是 http.StatusOK(即 200 OK),则返回错误。
  • 使用 goquery.NewDocumentFromReader 从响应体创建一个 goquery.Document 对象。
  • 返回文档对象或错误。
  1. main 函数:
  • 定义了豆瓣电影 Top 250 的基础 URL。
  • 循环遍历 10 页(假设每页有 25 部电影)。
  • 构造每一页的完整 URL。
  • 调用 fetch 函数获取页面的 goquery.Document。
  • 使用 doc.Find(".item") 查找所有具有类 .item 的元素,这些元素代表单个电影条目。
  • 对于每个找到的电影条目,提取标题、评分和投票数。
  • 打印提取的信息。

代码中使用了 goquery 库来解析和选择 HTML 元素,以及 log.Fatal 来记录并终止程序在遇到错误时的运行。

相关推荐
SEO_juper9 小时前
hreflang 审计工具:外贸多语言站谷歌SEO的隐性杀手
开发语言·人工智能·爬虫·python·seo
深蓝电商API12 小时前
Firecrawl、ScrapeGraphAI:AI爬虫框架横评
人工智能·爬虫·firecrawl·scrapegraphai
小花皮猪14 小时前
从 Prompt 到结构化 JSON:如何利用 Bright Data 快速搭建 YouTube 监测工作流?
人工智能·爬虫·agent·数据采集
云老大-阿里云国际站代理商15 小时前
网站遇到恶意爬虫和CC攻击,阿里云国际站WAF与Bot管理怎么搭配
爬虫·阿里云·云计算
重生之高冷汉堡包16 小时前
Perplexity爬虫怎么做?2026常见方案对比、实操教程与问题排查
大数据·网络·爬虫·安全·ai
傻啦嘿哟16 小时前
设计类网站爬虫:爬取站酷+CNU设计作品,做灵感采集器
爬虫
深蓝电商API2 天前
LLM正在改变爬虫:Crawl4AI源码深度解析
爬虫·crawl4ai
Chengbei114 天前
JsOwl|AI 赋能 JS 敏感信息扫描器,AST + 正则、source‑map 源码还原、登录态爬虫输出交互式 HTML 报告
开发语言·javascript·网络·人工智能·爬虫·网络安全·自动化
远航计算机4 天前
AI 答案里的链接,为什么开始分等级了?
大数据·人工智能·爬虫·aigc
Novproxy_Z4 天前
爬虫任务被拦截:区分 IP 封禁、设备封禁、账号封禁
爬虫·网络协议·tcp/ip