我正在使用 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
有没有人知道为什么存在性能差异以及可能如何克服它?任何帮助将不胜感激。
答案 0 :(得分:2)
BeautifulSoup
不是decisionpage.read()
,而是urllib.urlopen
。
.read()
返回一个套接字对象,实际的http请求发生在?
。因此,如果您在网络中的某个地方出现瓶颈:您的Internet连接或远程网站速度很慢(或两者都有)。
由于您是I / O绑定并拥有数千个网站,因此您可以通过运行多个线程同时解析不同的网站来显着加快速度。
答案 1 :(得分:0)
您的问题可能存在矛盾的解决方案。很明显,你试图掠夺的网站会限制你。
我建议您尝试尊重他们的意愿,并在您的请求之间添加暂停。如果您将time.sleep(2)
(和import time
添加到脚本顶部)到循环结束,则可能会阻止您被限制60秒。
尝试并查看最适合您的号码。
答案 2 :(得分:0)
抓取大型网站时使用线程:concurrent.futures
或threading
。在网络I / O中,网络资源read()
的线程大部分时间都在等待。这是采用并发的一种非常合适的情况。
其次,如果你没有抓取特定的东西,只需跟随锚标签,使用正则表达式。它们比我机器中的HTMLParser
快约100倍。加速将是重要的。