Go语言并发爬虫的具体实现
作者:小生凡一 发布时间:2024-02-22 10:35:31
标签:Go语言,并发,爬虫
写在前面
这篇文章主要让大家明白
多线程爬虫
,因为go语言实现并发是很容易的。
这次的服务端,是我们之前搭建的电子商城平台,所以我们不担心ip被封
之类的问题。
而实际生产环境中,其实我们都是用python
爬虫的。python实现多线程也很简单。
这次我们可以试试新玩法,试试go语言的并发爬虫。
主要是爬取第一页的商品,爬取十次,比较单线程和多线程的时间。
1. 单线程爬虫
定义一个用户
var Client http.Client
主函数
func main() {
url := "http://localhost:3000/api/v1/products"
start := time.Now()
for i := 0; i < 10; i++ {
Spider(url, i)
}
elapsed := time.Since(start)
fmt.Printf("Time %s", elapsed)
}
爬取函数
func Spider(url string, i int) {
reqSpider, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
reqSpider.Header.Set("content-length", "0")
reqSpider.Header.Set("accept", "*/*")
reqSpider.Header.Set("x-requested-with", "XMLHttpRequest")
respSpider, err := Client.Do(reqSpider)
if err != nil {
log.Fatal(err)
}
bodyText, _ := ioutil.ReadAll(respSpider.Body)
var result Result
_ = json.Unmarshal(bodyText, &result)
fmt.Println(i,result.Data)
}
运行时间为:651.8207ms
2. 多线程爬虫
2.1 channel main函数
我们构造一个无缓冲的通道,来阻塞主进程,等待子进程的执行。
func main() {
url := "http://localhost:3000/api/v1/products"
ch := make(chan bool)
start := time.Now()
for i := 0; i < 10; i++ {
go Spider(url, ch, i)
}
for i := 0; i < 10; i++ {
<-ch
}
elapsed := time.Since(start)
fmt.Printf("Time %s", elapsed)
}
最后记得在爬虫的结束的时候,把值写入到通道中,不然会一直阻塞主进程
运行时间:187.7921ms
比之前快了非常多。
2.2 sync.WaitGroup
定义一个进程组并加10个进程
var wg sync.WaitGroup
wg.Add(10)
开辟十个goruntime
for i := 0; i < 10; i++ {
go func(i int) {
defer wg.Done()
SpiderWaitGroup(url,i)
}(i)
}
阻塞主进程
wg.Wait()
结果:64.5246ms
3. 源码地址
GitHub地址:https://github.com/CocaineCong/Go-Spider-Demo
NormalStart(url) // 单线程爬虫
ChannelStart(url) // Channel多线程爬虫
WaitGroupStart(url) // Wait 多线程爬虫
其实多线程的两种都差不多的,只是有时候会因为机器的原因而导致一些误差。
来源:https://blog.csdn.net/weixin_45304503/article/details/121885673
0
投稿
猜你喜欢
- 今天在用python3+ImageFont输出中文时,结果显示乱码# coding:utf-8from PIL import Image,
- 彩色圆环更漂亮A.课程内容通过绘制彩色的圆环来学习列表的使用方法、颜色的使用技巧等,通过学习掌握python程序绘制彩色的图形的方法。B.知
- 本文实例为大家分享了python+logging+yaml实现日志分割的具体代码,供大家参考,具体内容如下1、建立log.yaml文件ver
- Pygame是跨平台Python模块,专为电子游戏设计,包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言
- 本文实例讲述了php获取客户端IP及URL的方法。分享给大家供大家参考,具体如下:function getonlineip(){//获取用户
- 1.简介 EXCEPT和INTERSECT运算符使您可以比较两个或多个SELECT语句的结果并返回非重复值。 2.区别 EXCEPT运算符返
- rpclib 是一个非常好用的 python webservice 库,可以动态的生成 wsdl, 不过这个项目已经基本停止,并被一个新的项
- 引文: 长期以来,多媒体信息在计算机中都是以文件形式存放,由操作系统管理的,但是随着计算机网络,分布式计算的发展,对多媒体信息进行高效的管理
- 提起python做网络爬虫就不得不说到强大的组件urllib2。在python中正是使用urllib2这个组件来抓取网页的。urllib2是
- 链表一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结
- 本文实例分析了python动态性强类型用法。分享给大家供大家参考。具体如下:Python变量声明和定义与C#不同,Python在使用变量之前
- 本文实例讲述了JS实现仿新浪微博发布内容为空时提示功能。分享给大家供大家参考。具体如下:这里使用JavaScript模拟新浪微博的一个功能,
- 1. go的依赖管理发展GOPATH 所有的依赖都放置在同一路径下,可以复用下载的依赖,但是当不同项目需要依赖不同版本的依赖时,就很容易出现
- 一、VS2008工程设置工作 首先,建立一个windows应用程序的工程,将C/C++->预处理器->预处理器定义下的_WIND
- 不得不承认,傲游在用户体验方面是做得比较好的,所以它的用户群非常大。也正因为如此,它的某些不好的特性也造成了开发人员不可忽略的浏览器兼容问题
- 效果图:图(1) 原始图图(2) 缩小后图(3) 放大后代码如下:<!DOCTYPE html><html> <
- 假设要实现一个存放多种类型数据结构的对象,比如一个存放算术操作数和操作符的树结点,需要存放包含一元操作符、二元操作符和数字类型的结点clas
- lambda函数是一种小的匿名函数。lambda语法lambda函数:lambda [arg1 [,arg2,...[,argn]]] :
- Pytorch的backward()函数假若有多个loss函数,如何进行反向传播和更新呢? x = torch.tensor(2.0, re
- 示例如下:function addFileToZip($path,$zip){ $handler=opendir($path);