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
4ever911
V2EX  ›  Python

爬虫把自己爬死了。。。。点解?

  •  
  •   4ever911 · 2017-03-06 12:09:26 +08:00 · 6634 次点击
    这是一个创建于 2600 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我弄了一个爬虫程序, 没有把服务器爬死,倒是把自己网络经常弄挂,

    大概就是用 gevent 创建一个 Pool(50) , 50 个并发,

    用 Requests 来迭代 (有打 m onkey patch )

    url 大概是接近 10000 个,

    速度其实还挺快的, 一秒能处理接近 300 个 requests , for 迭代,没有 sleep

    但是现在的问题是,每次连续处理 3000 个左右还好,再多了,经常就把本地网络弄挂了,导致程序也 timeout 退出。
    一两分钟内,经常网络也连不上。不知道是不是我程序写的太耗系统资源,可能要稍微在一段任务后休息一下。

    现在的解决办法就是, 把任务分成小块,每块大概 2000 个, 每爬了 2000 个就休息几秒。

    有没有更科学的方法,或者是我哪里使用不当?
    第 1 条附言  ·  2017-03-06 12:43:59 +08:00
    看到楼下都说路由器的问题,我猜应该也是路由器的问题。

    同样的代码在阿里云服务器上跑,毫无压力。

    我自己的路由器按说已经是家用里很好的了, Netgear 的 3000 多,

    换别的路由连接方式也不大可行,因为还有很多其他电脑,加上物理距离,不大可行。


    那目前看,好像也只能自己控制减慢并发请求的速度了。
    第 2 条附言  ·  2017-03-07 00:48:27 +08:00
    最后发现, 路由器表示不背锅, 是我的程序写的有问题

    在 gevent 调用的函数里面,我直接用的 Requests.get 来下载页面,这个方式下不能复用连接,也没有主动去调用关闭,所以程序保持了几千个服务器之间的连接,最后把路由器玩死了。


    现在修改成用 session 来 get ,一切完美了,速度也快了好多。


    nCount = 50
    connection_limit = nCount
    adapter = requests.adapters.HTTPAdapter(pool_connections=connection_limit,
    pool_maxsize=connection_limit)
    session = requests.session()
    session.mount('http://', adapter)

    fetchpool = Pool(nCount)
    for job in jobs:
    fetchpool.spawn(self.foobar, session, job)
    fetchpool.join()



    def foobar(self, session, job):
    session.get(......)
    23 条回复    2017-03-07 17:09:20 +08:00
    markmx
        1
    markmx  
       2017-03-06 12:15:30 +08:00   ❤️ 1
    换个好路由器.
    IanPeverell
        2
    IanPeverell  
       2017-03-06 12:22:54 +08:00   ❤️ 1
    感觉是:请求太多了,一次发不出那么多请求,全排路由缓存里了,然后把缓存挤爆了后面的都排不进去了就超时了,然后处理这些请求花了一两分钟,换个加宽带宽,然后异步请求更好一点
    onetrlee
        3
    onetrlee  
       2017-03-06 12:24:49 +08:00   ❤️ 1
    1L+1
    如果有在用路由,先尝试不用路由,再跑一下.如果有用光猫把光猫改成桥接,直连电脑然后电脑拨号跑一下试试.

    我前段时间也是写爬虫,就是这个问题,最开始,1 秒撑死直接处理不到 1000 个请求,上行带宽只用了不到 10M.后来去掉路由有提升但是还是没跑满,又把光猫改成桥接电脑直接拨号,问题就解决了.

    所以,如果你确定代码没问题的话,检查一下自己网络会经过的设备,挨个排查吧.
    imn1
        4
    imn1  
       2017-03-06 12:26:49 +08:00   ❤️ 1
    可以确认 LZ 不玩 P2P ,是个好孩子
    4ever911
        5
    4ever911  
    OP
       2017-03-06 12:35:12 +08:00 via iPhone
    我也怀疑是路由器,这个是华为的 3000 多的路由器,按说不至于这么脆弱啊。

    我确实在阿里云上测试过,毫无压力。
    4ever911
        6
    4ever911  
    OP
       2017-03-06 12:36:33 +08:00 via iPhone
    说错了, netgear 的路由器
    relaxchen
        7
    relaxchen  
       2017-03-06 13:05:23 +08:00
    @4ever911 NetGear 3000+的路由器,,那只可能是 R9000 了?
    4ever911
        8
    4ever911  
    OP
       2017-03-06 14:36:20 +08:00
    @relaxchen R8500

    现在在外面一个小茶楼, 居然这边的网络也毫无压力。。。。
    看来是我家里有设备有问题,我中间搭配了几个光猫,还有个苹果的 Airport Extreme
    8355
        9
    8355  
       2017-03-06 14:47:53 +08:00
    肯定是路由器设置问题. 找找一般抗攻击之类的设置.
    ericbize
        10
    ericbize  
       2017-03-06 15:00:45 +08:00
    不要开 Qos , 网件的 Qos 好奇怪,连测速的都给搞一下。
    4ever911
        11
    4ever911  
    OP
       2017-03-06 15:08:09 +08:00
    @ericbize 我没有开 Qos
    sola97
        12
    sola97  
       2017-03-06 15:12:18 +08:00 via Android
    记得以前用 zmap ,速度过快就全堆内存里了, 24G 内存堆满就报错,网卡还要处理十分钟
    yxqcyl
        13
    yxqcyl  
       2017-03-06 16:10:56 +08:00
    楼主广东人?
    relaxchen
        14
    relaxchen  
       2017-03-06 17:20:56 +08:00
    @4ever911 把家里的网络拓扑图贴出来让大家看看呗?
    webcoder
        15
    webcoder  
       2017-03-06 17:34:58 +08:00
    端口刷太多,然后不释放,锁死了??
    Sh888
        16
    Sh888  
       2017-03-06 17:39:25 +08:00
    家用宽带应该有最大连接数限制吧。
    dsg001
        17
    dsg001  
       2017-03-06 20:06:09 +08:00
    本机 gevent+requests 跑百万 url 没问题,路由器应该事设置有问题吧
    bertie55
        18
    bertie55  
       2017-03-06 20:10:32 +08:00
    求个 python 爬虫工程师,两年爬虫经验。
    暴风体育 [email protected]

    跪求人才,欢迎咨询。
    qydyhyn
        19
    qydyhyn  
       2017-03-06 20:23:25 +08:00
    用软路由试试吧!
    nicevar
        20
    nicevar  
       2017-03-06 20:38:17 +08:00 via iPhone
    量太大了,家用路由器扛不住的,我的 R8000 和 6300 被我跑崩好多次
    4ever911
        21
    4ever911  
    OP
       2017-03-07 00:49:26 +08:00
    最后发现, 路由器表示不背锅, 是我的程序写的有问题

    在 gevent 调用的函数里面,我直接用的 Requests.get 来下载页面,这个方式下不能复用连接,也没有主动去调用关闭,所以程序保持了几千个服务器之间的连接,最后把路由器玩死了。


    现在修改成用 session 来 get ,一切完美了,速度也快了好多。


    nCount = 50
    connection_limit = nCount
    adapter = requests.adapters.HTTPAdapter(pool_connections=connection_limit,
    pool_maxsize=connection_limit)
    session = requests.session()
    session.mount('http://', adapter)

    fetchpool = Pool(nCount)
    for job in jobs:
    fetchpool.spawn(self.foobar, session, job)
    fetchpool.join()



    def foobar(self, session, job):
    session.get(......)



    不过,之前也没留心,我的路由器也有一些问题,非常不稳定,尤其是 wifi ,干扰严重,即使我已经选择了别人都没有用的 channel
    skylancer
        22
    skylancer  
       2017-03-07 08:26:03 +08:00 via Android
    几千的连接就能跑挂..

    我是建议先把渣渣网件固件换了
    啊 8500 啊,那再见...
    log4geek
        23
    log4geek  
       2017-03-07 17:09:20 +08:00
    网络搞挂就只能升级网络了啦~
    说到爬虫,我这里给分享个爬虫的学习笔记
    http://log4geek.cc/2017/03/零基础 12 天从入门到精通 python 爬虫 /
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3324 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:56 · PVG 19:56 · LAX 04:56 · JFK 07:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.