python作为爬虫利器,抓网页的方式简洁明了。爬成百上千的网页,都可以很快爬完,但是如果网页数量上万呢?速度就不能忍受了。

这是一段爬取页面的函数,用了requests库:1

2

3

4

5import requests

def (url):

req = requests.get(url,header = header)

content = req.text

return content

这种方式,对于url较少时可以使用,但是如果url量很大,比如10w+,抓取过程就十分漫长,如果用多线程,由于GIL限制,实际上效率并不高,如果用多进程,就没有GIL限制,但是多进程也有其自己的限制:相比线程更加笨重、切换耗时更长,并且在python的多进程下,进程数量不推荐超过CPU核心数(一个进程只有一个GIL,所以一个进程只能跑满一个CPU),因为一个进程占用一个CPU时能充分利用机器的性能,但是进程多了就会出现频繁的进程切换,反而得不偿失.不过特殊情况(特指IO密集型任务)下,多线程是比多进程好用的。

举个例子:给你200W条url,需要你把每个url对应的页面抓取保存起来,这种时候,单单使用多进程,效果肯定是很差的。为什么呢?

例如每次请求的等待时间是2秒,那么如下(忽略cpu计算时间):

单进程+单线程

需要2秒*200W=400W秒==1111.11个小时==46.3天,这个速度明显是不能接受的

单进程+多线程

例如我们在这个进程中开了10个多线程,比1中能够提升10倍速度,也就是大约4.63天能够完成200W条抓取,请注意,这里的实际执行是:线程1遇见了阻塞,CPU切换到线程2去执行,遇见阻塞又切换到线程3等等,10个线程都阻塞后,这个进程就阻塞了,而直到某个线程阻塞完成后,这个进程才能继续执行,所以速度上提升大约能到10倍(这里忽略了线程切换带来的开销,实际上的提升应该是不能达到10倍的),但是需要考虑的是线程的切换也是有开销的,所以不能无限的启动多线程(开200W个线程肯定是不靠谱的)

多进程+多线程

这里就厉害了,一般来说也有很多人用这个方法,多进程下,每个进程都能占一个cpu,而多线程从一定程度上绕过了阻塞的等待,所以比单进程下的多线程又更好使了,例如我们开10个进程,每个进程里开20W个线程,执行的速度理论上是比单进程开200W个线程快10倍以上的(为什么是10倍以上而不是10倍,主要是cpu切换200W个线程的消耗肯定比切换20W个进程大得多,考虑到这部分开销,所以是10倍以上)。

还有更好的方法吗?答案是肯定的,它就是:

协程

使用它之前我们先讲讲what/why/how(它是什么/为什么用它/怎么使用它)

what:

协程是一种用户级的轻量级线程。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:

协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

在并发编程中,协程与线程类似,每个协程表示一个执行单元,有自己的本地数据,与其它协程共享全局数据和其它资源。

why:

目前主流语言基本上都选择了多线程作为并发设施,与线程相关的概念是抢占式多任务(Preemptive multitasking),而与协程相关的是协作式多任务。

不管是进程还是线程,每次阻塞、切换都需要陷入系统调用(system call),先让CPU跑操作系统的调度程序,然后再由调度程序决定该跑哪一个进程(线程)。

而且由于抢占式调度执行顺序无法确定的特点,使用线程时需要非常小心地处理同步问题,而协程完全不存在这个问题(事件驱动和异步程序也有同样的优点)。

因为协程是用户自己来编写调度逻辑的,对CPU来说,协程其实是单线程,所以CPU不用去考虑怎么调度、切换上下文,这就省去了CPU的切换开销,所以协程在一定程度上又好于多线程。

how:

python里面怎么使用协程?使用gevent,使用方法:看这里.

所以使用协程,可以不受线程开销的限制,我尝试过一次把20W条url放在单进程的协程里执行,完全没问题。

所以最推荐的方法,是多进程+协程(可以看作是每个进程里都是单线程,而这个单线程是协程化的)

多进程+协程下,避开了CPU切换的开销,又能把多个CPU充分利用起来,这种方式对于数据量较大的爬虫还有文件读写之类的效率提升是巨大的。

具体方式如下:1

2

3

4

5

6

7

8

9

10

11

12import requests

import gevent

from gevent import monkey;monkey.patch_all()

def (url):

req = requests.get(url,header = header)

content = req.text

return content

if __name__ == '__main__':

geventjobs = []

for url in urllist:

geventjobs.append(gevent.spawn(fetchPage,url))

python从网址爬图片协程_python 用 gevent 协程抓取海量网页相关推荐

  1. python从网址爬图片协程_python协程gevent案例 爬取斗鱼图片过程解析

    分析 分析网站寻找需要的网址 用谷歌浏览器摁F12打开开发者工具,然后打开斗鱼颜值分类的页面,如图: 在里面的请求中,最后发现它是以ajax加载的数据,数据格式为json,如图: 圈住的部分是我们需要 ...

  2. python从网址爬图片协程_python协程gevent案例:爬取斗鱼美女图片

    分析 分析网站寻找需要的网址 用谷歌浏览器摁F12打开开发者工具,然后打开斗鱼颜值分类的页面,如图: 在里面的请求中,最后发现它是以ajax加载的数据,数据格式为json,如图: 圈住的部分是我们需要 ...

  3. python从网址爬图片协程_Python爬虫多任务协程爬取虎牙MM图片

    查看: 4420|回复: 241 [作品展示] Python爬虫多任务协程爬取虎牙MM图片 电梯直达 发表于 2019-4-17 21:35:47 | 只看该作者 |倒序浏览 |阅读模式 马上注册,结 ...

  4. python爬取网页停止_如何使用Python抓取雪球网页?

    我想使用beautifulsoup或者其他的python包 抓取 雪球网页上面的一些组合,因为雪球网的组合持仓变动的时候,雪球网不会给提示,比如说,我想抓取这个http://xueqiu.com/P/ ...

  5. Python爬虫抓取指定网页图片代码实例

    更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接:好看站 http://www.nrso.net/ 高州阳光论坛https://www.hnthzk.com/ 想 ...

  6. python网页数据存入数据库_python网络爬虫抓取动态网页并将数据存入数据库MySQL...

    简述 以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网 ...

  7. python爬虫抓取动态网页数据_python网络爬虫抓取ajax动态网页数据:以抓取KFC门店地址为例...

    一,尝试用BeautifulSoup抓取 先打开KFC网站门店列表页面:http://www.kfc.com.cn/kfccda/storelist/index.aspx 可以看到门店列表如下图: 打 ...

  8. 雪球python爬虫炒股_如何使用 Python 抓取雪球网页?

    我想使用beautifulsoup或者其他的python包 抓取 雪球网页上面的一些组合,因为雪球网的组合持仓变动的时候,雪球网不会给提示,比如说,我想抓取这个http://xueqiu.com/P/ ...

  9. 如何抓取各种网页上的图片

    1.普通网页图片,如何抓取 要抓取普通网页上的图片,可以使用Python编写代码.以下是一个示例代码片段,可以帮助你了解如何开始编写此类代码: ```python import requests fr ...

最新文章

  1. 簡單安裝軟件 GNU Linux
  2. P5367 【模板】康托展开
  3. iOS上传头像, 相册权限,相册权限,拍照上传,相册选择图片,拍照页面语言设置,保存到相册...
  4. Scala 学习笔记
  5. 飞鸽传书确保服务数据的安全可靠
  6. Git学习总结(11)——Git撤销操作详解
  7. 【转】【重要】破除“系统学习”的情结
  8. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)签到题E Evil Coordinate
  9. .Net中加密解密相关知识
  10. Use AVAudioPlayer in OperationQueue
  11. 如何使用qq截图工具,却能保证系统不会随意放大
  12. ZeroTier + win10 远程桌面(替代TeamViewer)
  13. 【Android Jetpack】彻底弄清Navigation的BackStack如何变化
  14. easyexcel 检查表头是否匹配_利用easyexcel生成excel文件-自定义表头与数据栏对应的处理方式...
  15. Python之科赫曲线绘制
  16. Python自动化:根据模板批量生成含指定数据的word文档
  17. c++小游戏代码(免费)
  18. Silverlight游戏特效开发(一) : 制作人物光环效果
  19. 听完网易大佬描述 “ 软件测试工程师的一生 ”,我哭了!
  20. word页眉页码目录

热门文章

  1. 用python画渐变的圆_Python成像库(PIL)绘图 – 带渐变的圆角矩形
  2. 怎么关闭电脑开机自动启动的程序_软件自动开启很烦人?如何彻底关掉Mac电脑开机自动开启的应用程序?...
  3. Python创建进程、线程的两种方式
  4. 《黑客帝国》中的代码雨让人身临其境!利用Python轻松实现!
  5. Python+Appium实现APP自动化测试
  6. Python高级——用多线程实现TCP服务端
  7. gridview 万能分页代码
  8. ListView(1)
  9. leetcode —— 965. 单值二叉树
  10. leetcode - 1143. 最长公共子序列