如何实现一个高效率的爬虫?

2014-04-08 14:31:08 +08:00
 hellove1985
简单描述一下场景:
现在有200w左右的ip,任务是把这写ip对应的web服务的首页抓取下来(大概有1/3的ip没有web服务)

我用gevent和urllib2简单写了个爬虫,在开发机用40wip做测试,耗时2021s,开发机下载顶峰速度为4m/s ,上传速度为600k/s,测试爬虫的时候,爬虫发出的请求速度在100-300k之间,下载数据速度在300k-1200k之间,cpu没占满,内存也没满。

请问大家,如何提升爬虫带宽的占用率?
10155 次点击
所在节点    Python
8 条回复
mclxly
2014-04-08 15:52:46 +08:00
之前用PHP和C分别实现过。PHP长时间运行好像有内存泄漏,效率也不高。后用C重写,库使用curl(multi interface模式)+libevent,测试可以达到下载峰值,有少部分失败请求。
hellove1985
2014-04-08 16:04:03 +08:00
@mclxly 谢谢回复,我忘记说了,在测试一个实际存在的站点的时候(一个ip抓取20w次首页),测试程序也可以达到下载顶峰,在描述的场景下,就不行。。。。
mclxly
2014-04-08 16:12:56 +08:00
@hellove1985 这样的话,可以试试一个程序测试是否有web访问,一个程序专门下载。
codingpp
2014-04-08 17:33:43 +08:00
如果使用异步模式下载网页,应该很容易达到下载峰值吧
类似这样子

from twisted.web.client import getPage
from twisted.python.util import println
from twisted.internet import defer, reactor

def getPages():
i = 0
while i < 1000:
url = 'http://127.0.0.1:8081'
getPage(url).addCallback(println)
i += 1

reactor.callWhenRunning(getPages)
reactor.run()
codingpp
2014-04-08 17:35:33 +08:00
如果200万这么多请求,还需要控制一下当前最大请求数量
mojidong
2014-04-09 10:51:25 +08:00
分布式,多进程
调度节点(集群)来分配任务,爬去节点(分布式多进程)获取任务处理
lykjwzc
2014-04-09 17:26:47 +08:00
我试过用scrapy开发一个通用的小爬虫,不过不是太关心性能目前
lizon
2016-06-03 00:16:42 +08:00
个人建议,经验来源于刚做完的毕设:
先说结果, 18min 能爬 3w 页面。
我是用 Java 写的, Apache HTTPClient 包做访问,封装爬取任务,投递到线程安全队列,单开一个线程作为消费者,不断将任务投递到线程池, 500 并发(已经吃满带宽,平稳状态消耗 1G 内存),外网 500KB/s ,爬取到的 URL 存储在内网某 Redis 里做去重,实际的页面存储根据你的需求来定,建议汇总到内网某一服务器,比较方便。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/107660

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX