百度一下
爬虫抓取豆瓣top250
,结果竟有70多页。
为什么豆瓣Top250如此受欢迎?由于它实在是太适合作爬虫入门练习了。git
几乎没有任何反爬限制,要抓取的电影相关内容也所有都在源码中(没有异步加载,JS动态修改DOM等状况)。github
原本计划抓取掘金热门文章来着,可是发现数据基本都是Ajax请求接口获取,因此仍是以豆瓣为例吧。api
由于第一份工做就是Python爬虫,因此对其余语言的爬虫框架也是比较感兴趣的。框架
爬虫说简单也简单,会发出Http请求、了解一些Html基本知识、可以将数据保存下来,就算是爬虫入门了。但爬虫说难也难,如何高效的编写爬虫、如何保证数据的准确和实效、如何应对各类反爬机制、以及如何在合规合法的状况下去获取数据。dom
在GitHub上搜了一圈Go语言相关的框架,发现Colly一枝独秀,竟有11.6k✨
。异步
重要的事情只说一遍: 必定要去看官方文档,这个好像不是官方的go-colly.org,可是也要浏览一遍才能够的。ide
挂一下官方example
里面的basic
示例吧。注释很详细,因此官方示例必定要看!!!学习
func main() { // Instantiate default collector c := colly.NewCollector( // Visit only domains: hackerspaces.org, wiki.hackerspaces.org colly.AllowedDomains("hackerspaces.org", "wiki.hackerspaces.org"), ) // On every a element which has href attribute call callback c.OnHTML("a[href]", func(e *colly.HTMLElement) { link := e.Attr("href") // Print link fmt.Printf("Link found: %q -> %s\n", e.Text, link) // Visit link found on page // Only those links are visited which are in AllowedDomains c.Visit(e.Request.AbsoluteURL(link)) }) // Before making a request print "Visiting ..." c.OnRequest(func(r *colly.Request) { fmt.Println("Visiting", r.URL.String()) }) // Start scraping on https://hackerspaces.org c.Visit("https://hackerspaces.org/") }
如图,咱们要作的就是:url
如图能够看到,当咱们处于第1页(非最后一页)时,span.next
元素下面是有a
元素的,里面的地址即为下一页。spa
当咱们翻到最后一页时,a
元素不见了。所以咱们能够根据是否有a
元素来判断是否是已经抓取彻底部数据了。
Colly中使用goquerySelector
来选择元素,也可使用XPath来作选择
,有兴趣的能够了解一下。这里咱们使用goquerySelector
。
下一页URL获取代码以下:
collector.OnHTML("div.paginator > span.next", func(element *colly.HTMLElement) { href, found := element.DOM.Find("a").Attr("href") // 若是有下一页,则继续访问 if found { element.Request.Visit(element.Request.AbsoluteURL(href)) } })
如图,咱们只须要查找到div.article > ol.grid_view
就找到了li
列表的直接父元素。而后再依次遍历li
节点便可。咱们所需的a
元素,在li
节点下面div.hd > a
的href
属性。
具体代码以下:
collector.OnHTML("ol.grid_view", func(element *colly.HTMLElement) { // 依次遍历全部的li节点 element.DOM.Find("li").Each(func(i int, selection *goquery.Selection) { href, found := selection.Find("div.hd > a").Attr("href") // 若是找到了详情页,则继续下一步的处理 if found { parseDetail(collector, href, writer) log.Println(href) } }) })
咱们要获取的内容:排名Idx,标题title,年份year,基本信息info,评分rating,地址url。
分析完页面Dom结构以后,整个抓取代码的编写就变得简单了起来。
具体信息获取代码以下:
collector.OnHTML("body", func(element *colly.HTMLElement) { selection := element.DOM.Find("div#content") idx := selection.Find("div.top250 > span.top250-no").Text() title := selection.Find("h1 > span").First().Text() year := selection.Find("h1 > span.year").Text() info := selection.Find("div#info").Text() info = strings.ReplaceAll(info, " ", "") info = strings.ReplaceAll(info, "\n", "; ") rating := selection.Find("strong.rating_num").Text() ...
可对抓取到的数据进行清洗、整理,而后入库等操做。本例仅将数据存储至csv文件。
抓取数据结果以下:
其实编写爬虫时,最耗时的是页面Dom结构分析的过程。代码编写只是整个抓取过程的实现部分,并不会耗费不少的时间。
若是耗费的不少的时间(伪装在说别人😄),那么你须要去看文档和官方示例了。
当你的才华和能力,不足以支撑你的梦想的时候,请静下心来学习。
欢迎留言交流~