我没有做太多的线程处理,但我想知道我是否可以同时保存图片在网页上,而不是一次一个。
目前,我的代码执行后一种方法:
while pageCount <= 5:
soup = BeautifulSoup(urllib2.urlopen("http://www.url.../%d" % pageCount))
for link in soup.find_all("div", class_="photo"):
pic = link.findAll('img')
url = re.search("(?P<url>https?://[^\s]+\.(?:jpe?g))", str(pic)).group("url")
count +=1
urllib.urlretrieve(url,'C:\Desktop/images/pics%s.jpg' % count)
pageCount +=1
我在想,这个过程可以通过采用多线程方法来加速,但不确定如何进行。
谢谢
发布于 2014-01-24 07:01:04
Python中的多线程只会使脚本在IO由于GIL
而阻塞时更快,任何CPU/IO密集型应用程序都不太可能看到性能的提高(如果有的话,它们可能会变慢)。
我已经为不同站点的大小编写了刮板(有些站点的大小与8+ TB一样大)。Python将很难在单个脚本上获得完整的行速率,您最好的选择是使用一个适当的作业队列(如celery
),然后运行多个工作人员来实现并发。
如果您不想要celery
,那么另一种麻木不仁的方法是使用subprocess
调用多个curl/wget/axel
实例,然后阻塞它们直到它们返回,检查退出代码,检查文件是否存在等等。然而,如果您的脚本没有干净地退出,那么您就会出现僵尸进程(即即使在您关闭脚本之后下载也会继续)。如果您不喜欢subprocess
的想法,那么您可以使用类似eventlet
或gevent
之类的东西,但是在单个脚本上不能达到全行率,那么您必须运行多个工作人员。
有些站点有速率限制,因此使用作业队列通常是一种很好的解决方法(例如,许多带有随机IP的EC2实例),每个站点都有X个工作人员,以获得最大的吞吐量。
Python是一个非常好的工具,可以抓取大量的数据,您只需要正确地完成它。
此外,在许多情况下,pyquery比BeautifulSoup处理结果的速度快得多。至少,不要依赖BeautifulSoup库为您请求数据。使用类似于python-requests
的方法来获取结果,然后将其传递到解析器中(如soup或pyquery等)。
如果您计划抓取/存储大量数据,例如处理作业和下载内容时的带宽优化,也需要考虑可伸缩性。有一些存储集群允许您将URL发送到它们的API,它们负责为您下载内容。这节省了浪费带宽下载,然后上传文件到你的后端-这可以削减你的带宽费用的一半。
值得一提的是,threading+BeautifulSoup已经被讨论过了;
https://stackoverflow.com/questions/21334624
复制相似问题