python 抓取网页数据,怎么用python抓取网页数据
Python网页抓取的性能问题-熊猫凶猛-博客花园
Python网页抓取的性能问题在网页抓取过程中,软件的性能瓶颈当然是网络连接,这是第一时间可以想到的。另外,通过cProfile.run和pstats也可以看得很清楚。Stats一般来说,这个问题可以通过以下方法解决:
通过线程和多重处理来解决。例如,#urls包含所有需要扫描的URL。
#列出包含每个线程扫描结果列表的列表
列表=[]
线程=[]
对于范围(10)内的I:
temp=[]
lists.append(临时)
t=螺纹。Thread(target=check_page,args=([_ for _ in URLs if URLs . index(_)% 10==I),temp))
启动()
threads.append
对于threads中的t:t . join()如果不需要获取完整的网页,可以在请求的HTTP头中添加接收范围的头,只获取网页的一部分:req=urllib2.request (URL,headers={ Range : bytes=0-1023 })。不过需要注意的是,少数网站不支持range的表头。
在请求的HTTP头中添加接收到的gzip编码内容的头:req=urllib2.request (URL,headers={ accept-encoding : gzip })。至于如何判断返回的内容是否真的是gzip编码的内容,以及如何解码gzip编码的内容,还有我的另一篇文章。
别忘了给urlopen加超时。在使用线程和多处理的过程中,我感觉这两种方式至少在扫描网页时性能相差不大。我创建了10个线程和10个进程来分别扫描大约8K个不同网站的页面。三次对比的时间差不到10%,而多处理占用的系统内存更多。
其实除了以上方法,Python中还有一些地方可能会更好的提升性能。比如支持更好的多线程多进程的greenlet、stackless python等工具,以及twisted、PycURL等异步IO也可以使用。不过我个人对greenlet不太熟悉,觉得twisted太扭了,PycURL不够python化,stackless python怕破坏其他python程序,所以还是用了urllib2线程方案。当然,因为GIL的问题,python多线程还是不够快,但是对于单线程的情况,已经节省了好几倍的时间。
另外,如果需要在多线程环境下使用lxml解析网页,有时会出现占用系统所有内存的问题。估计lxml使用的底层libxslt或libxml2库有重入问题。这时候就需要把lxml解析html的工作放到主线程中。当然这会导致系统性能下降,但这是lxml库本身的局限性。除非启动真正的多重处理,否则即使使用多重处理,仍然会出现错误。
为什么不用BeautifulSoup?嗯,这是因为它所依赖的sgmllib有一些特别令人沮丧的错误,还因为它解析HTML的速度比lxml.html慢10倍,这是另一回事。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。