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
foxyier
V2EX  ›  Python

「请教贴」 Python 爬虫如何把单核跑满

  •  
  •   foxyier · 2021-06-04 18:26:10 +08:00 · 3054 次点击
    这是一个创建于 1027 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求场景:

    目标有采集需求, 对于效率要求比较高, 但是程序运行的过程中对于内存资源消耗比较严重, 对于 cpu 使用率就很低, 结果造成了大量 cpu 资源的浪费。 所以想请教一下 python 爬虫有什么办法能充分利用 cpu 性能从而提升效率么

    22 条回复    2021-06-09 16:37:29 +08:00
    liprais
        1
    liprais  
       2021-06-04 18:27:33 +08:00 via iPhone   ❤️ 3
    你想的太简单了,建议好好想想
    efaun
        2
    efaun  
       2021-06-04 18:46:50 +08:00
    协程,异步
    geebos
        3
    geebos  
       2021-06-04 18:56:23 +08:00
    多线程或者协程。但是大概率速度起来会触发反爬,所以还得加代理。
    youngce
        4
    youngce  
       2021-06-04 19:03:48 +08:00
    亲这边建议买 1 核 1T 内存的机器,这样就不会浪费 CPU 资源了。

    好了不扯淡了,爬虫本身就是 IO 密集操作,你闲 cpu 没用上,就需要多用代理 IP,并发的来发送 HTTP 请求,这样 CPU 才有机会来解析页面什么计算密集操作。
    keylock
        5
    keylock  
       2021-06-04 19:05:09 +08:00
    使用异步框架,如 sanic 等,配合 aiohttp(代替 requests)
    winnerczwx
        6
    winnerczwx  
       2021-06-04 19:37:04 +08:00
    建议先看下时间用在哪儿了, 可能是网络 io 也可能是 硬盘 io 也可能是并发量没上去
    chenqh
        7
    chenqh  
       2021-06-04 19:46:01 +08:00
    用链接池呀
    比如 requests, 使用全局 session,快很多的
    no1xsyzy
        8
    no1xsyzy  
       2021-06-04 20:44:24 +08:00
    大概率你把千兆带宽跑满了 CPU 也只有单核的 50% 不到。
    mckelvin
        9
    mckelvin  
       2021-06-04 21:12:33 +08:00
    一般来说网络爬虫的瓶颈是网络 I/O,也就是说 CPU/内存 /磁盘的使用尚在资源富裕的时候,网络 I/O 先到瓶颈了。网络 I/O 瓶颈具体细分看也有好多类型,比如如果是同步阻塞的网络,会花很多时间在等待网络资源收发上。这种情况下可以通过非阻塞(non-blocking)的方式在单个进程内管理多个网络连接同时抓取(底层的系统调用可能是 poll/select)。当然用多线程或者多进程阻塞地请求网络资源也能达到相同的目的,但是代价更贵。此时抓取效率增加后如果反爬机制还没工作的话,瓶颈可能出现在网络带宽上,如果网络带宽也很足的话那接下去瓶颈可能出在 CPU/磁盘 /内存。如果你磁盘容量大,性能好,内存也很充足的话,那 CPU 才可能成为瓶颈,这是你才有机会把 CPU 跑满,让 CPU 成为瓶颈。

    但是如果你只是单纯相当 CPU 假装很忙的话,可以不用多路复用而选择开很多很多线程,这样 CPU 就可以在 context switching 这件事情上摸鱼了。
    GrayXu
        10
    GrayXu  
       2021-06-04 21:21:51 +08:00   ❤️ 1
    你的思路就有问题,从 system 的角度来看,优化的思路不是直接想利用 XX 的空闲资源看能干嘛,而是先寻找瓶颈,才有解决方案。而爬虫一般的瓶颈显然是出现在网络 IO 上。
    leimao
        11
    leimao  
       2021-06-04 22:28:33 +08:00 via iPhone
    asyncio
    just1
        12
    just1  
       2021-06-04 22:33:17 +08:00
    上协程,忽略 https 校验,多核配合多进程。如果还是资源吃紧,换语言吧。
    https://hunsh.net/archives/74/
    ClericPy
        13
    ClericPy  
       2021-06-04 23:31:41 +08:00
    几个关键词吧

    无栈协程 (比多线程快一倍多, 比有栈的略快大概一半, 不过也可能是 HTTP 库的差距)
    aiohttp (Cython 提速, 比 httpx 快差不多一倍)
    uvloop (有它没它速度能差接近一倍)
    共用 Session (比每次新开一个连接快很多, 尤其高并发的时候)
    高带宽机器(比如我 aws 上上千并发就能抗住, 阿里云小水管就给我超时...)
    根据带宽控制 Semophare, 既要避免特别慢的拖累别人, 也要避免带宽已满却额外开了一群连接实际速度没有提升还导致 read 超时

    目前拿本机接口单核随便跑跑接近 3000 qps, 比 golang 慢了不多(如果简简单单请求一下, golang 还是挺香的), 不过已经是 2 年前的结论了

    楼上的忽略 https 也是个好办法, ssl=False
    CEBBCAT
        14
    CEBBCAT  
       2021-06-04 23:38:46 +08:00 via Android
    有必要优化得很好吗?站点没有被你怕挂吧?
    figo
        15
    figo  
       2021-06-05 00:17:05 +08:00
    跑得太快目标站都挂了
    so1n
        16
    so1n  
       2021-06-05 00:58:03 +08:00 via Android
    方向错了。。。爬虫一般不会吃 cpu 都是 io 和内存为主
    locoz
        17
    locoz  
       2021-06-05 05:48:56 +08:00
    爬虫主要还是个 IO 密集型的东西,CPU 资源都是解析内容的时候吃得多,如果想要让 CPU 压力高点,那就多加点并发...
    另外,通常情况下爬虫程序的内存占用高就代表着 CPU 占用也会高,毕竟待解析和存储的内容都在内存里堆着。但从你说的情况来看貌似只有内存占用高,这很可能是你的程序有问题,用了内存却没有及时释放,所以内存占用才高,建议检查一下代码。
    deplives
        18
    deplives  
       2021-06-05 10:20:08 +08:00 via iPhone
    爬虫不是 io 密集么?
    no1xsyzy
        19
    no1xsyzy  
       2021-06-05 10:39:14 +08:00
    @just1 忽略 https 校验就不对了,这东西只占 CPU,强制打开,甚至给我校验三遍啊三遍,才更符合楼主的需求 :doge:
    llsquaer
        20
    llsquaer  
       2021-06-07 18:12:35 +08:00
    没遇到过 cpu 跑满的情况...倒是家用把 tcp 链接跑满了..不知道怎么搞..
    lusi1990
        21
    lusi1990  
       2021-06-08 16:06:34 +08:00
    好多人答偏了, 既然瓶颈是内存,解决思路就是:要么优化代码,要么加内存
    zhouxianggen
        22
    zhouxianggen  
       2021-06-09 16:37:29 +08:00
    CPU 利用率很低,就说明 CPU 它不是瓶颈,那提高 CPU 性能就达不到提升效率的目的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4416 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:10 · PVG 18:10 · LAX 03:10 · JFK 06:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.