思路:
- 观察目标网站(豆瓣)的请求体(url,method)和响应体(返回的是text/html,∴通过元素选择器获取目标值)
- 定义map集合存储爬取到值
- 对map集合进行值排序(通过struct结构体实现)
一. 所需包的整理:
net/http //发送网络请求
os //爬取的数据封装成文件
goquery //go语言的HTML解析器,可作用DOM树的节点Node,选择器
strconv //字符串和基本数据类型的转换包
sort //排序包
复制代码
二. 目标url解析:
https://movie.douban.com/top250?start=0&filter= //获取Top250在于参数start=n*25(n∈[0,9])
∴对只需进行for循环发送10次GET网络请求便可获取Top250的电影信息
复制代码
三. 目标值所在选择器:
电影名 --- .title:first-child
评分 --- .rating_num
复制代码
四. 发送GET网络请求:
client := &http.Client{} // 创建http客户端
req, _ := http.NewRequest("GET", urls, nil) //创建请求, 方法为GET
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36")//设置请求头
resp, err := client.Do(req) //发送请求
复制代码
五. goquery获取选择器的值:
doc, err := goquery.NewDocumentFromReader(resp.Body) //创建DOM文档
doc.Find(".title:first-child").Each(func(i int, s *goquery.Selection){}) //根据title类第一个子元素查找doc.Find(".rating_num").Each(func(i int, s *goquery.Selection){}) //根据rating_num类遍历查找更多详情API可参考 http://liyangliang.me/posts/2016/03/zhihu-go-insight-parsing-html-with-goquery/
复制代码
六. 创建文件和写入文件:
f,_ := os.Create("D:\\Timor\\jwt\\豆瓣Top250.txt") //在本地创建txt文件
f.WriteString(name + ":" + rate + "\n") //txt文件写入 电影名 : 评分 的行数据
复制代码
七. 代码:
package mainimport ( "fmt" "net/http" "github.com/PuerkitoBio/goquery" "strconv" "os" "sort")func main(){ m := make(map[string]string) f,_ := os.Create("D:\\Timor\\jwt\\豆瓣Top250.txt") defer f.Close() for i:=0;i<=250;i=i+25{ r := "https://movie.douban.com/top250?start="+strconv.Itoa(i)+"&filter=" url := (r) getUrl(url,m) } getMap(m,f)}func getUrl(urls string,m map[string]string){ name := make(map[int]string) rate := make(map[int]string) client := &http.Client{} req, _ := http.NewRequest("GET", urls, nil) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36") resp, err := client.Do(req) if err != nil { fmt.Println("error:", err) } defer resp.Body.Close() doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { fmt.Println("error:", err) } doc.Find(".title:first-child").Each(func(i int, s *goquery.Selection) { content := s.Text() name[i] = content //_,err := f.WriteString(content+" ") if err != nil { fmt.Println(err) } }) doc.Find(".rating_num").Each(func(i int, s *goquery.Selection) { rating := s.Text() rate[i] = rating if err != nil { fmt.Println(err) } }) for i, v := range name { m[v]=rate[i] }}func getMap(m map[string]string,f *os.File){ type str struct{ key string value string } var slice []str for k,v := range m{ slice = append(slice,str{k,v}) } sort.Slice(slice,func(i,j int) bool { return slice[i].value > slice[j].value }) for i,v := range slice{ f.WriteString(strconv.Itoa(i+1) + " : " + v.key + " "+ v.value + "\n") }}
复制代码
八. 代码git地址:
https://github.com/Timorls/dou-ban
复制代码
九. txt演示:
1 : 肖申克的救赎 9.7
2 : 控方证人 9.6
3 : 霸王别姬 9.6
4 : 美丽人生 9.6
5 : 阿甘正传 9.5
6 : 辛德勒的名单 9.5
7 : 人生果实 9.5
8 : 茶馆 9.5
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END