V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
hellove1985
V2EX  ›  Python

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

  •  
  •   hellove1985 · 2014-04-08 14:31:08 +08:00 · 10260 次点击
    这是一个创建于 3886 天前的主题,其中的信息可能已经有所发展或是发生改变。
    简单描述一下场景:
    现在有200w左右的ip,任务是把这写ip对应的web服务的首页抓取下来(大概有1/3的ip没有web服务)

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

    请问大家,如何提升爬虫带宽的占用率?
    8 条回复    2016-06-03 00:16:42 +08:00
    mclxly
        1
    mclxly  
       2014-04-08 15:52:46 +08:00
    之前用PHP和C分别实现过。PHP长时间运行好像有内存泄漏,效率也不高。后用C重写,库使用curl(multi interface模式)+libevent,测试可以达到下载峰值,有少部分失败请求。
    hellove1985
        2
    hellove1985  
    OP
       2014-04-08 16:04:03 +08:00
    @mclxly 谢谢回复,我忘记说了,在测试一个实际存在的站点的时候(一个ip抓取20w次首页),测试程序也可以达到下载顶峰,在描述的场景下,就不行。。。。
    mclxly
        3
    mclxly  
       2014-04-08 16:12:56 +08:00
    @hellove1985 这样的话,可以试试一个程序测试是否有web访问,一个程序专门下载。
    codingpp
        4
    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
        5
    codingpp  
       2014-04-08 17:35:33 +08:00
    如果200万这么多请求,还需要控制一下当前最大请求数量
    mojidong
        6
    mojidong  
       2014-04-09 10:51:25 +08:00
    分布式,多进程
    调度节点(集群)来分配任务,爬去节点(分布式多进程)获取任务处理
    lykjwzc
        7
    lykjwzc  
       2014-04-09 17:26:47 +08:00
    我试过用scrapy开发一个通用的小爬虫,不过不是太关心性能目前
    lizon
        8
    lizon  
       2016-06-03 00:16:42 +08:00
    个人建议,经验来源于刚做完的毕设:
    先说结果, 18min 能爬 3w 页面。
    我是用 Java 写的, Apache HTTPClient 包做访问,封装爬取任务,投递到线程安全队列,单开一个线程作为消费者,不断将任务投递到线程池, 500 并发(已经吃满带宽,平稳状态消耗 1G 内存),外网 500KB/s ,爬取到的 URL 存储在内网某 Redis 里做去重,实际的页面存储根据你的需求来定,建议汇总到内网某一服务器,比较方便。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1542 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 17:04 · PVG 01:04 · LAX 09:04 · JFK 12:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.