Go 每日一库之 colly

Go 优雅的爬虫框架 - Colly Colly款用 Go 语言编写的优雅网络爬虫框架,速度快、灵活且易于使用配置可以写在里面,也可以写在外面。 阅读详情

简介

colly是用 Go 语言编写的功能强大的爬虫框架。它提供简洁的 API,拥有强劲的性能,可以自动处理 cookie&session,还有提供灵活的扩展机制。

首先,我们介绍colly的基本概念。然后通过几个案例来介绍colly的用法和特性:拉取 GitHub Treading,拉取百度小说热榜,下载 Unsplash 网站上的图片

快速使用

本文代码使用 Go Modules。

创建目录并初始化:

$ mkdir colly && cd colly
$ go mod init github.com/darjun/go-daily-lib/colly

安装colly库:

$ go get -u github.com/gocolly/colly/v2

使用:

package main

import (
  "fmt"

  "github.com/gocolly/colly/v2"
)

func main() {
  c := colly.NewCollector(
    colly.AllowedDomains("www.baidu.com" ),
  )

  c.OnHTML("a[href]", func(e *colly.HTMLElement) {
    link := e.Attr("href")
    fmt.Printf("Link found: %q -> %s\n", e.Text, link)
    c.Visit(e.Request.AbsoluteURL(link))
  })

  c.OnRequest(func(r *colly.Request) {
    fmt.Println("Visiting", r.URL.String())
  })

  c.OnResponse(func(r *colly.Response) {
    fmt.Printf("Response %s: %d bytes\n", r.Request.URL, len(r.Body))
  })

  c.OnError(func(r *colly.Response, err error) {
    fmt.Printf("Error %s: %v\n", r.Request.URL, err)
  })

  c.Visit("http://www.baidu.com/")
}

colly的使用比较简单:

首先,调用colly.NewCollector()创建一个类型为*colly.Collector的爬虫对象。由于每个网页都有很多指向其他网页的链接。如果不加限制的话,运行可能永远不会停止。所以上面通过传入一个选项colly.AllowedDomains("www.baidu.com")限制只爬取域名为www.baidu.com的网页。

然后我们调用c.OnHTML方法注册HTML回调,对每个有href属性的a元素执行回调函数。这里继续访问href指向的 URL。也就是说解析爬取到的网页,然后继续访问网页中指向其他页面的链接。

调用c.OnRequest()方法注册请求回调,每次发送请求时执行该回调,这里只是简单打印请求的 URL。

调用c.OnResponse()方法注册响应回调,每次收到响应时执行该回调,这里也只是简单的打印 URL 和响应大小。

调用c.OnError()方法注册错误回调,执行请求发生错误时执行该回调,这里简单打印 URL 和错误信息。

最后我们调用c.Visit()开始访问第一个页面。

运行:

$ go run main.go
Visiting http://www.baidu.com/
Response http://www.baidu.com/: 303317 bytes
Link found: "百度首页" -> /
Link found: "设置" -> javascript:;
Link found: "登录" -> https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F&sms=5
Link found: "新闻" -> http://news.baidu.com
Link found: "hao123" -> https://www.hao123.com
Link found: "地图" -> http://map.baidu.com
Link found: "直播" -> https://live.baidu.com/
Link found: "视频" -> https://haokan.baidu.com/?sfrom=baidu-top
Link found: "贴吧" -> http://tieba.baidu.com
...

colly爬取到页面之后,会使用goquery解析这个页面。然后查找注册的 HTML 回调对应元素选择器(element-selector),将goquery.Selection封装成一个colly.HTMLElement执行回调。

colly.HTMLElement其实就是对goquery.Selection的简单封装:

type HTMLElement struct {
  Name string
  Text string
  Request *Request
  Response *Response
  DOM *goquery.Selection
  Index int
}

并提供了简单易用的方法:

  • Attr(k string):返回当前元素的属性,上面示例中我们使用e.Attr("href")获取了href属性;

  • ChildAttr(goquerySelector, attrName string):返回goquerySelector选择的第一个子元素的attrName属性;

  • ChildAttrs(goquerySelector, attrName string):返回goquerySelector选择的所有子元素的attrName属性,以[]string返回;

  • ChildText(goquerySelector string):拼接goquerySelector选择的子元素的文本内容并返回;

  • ChildTexts(goquerySelector string):返回goquerySelector选择的子元素的文本内容组成的切片,以[]string返回。

  • ForEach(goquerySelector string, callback func(int, *HTMLElement)):对每个goquerySelector选择的子元素执行回调callback

  • Unmarshal(v interface{}):通过给结构体字段指定 goquerySelector 格式的 tag,可以将一个 HTMLElement 对象 Unmarshal 到一个结构体实例中。

这些方法会被频繁地用到。下面我们就通过一些示例来介绍colly的特性和用法。

GitHub Treading

我之前写过一个拉取GitHub Treading 的 API,用colly更方便:

type Repository struct {
  Author  string
  Name    string
  Link    string
  Desc    string
  Lang    string
  Stars   int
  Forks   int
  Add     int
  BuiltBy []string
}

func main() {
  c := colly.NewCollector(
    colly.MaxDepth(1),
  )


  repos := make([]*Repository, 0, 15)
  c.OnHTML(".Box .Box-row", func (e *colly.HTMLElement) {
    repo := &Repository{}

    // author & repository name
    authorRepoName := e.ChildText("h1.h3 > a")
    parts := strings.Split(authorRepoName, "/")
    repo.Author = strings.TrimSpace(parts[0])
    repo.Name = strings.TrimSpace(parts[1])

    // link
    repo.Link = e.Request.AbsoluteURL(e.ChildAttr("h1.h3 >a", "href"))

    // description
    repo.Desc = e.ChildText("p.pr-4")

    // language
    repo.Lang = strings.TrimSpace(e.ChildText("div.mt-2 > span.mr-3 > span[itemprop]"))

    // star & fork
    starForkStr := e.ChildText("div.mt-2 > a.mr-3")
    starForkStr = strings.Replace(strings.TrimSpace(starForkStr), ",", "", -1)
    parts = strings.Split(starForkStr, "\n")
    repo.Stars , _=strconv.Atoi(strings.TrimSpace(parts[0]))
    repo.Forks , _=strconv.Atoi(strings.TrimSpace(parts[len(parts)-1]))

    // add
    addStr := e.ChildText("div.mt-2 > span.float-sm-right")
    parts = strings.Split(addStr, " ")
    repo.Add, _ = strconv.Atoi(parts[0])

    // built by
    e.ForEach("div.mt-2 > span.mr-3  img[src]", func (index int, img *colly.HTMLElement) {
      repo.BuiltBy = append(repo.BuiltBy, img.Attr("src"))
    })

    repos = append(repos, repo)
  })

  c.Visit("https://github.com/trending")
  
  fmt.Printf("%d repositories\n", len(repos))
  fmt.Println("first repository:")
  for _, repo := range repos {
      fmt.Println("Author:", repo.Author)
      fmt.Println("Name:", repo.Name)
      break
  }
}

我们用ChildText获取作者、仓库名、语言、星数和 fork 数、今日新增等信息,用ChildAttr获取仓库链接,这个链接是一个相对路径,通过调用e.Request.AbsoluteURL()方法将它转为一个绝对路径。

运行:

$ go run main.go
25 repositories
first repository:
Author: Shopify
Name: dawn

百度小说热榜

网页结构如下:

各部分结构如下:

  • 每条热榜各自在一个div.category-wrap_iQLoo中;

  • a元素下div.index_1Ew5p是排名;

  • 内容在div.content_1YWBm中;

  • 内容中a.title_dIF3B是标题;

  • 内容中两个div.intro_1l0wp,前一个是作者,后一个是类型;

  • 内容中div.desc_3CTjT是描述。

由此我们定义结构:

type Hot struct {
  Rank   string `selector:"a > div.index_1Ew5p"`
  Name   string `selector:"div.content_1YWBm > a.title_dIF3B"`
  Author string `selector:"div.content_1YWBm > div.intro_1l0wp:nth-child(2)"`
  Type   string `selector:"div.content_1YWBm > div.intro_1l0wp:nth-child(3)"`
  Desc   string `selector:"div.desc_3CTjT"`
}

tag 中是 CSS 选择器语法,添加这个是为了可以直接调用HTMLElement.Unmarshal()方法填充Hot对象。

然后创建Collector对象:

c := colly.NewCollector()

注册回调:

c.OnHTML("div.category-wrap_iQLoo", func(e *colly.HTMLElement) {
  hot := &Hot{}

  err := e.Unmarshal(hot)
  if err != nil {
    fmt.Println("error:", err)
    return
  }

  hots = append(hots, hot)
})

c.OnRequest(func(r *colly.Request) {
  fmt.Println("Requesting:", r.URL)
})

c.OnResponse(func(r *colly.Response) {
  fmt.Println("Response:", len(r.Body))
})

OnHTML对每个条目执行Unmarshal生成Hot对象。

OnRequest/OnResponse只是简单输出调试信息。

然后,调用c.Visit()访问网址:

err := c.Visit("https://top.baidu.com/board?tab=novel")
if err != nil {
  fmt.Println("Visit error:", err)
  return
}

最后添加一些调试打印:

fmt.Printf("%d hots\n", len(hots))
for _, hot := range hots {
  fmt.Println("first hot:")
  fmt.Println("Rank:", hot.Rank)
  fmt.Println("Name:", hot.Name)
  fmt.Println("Author:", hot.Author)
  fmt.Println("Type:", hot.Type)
  fmt.Println("Desc:", hot.Desc)
  break
}

运行输出:

Requesting: https://top.baidu.com/board?tab=novel
Response: 118083
30 hots
first hot:
Rank: 1
Name: 逆天邪神
Author: 作者:火星引力
Type: 类型:玄幻
Desc: 掌天毒之珠,承邪神之血,修逆天之力,一代邪神,君临天下!  查看更多>

Unsplash

我写公众号文章,背景图片基本都是从 unsplash 这个网站获取。unsplash 提供了大量的、丰富的、免费的图片。这个网站有个问题,就是访问速度比较慢。既然学习爬虫,刚好利用程序自动下载图片。

unsplash 首页如下图所示:

网页结构如下:

但是首页上显示的都是尺寸较小的图片,我们点开某张图片的链接:

网页结构如下:

由于涉及三层网页结构(img最后还需要访问一次),使用一个colly.Collector对象,OnHTML回调设置需要格外小心,给编码带来比较大的心智负担。colly支持多个Collector,我们采用这种方式来编码:

func main() {
  c1 := colly.NewCollector()
  c2 := c1.Clone()
  c3 := c1.Clone()

  c1.OnHTML("figure[itemProp] a[itemProp]", func(e *colly.HTMLElement) {
    href := e.Attr("href")
    if href == "" {
      return
    }

    c2.Visit(e.Request.AbsoluteURL(href))
  })

  c2.OnHTML("div._1g5Lu > img[src]", func(e *colly.HTMLElement) {
    src := e.Attr("src")
    if src == "" {
      return
    }

    c3.Visit(src)
  })

  c1.OnRequest(func(r *colly.Request) {
    fmt.Println("Visiting", r.URL)
  })

  c1.OnError(func(r *colly.Response, err error) {
    fmt.Println("Visiting", r.Request.URL, "failed:", err)
  })
}

我们使用 3 个Collector对象,第一个Collector用于收集首页上对应的图片链接,然后使用第二个Collector去访问这些图片链接,最后让第三个Collector去下载图片。上面我们还为第一个Collector注册了请求和错误回调。

第三个Collector下载到具体的图片内容后,保存到本地:

func main() {
  // ... 省略
  var count uint32
  c3.OnResponse(func(r *colly.Response) {
    fileName := fmt.Sprintf("images/img%d.jpg", atomic.AddUint32(&count, 1))
    err := r.Save(fileName)
    if err != nil {
      fmt.Printf("saving %s failed:%v\n", fileName, err)
    } else {
      fmt.Printf("saving %s success\n", fileName)
    }
  })

  c3.OnRequest(func(r *colly.Request) {
    fmt.Println("visiting", r.URL)
  })
}

上面使用atomic.AddUint32()为图片生成序号。

运行程序,爬取结果:

异步

默认情况下,colly爬取网页是同步的,即爬完一个接着爬另一个,上面的 unplash 程序就是如此。这样需要很长时间,colly提供了异步爬取的特性,我们只需要在构造Collector对象时传入选项colly.Async(true)即可开启异步:

c1 := colly.NewCollector(
  colly.Async(true),
)

但是,由于是异步爬取,所以程序最后需要等待Collector处理完成,否则早早地退出main,程序会退出:

c1.Wait()
c2.Wait()
c3.Wait()

再次运行,速度快了很多????。

第二版

向下滑动 unsplash 的网页,我们发现后面的图片是异步加载的。滚动页面,通过 chrome 浏览器的 network 页签查看请求:

请求路径/photos,设置per_pagepage参数,返回的是一个 JSON 数组。所以有了另一种方式:

定义每一项的结构体,我们只保留必要的字段:

type Item struct {
  Id     string
  Width  int
  Height int
  Links  Links
}

type Links struct {
  Download string
}

然后在OnResponse回调中解析 JSON,对每一项的Download链接调用负责下载图像的CollectorVisit()方法:

c.OnResponse(func(r *colly.Response) {
  var items []*Item
  json.Unmarshal(r.Body, &items)
  for _, item := range items {
    d.Visit(item.Links.Download)
  }
})

初始化访问,我们设置拉取 3 页,每页 12 个(和页面请求的个数一致):

for page := 1; page <= 3; page++ {
  c.Visit(fmt.Sprintf("https://unsplash.com/napi/photos?page=%d&per_page=12", page))
}

运行,查看下载的图片:

限速

有时候并发请求太多,网站会限制访问。这时就需要使用LimitRule了。说白了,LimitRule就是限制访问速度和并发量的:

type LimitRule struct {
  DomainRegexp string
  DomainGlob string
  Delay time.Duration
  RandomDelay time.Duration
  Parallelism    int
}

常用的就Delay/RandomDelay/Parallism这几个,分别表示请求与请求之间的延迟,随机延迟,和并发数。另外必须指定对哪些域名施行限制,通过DomainRegexpDomainGlob设置,如果这两个字段都未设置Limit()方法会返回错误。用在上面的例子中:

err := c.Limit(&colly.LimitRule{
  DomainRegexp: `unsplash\.com`,
  RandomDelay:  500 * time.Millisecond,
  Parallelism:  12,
})
if err != nil {
  log.Fatal(err)
}

我们设置针对unsplash.com这个域名,请求与请求之间的随机最大延迟 500ms,最多同时并发 12 个请求。

设置超时

有时候网速较慢,colly中使用的http.Client有默认超时机制,我们可以通过colly.WithTransport()选项改写:

c.WithTransport(&http.Transport{
  Proxy: http.ProxyFromEnvironment,
  DialContext: (&net.Dialer{
    Timeout:   30 * time.Second,
    KeepAlive: 30 * time.Second,
  }).DialContext,
  MaxIdleConns:          100,
  IdleConnTimeout:       90 * time.Second,
  TLSHandshakeTimeout:   10 * time.Second,
  ExpectContinueTimeout: 1 * time.Second,
})

扩展

colly在子包extension中提供了一些扩展特性,最最常用的就是随机 User-Agent 了。通常网站会通过 User-Agent 识别请求是否是浏览器发出的,爬虫一般会设置这个 Header 把自己伪装成浏览器。使用也比较简单:

import "github.com/gocolly/colly/v2/extensions"

func main() {
  c := colly.NewCollector()
  extensions.RandomUserAgent(c)
}

随机 User-Agent 实现也很简单,就是从一些预先定义好的 User-Agent 数组中随机一个设置到 Header 中:

func RandomUserAgent(c *colly.Collector) {
  c.OnRequest(func(r *colly.Request) {
    r.Headers.Set("User-Agent", uaGens[rand.Intn(len(uaGens))]())
  })
}

实现自己的扩展也不难,例如我们每次请求时需要设置一个特定的 Header,扩展可以这么写:

func MyHeader(c *colly.Collector) {
  c.OnRequest(func(r *colly.Request) {
    r.Headers.Set("My-Header", "dj")
  })
}

Collector对象调用MyHeader()函数即可:

MyHeader(c)

总结

colly是 Go 语言中最流行的爬虫框架,支持丰富的特性。本文对一些常用特性做了介绍,并辅之以实例。限于篇幅,一些高级特性未能涉及,例如队列,存储等。对爬虫感兴趣的可去深入了解。

大家如果发现好玩、好用的 Go 语言库,欢迎到 Go 每日一库 GitHub 上提交 issue????

参考

  1. Go 每日一库 GitHub:https://github.com/darjun/go-daily-lib

  2. Go 每日一库之 goquery:https://darjun.github.io/2020/10/11/godailylib/goquery/

  3. 用 Go 实现一个 GitHub Trending API:https://darjun.github.io/2021/06/16/github-trending-api/

  4. colly GitHub:https://github.com/gocolly/colly

我的博客:https://darjun.github.io

欢迎关注我的微信公众号【GoUpUp】,共同学习,一起进步~

超越音频!STM32 SAI接口在AD7768高速ADC采集中的妙用(含PCB布局指南) 本文深入探讨了如何将STM32的SAI接口应用于AD7768高速ADC的数据采集系统,超越了其传统的音频应用范畴。文章详细解析了SAI协议与ADC时序的匹配方法,提供了从CubeMX配置、DMA数据搬运到关键PCB布局指南的完整实战方案,旨在帮助工程师实现稳定、高精度的工业级高速数据采集。 阅读详情

相关推荐

Go语言爬虫框架:Colly 的详细使用及对应采集案例

前言:collyGo 实现的比较有名的款爬虫框架,而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的。它的主要特点是轻量、快速,设计非常优雅,并且分布式的支持也非常简单,易于扩展。框架简介:基于colly框架及net/http进行封装,实现的款可配置分布式爬虫架构。使用者只需要配置解析、并发数、入topic、请求方式、请求url等参数即可,其他代码类似于scrapy,不需要单独编写。github地址:colly特性干净的API快速(单核>1k请求/秒)

数据知道的博客 1万+

使用 CollyGolang 中进行网页抓取的步骤

Golang 是最强大的网络爬虫工具之。而 Colly 在使用 Go 时提供了很大帮助。阅读这篇博文,了解有关 Colly 的最详细的信息,并学习如何使用 Colly 抓取网站。

wellshake的博客 3466

uniapp - 详解APP端免费人脸识别+人脸核身+人脸对比+活体检测插件功能完整源码,uniAPP纯前端实现不依赖后端API接口或第三方付费人脸识别功能示例(仅兼容安卓app与苹果ios App)

uniapp免费人脸认证功能,uniapp APP开发活体人脸识别,UniApp人脸识别与活体检测,人脸核身uni-app插件 活体检测 人脸对比 人脸识别 人脸认证 身份证件,uni-app人脸核身,如何在app端实现免费人脸识别教程,人脸核身uni-app插件活体检测,uniapp安卓ios百度人脸识别、活体检测、人脸采集APP原生插件,详细实现人脸识别和活体检测功能,实时监测人脸是否进入区域及动作是否正确播报,提供提供实名认证、身份证识别、有没有免费的,api,活体检测,人脸信息采集、刷脸扫脸认证示例

🏆 前端领域优质创作者 4342

Go colly爬虫框架精简高效【杠杠的】入门到精通

爬虫框架中,各中流行的编程语言都有自己热门框架,python中的selenium、Scrapy、PySpider等,Java中的Nutch、Crawler4j、WebMagic、WebCollector等。golang中colly使用Go语言编写的功能强大的爬虫框架,api简洁、性能强大、并发性高,github star 接近20K。

small_to_large的博客 4326

gocolly简介

0x00 gocolly是使用golang实现的个爬虫。之前在爬某些网页的时候做过简单应用,最近在爬某电商网站的时候,发现关于这个还挺有意思,所以趁年前有时间,看了下源码实现。 gocolly内部依赖的是http.Client与goquery。其中goquery的语法和jquery相同,整个流程比较简单。 0x01 gocolly的使用很简单,具体可以看给出的些例子。 套路般就是设置相关的...

weixin_43787608的博客 4984

Go 每日goquery

简介goquery是用 Go 语言编写的个类似于 jQuery 的。它基于 HTML 解析net/htmlCSS cascadia,提供与 jQuery 相近的接口。Go 著...

darjun的博客 662

goquery php,Go 每日goquery

简介goquery是用 Go 语言编写的个类似于 jQuery 的。它基于 HTML 解析net/htmlCSS cascadia,提供与 jQuery 相近的接口。Go 著名的爬虫框架colly就是基于 goquery 的。快速使用本文代码使用 Go Modules。创建目录并初始化:$ mkdir goquery && cd goquery$ go mod init...

weixin_34161139的博客 297

爬虫如何监听插件_Go 爬虫之 colly 从入门到不放弃指南

Go语言中文网,致力于每日分享编码、开源等知识,欢迎关注我,会有意想不到的收获!最近发现知乎上感兴趣的问题越来越少,于是准备聚合下其他平台技术问答,比如 segmentfault、stackoverflow 等。要完成这个工作,肯定是离不开爬虫的。我就顺便抽时间研究了 Go款爬虫框架 colly。概要介绍collyGo 实现的比较有名的款爬虫框架,而且 Go 在高并发和分布式场景的优...

weixin_33180221的博客 245

GoCN酷Go推荐」Go 语言爬虫神器 gocolly/colly

推荐背景日常业务开发中常会遇到些采集整理互联网数据信息的业务需求,单纯靠人力进行信息采集,不仅低效繁琐,搜集的成本也会提高,此时就用爬虫手段来对数据进行自动采集降低完成业务所需的人力成本...

Go中国 739

Github每日精选(第75期):colly 爬取网站所有的数据

对于个爬取网站的程序,需要注意几点东西,程序能够自动的获取该爬取的网站,不断的探测下去,把整个网站都全部爬取完成。,您可以轻松地从网站中提取结构化数据,这些数据可用于广泛的应用,如数据挖掘、数据处理或存档。提供了个干净的接口来编写任何类型的爬虫。是个优雅的 Golang 爬虫框架。这是个简单的爬取qq.com的代码。github上的地址在。

haleycat的博客 1501

go每日新闻(2021-07-02)——你真的了解 Load Balance 嘛

每日谚:If you feel comments are unclear or hard to write concisely, reconsider your API design. go中文网每日资讯--2021-07-02 Go语言中文网 全面分析Uber的高性能日志Zap 听说Mutex源码是出名的不好看,我不信,来试下 二、亚军进化史 Go技术日报(2021-07-01)——Redis 和 Golang 的可扩展事件流 三、polarisxu 惊呆了!Go 代码的第次提交.

韩亚军的博客 557

go每日新闻--2020-05-18

go语言中文网(每日资讯)_2020-05-18 Go语言中文网 字节跳动自研的 Go RPC 框架 KiteX 核心技术讲解 Go 语言 Web 编程系列 —— 通过 Request 读取 HTTP 请求报文 聊天机器人训练语料获取之colly爬虫 Go语言进阶之路(八):正则表达式 二、亚军进化史 Go技术日报(2020-05-17) 三、xueyuanjun Go 语言 Web 编程系列(十二)—— 通过 Request 读取 HTTP 请求报文 四、火丁笔记 分布式

韩亚军的博客 821

Go 1.18泛型:好的、坏的、丑的 | Gopher Daily (2021.12.25) ʕ◔ϖ◔ʔ

每日谚:In Go, constants are mathematically precise.祝各位Gopher们圣诞节快乐!Go技术生态Go 1.18泛型:好的、坏的、丑的 - ht...

TonyBai 342

半小时实现go 爬虫

1、Quick Start 只需三步,你就可以部署个爬取 gocn 网站的所有新闻的爬虫 第步,你需要去 github 上生成个自己的 token Settings ——> Developer settings ——> Personal access tokens ——> Generate new token 然后,配置自己的环境变量 export GITHUB_TOKEN...

diubrother的博客 919

Colly 使用教程

Colly 使用教程 【免费下载链接】colly Elegant Scraper and Crawler Framework for Golang 项目地址: https://gitcode.com/gh_mirrors/co/c...

gitblog_01198的博客 1394

介绍个基于 Go 语言的爬虫框架 colly

大家好,我是TheWeiJun。很高兴又和大家见面了,国庆假期马上就要结束了,在国庆假期里小编看了下colly框架,故这篇文章中将提到colly的使用及分析;欢迎各位读者多多阅读与交流!特别声明:本公众号文章只作为学术研究,不作为其它不法用途;如有侵权请联系作者删除。这是「进击的Coder」的第728篇技术分享作者:TheWeiJun来源:逆向与爬虫的故事目录colly框架简介...

静觅 3003

GoColly:打造高效、智能的网页爬取利器,掌握数据世界的钥匙

这只是 Colly 的基本用法示例,您可以根据自己的需求使用更多的 Colly API,例如设置请求头、处理 Cookie、处理表单提交等。通过 Colly 的灵活性和丰富的功能,您可以编写出强大的网络爬虫和数据抓取程序。通过项目测试并逐步调整,并结合对目标服务器的了解,您可以找到适合每个收集器的合适并发度,以平衡爬取效率和对服务器的负载。需要注意的是,Scrapy 作为个成熟的 Python 爬虫框架,具有广泛的用户基础、丰富的文档和社区支持。根据响应时间的变化,可以调整并发度。

代码炼金术 3885

Go 爬虫之 colly 从入门到不放弃指南

collyGo 实现的比较有名的款爬虫框架,而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的。它的主要特点是轻量、快速,设计非常优雅,并且分布式的支持也非常简单,易于扩展。读完 colly 的官方文档会发现,虽然它的文档简陋无比,但应该介绍的内容基本上都涉及到了。如果有部分未涉及的内容,我也在本文之中做了相关的补充。之前在使用 Go 的elastic包时,同样也是文档少的可怜,但简单读下源码,就能立刻明白了该如何去使用它。或许这就是 Go 的大道至简吧。

我是波罗学 2709

Colly官方文档入门教程

Colly 的设计非常模块化,通过 Collector 组件管理请求和响应,通过中间件和事件处理器进行灵活的定制。这种设计使得 Colly 成为个高效且易于扩展的网络爬虫框架。

学海无涯 2794

【亲测免费】 **Colly爬虫框架下载与安装教程**

Colly爬虫框架下载与安装教程 【免费下载链接】colly Elegant Scraper and Crawler Framework for Golang 项目地址: https://gitcode.com/gh_mirror...

gitblog_01256的博客 2175

电商-电商平台-电商平台源码-电商平台java代码-基于springboot的电商平台-电商项目-电商项目代码-电商代码-代码

电商-电商平台-电商平台源码-电商平台java代码-电商平台设计与实现-基于springboot的电商平台-基于Web的电商平台设计与实现-电商网站-电商网站源码-电商网站java代码-电商项目-电商项目代码-电商系统-电商系统源码-电商管理系统-电商管理系统java代码-电商代码1、技术栈:java,springboot,vue,ajax,maven,mysql,MyBatisPlus等开发语言:Java框架:SpringBootJDK版本:JDK1.8数据:mysql 5.7数据工具:SQLyog/Navicat开发软件:eclipse/myeclipse/ideaMaven包:Maven浏览器:谷歌浏览器2、系统的实现用户信息图片素材视频素材摘 要I目 录III第1章 绪论11.1选题动因11.2背景与意义1第2章 相关技术介绍32.1 MySQL数据32.2 Vue前端技术32.3 B/S架构模式42.4 ElementUI介绍4第3章 系统分析53.1 可行性分析53.1.1技术可行性

上一篇: Go 每日一库之 resty
下一篇: Go 每日一库之 termtables
darjun
博客等级 码龄10年 107粉丝 82原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值