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

2021-06-04 18:26:10 +08:00
 foxyier

需求场景:

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

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

好了不扯淡了,爬虫本身就是 IO 密集操作,你闲 cpu 没用上,就需要多用代理 IP,并发的来发送 HTTP 请求,这样 CPU 才有机会来解析页面什么计算密集操作。
keylock
2021-06-04 19:05:09 +08:00
使用异步框架,如 sanic 等,配合 aiohttp(代替 requests)
winnerczwx
2021-06-04 19:37:04 +08:00
建议先看下时间用在哪儿了, 可能是网络 io 也可能是 硬盘 io 也可能是并发量没上去
chenqh
2021-06-04 19:46:01 +08:00
用链接池呀
比如 requests, 使用全局 session,快很多的
no1xsyzy
2021-06-04 20:44:24 +08:00
大概率你把千兆带宽跑满了 CPU 也只有单核的 50% 不到。
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
2021-06-04 21:21:51 +08:00
你的思路就有问题,从 system 的角度来看,优化的思路不是直接想利用 XX 的空闲资源看能干嘛,而是先寻找瓶颈,才有解决方案。而爬虫一般的瓶颈显然是出现在网络 IO 上。
leimao
2021-06-04 22:28:33 +08:00
asyncio
just1
2021-06-04 22:33:17 +08:00
上协程,忽略 https 校验,多核配合多进程。如果还是资源吃紧,换语言吧。
https://hunsh.net/archives/74/
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
2021-06-04 23:38:46 +08:00
有必要优化得很好吗?站点没有被你怕挂吧?
figo
2021-06-05 00:17:05 +08:00
跑得太快目标站都挂了
so1n
2021-06-05 00:58:03 +08:00
方向错了。。。爬虫一般不会吃 cpu 都是 io 和内存为主
locoz
2021-06-05 05:48:56 +08:00
爬虫主要还是个 IO 密集型的东西,CPU 资源都是解析内容的时候吃得多,如果想要让 CPU 压力高点,那就多加点并发...
另外,通常情况下爬虫程序的内存占用高就代表着 CPU 占用也会高,毕竟待解析和存储的内容都在内存里堆着。但从你说的情况来看貌似只有内存占用高,这很可能是你的程序有问题,用了内存却没有及时释放,所以内存占用才高,建议检查一下代码。
deplives
2021-06-05 10:20:08 +08:00
爬虫不是 io 密集么?
no1xsyzy
2021-06-05 10:39:14 +08:00
@just1 忽略 https 校验就不对了,这东西只占 CPU,强制打开,甚至给我校验三遍啊三遍,才更符合楼主的需求 :doge:
llsquaer
2021-06-07 18:12:35 +08:00
没遇到过 cpu 跑满的情况...倒是家用把 tcp 链接跑满了..不知道怎么搞..

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

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

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

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

© 2021 V2EX