加快美丽的汤

时间:2016-03-30 19:58:33

标签: python performance web-scraping beautifulsoup urllib

我正在使用 BeautifulSoup 来解析for循环中的几千个网站。以下是我的代码片段:

def parse_decision(link):
    t1 = time.time()
    decisionpage = urllib.urlopen(link)
    t2 = time.time()
    soup = BeautifulSoup(decisionpage.read(), 'lxml')
    t3 = time.time()
    # ...
    # Parsing happens here and returns a pandas dataframe

因为代码需要永远运行,所以我开始调查原因并发现BeautifulSoup读取决策页所需的时间差异很大。以下是完成每个步骤所需秒数的片段:

    Element | t2-t1  |  t3-t2
    1.      | 0.073  | 60.023
    2.      | 0.096  | 0.005
    3.      | 0.096  | 60.016
    4.      | 0.064  | 0.006

正如我们所看到的,大约每一个第二个网站都需要 60秒,尽管这些网站的格式相同并且包含大致相同的信息。 网站是与此类似的法院判决:         http://www.nycourts.gov/reporter/3dseries/2003/2003_17749.htm

有没有人知道为什么存在性能差异以及可能如何克服它?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

BeautifulSoup不是decisionpage.read(),而是urllib.urlopen

.read()返回一个套接字对象,实际的http请求发生在?。因此,如果您在网络中的某个地方出现瓶颈:您的Internet连接或远程网站速度很慢(或两者都有)。

由于您是I / O绑定并拥有数千个网站,因此您可以通过运行多个线程同时解析不同的网站来显着加快速度。

答案 1 :(得分:0)

您的问题可能存在矛盾的解决方案。很明显,你试图掠夺的网站会限制你。

我建议您尝试尊重他们的意愿,并在您的请求之间添加暂停。如果您将time.sleep(2)(和import time添加到脚本顶部)到循环结束,则可能会阻止您被限制60秒。

尝试并查看最适合您的号码。

答案 2 :(得分:0)

抓取大型网站时使用线程:concurrent.futuresthreading。在网络I / O中,网络资源read()的线程大部分时间都在等待。这是采用并发的一种非常合适的情况。

其次,如果你没有抓取特定的东西,只需跟随锚标签,使用正则表达式。它们比我机器中的HTMLParser快约100倍。加速将是重要的。