Python 中的多处理:网页抓取没有加速

Dan*_*Eng 1 python multiprocessing web-scraping

我想使用多处理模块来加速网页抓取。我的目标是在页面中提取一部分 HTML 并将其保存在父变量中。最后,将该变量写入文件。

但我遇到的问题是处理页面大约需要 1 秒。

我的代码有效,但它没有做我想要的:

import urllib.request
from bs4 import BeautifulSoup
from multiprocessing.dummy import Pool  # This is a thread-based Pool
from multiprocessing import cpu_count


def parseWeb(url):
    page = urllib.request.urlopen(url)
    soup = BeautifulSoup(page)
    h2_tag = soup.find('h2', class_='midashigo')
    return h2_tag

if __name__ == '__main__':
    file = 'links.txt' # each link is on a separate line.
    pool = Pool(cpu_count() * 2)
    with open(file, 'r') as f:
        results = pool.map(parseWeb, f)
    with open('output.txt', 'w', encoding='utf-8') as w:
        w.write(str(results))
Run Code Online (Sandbox Code Playgroud)

如何修改它以赋予它多处理的全部功能?谢谢你。

Leo*_*eon 7

这个过程应该是 I/O 绑定的,这意味着你的瓶颈应该是在解析之前你可以拉下多少连接,但实际上它可能会被 CPU 或内存绑定。

您需要意识到的第一件事是多线程/处理不会加快单个页面的解析时间。因此,如果一页需要一秒钟,而您有 420000 页,则需要 420000 秒。如果您将线程数增加到您的 PC 的内核数量的两倍,并且您的 PC 有 4 个内核,那么您将有 8 个线程每页运行 1 秒。您仍然以 420000 / 8 秒结束,即 875 分钟(实际上这并不完全正确),这是 14.5 小时的处理时间....

为了使时间跨度易于管理,您将需要大约 400 个线程,这将使处理时间减少到理论上的 17 多分钟。

有这么多线程在运行,页面被解析,内存也将成为一个问题。

我把这个小应用程序放在一起测试了几次

from time import sleep

from multiprocessing.dummy import Pool
from multiprocessing import cpu_count


def f(x):
    sleep(1)
    x = int(x)
    return x *x

if __name__ == '__main__':
    pool = Pool(cpu_count() * 100)

    with open('input.txt', 'r') as i:
        results = pool.map(f, i)
    with open('output.txt', 'w') as w:
        w.write(str(results))
Run Code Online (Sandbox Code Playgroud)

对于数字 1 到 420 000 的输入文件,处理时间花费了 1053.39 秒(大约 17.5 分钟),但这并不能很好地指示您需要多长时间,因为上述内存和 I/O 受到限制问题,你最终可能会得到明显更慢的东西。

底线是,如果您没有最大限度地利用 CPU、RAM 或网络 I/O,那么您的线程池就太小了。