使用多线程来提高Web抓取的速度

时间:2018-10-19 21:08:22

标签: python multithreading web-scraping parallel-processing beautifulsoup

我有点困境。

有一个网址,其格式为:https://www.example.com/blahblah/moreblah.php?x=123456789&lang=en

如您所见,查询中有一个唯一标识符(在此示例中,UID = 123456789)。我编写的脚本将提取x = 123456789的页面的所有必需信息。我还将脚本放入循环中,它会将UID的计数增加1(请参见下文)。所有的UID中只有大约4%有数据,但是我无法确定哪些UID包含数据(我在运气不好的情况下尝试生成xml网站地图-不断获取“网站不可索引”)。

现有代码有效,问题在于此方法将花费太长时间。我做了一些快速数学运算,从理论上讲,要检查0到5400万之间的每个UID都需要花费数年的时间(我浏览了该站点,发现UID高达5300万)。

我认为有两种选择: 1.多线程/池化(不确定如何执行此操作)。同样,在下面设置循环的方式,必须完成一个循环才能使uid增加1,然后才能执行下一个查询(请参见第20行)。
2.找到爬网该站点的方法,并准确确定需要删除的ID,然后将循环限制为这些确切的ID。

我也愿意接受其他建议。

import urllib2
from bs4 import BeautifulSoup

proxy = urllib2.ProxyHandler({'https': xxx.xx.xxx.xxx:xxxx})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
uid = 0
def scrape (uid):
    while uid < 54000000:
        page = urllib2.urlopen("https://www.example.com/blahblah/moreblah.php?x={}&lang=en".format(str(uid)))
        soup = BeautifulSoup(page, 'html.parser')
        x = soup.find_all('div', id="container")
        x_string = str(x)
        try:
             parsing the x_string
        except:
            print "There is no data on this page"
        uid+=1

scrape(uid)

1 个答案:

答案 0 :(得分:0)

多线程在这里无济于事。即使可以并行发出多个请求,您仍然仍然需要总共发出54MM + HTTP请求。处理这些请求将给远程Web服务器带来沉重的负担。 (来自Web服务器的404响应仅很容易达到数百GB的数据。)如果尝试这样做,爬网程序很可能在爬网完成之前很长时间就无法访问该站点。

您将需要找到其他方法来确定哪些ID有效。