我正在使用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秒的,尽管这些网站的格式是相同的,并且包含了大致相同的信息。网站是类似于法院判决的:17749.htm
有没有人知道为什么性能差异存在,以及如何克服它?任何帮助都将不胜感激。
发布于 2016-03-30 20:03:49
慢的不是BeautifulSoup,而是decisionpage.read()。
urllib.urlopen返回一个套接字对象,实际的http请求发生在.read()。因此,如果您的瓶颈在网络的某处:您的互联网连接或远程网站是缓慢(或两者兼而有之)。
因为你是I/O绑定的,并且有几千个网站,你可以通过同时运行几个解析不同网站的线程来显着地加快速度。
发布于 2016-03-30 20:08:13
你的问题也许有一个矛盾的解决办法。很明显,你试图刮掉的网站正在扼杀你。
我建议试着尊重他们的意愿,并在你们的请求之间增加一个停顿。如果将time.sleep(2) (和import time添加到脚本顶部)添加到循环的末尾,则可能会阻止您被节流60秒。
试一试,看看哪个数字最适合你。
发布于 2016-04-04 22:45:59
在爬行大型网站时,使用线程:concurrent.futures或threading。在网络I/O中,对网络资源执行read()的线程大部分时间都在等待。这是一个非常适合使用并发的情况。
第二,如果您不是在抓取特定的内容,只需遵循锚标记,就会使用正则表达式。在我的机器上,它们比HTMLParser快100倍左右。加速速度将是显著的。
https://stackoverflow.com/questions/36318547
复制相似问题