首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >同时从url中抓取图像

同时从url中抓取图像
EN

Stack Overflow用户
提问于 2014-01-24 14:03:14
回答 4查看 1.6K关注 0票数 0

我没有做太多的线程处理,但我想知道我是否可以同时保存图片在网页上,而不是一次一个。

目前,我的代码执行后一种方法:

代码语言:javascript
代码运行次数:0
运行
复制
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 

我在想,这个过程可以通过采用多线程方法来加速,但不确定如何进行。

谢谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-01-24 14:09:21

刮痕是并行的,并且已经准备好使用图像下载中间件

票数 4
EN

Stack Overflow用户

发布于 2014-01-24 15:01:04

Python中的多线程只会使脚本在IO由于GIL而阻塞时更快,任何CPU/IO密集型应用程序都不太可能看到性能的提高(如果有的话,它们可能会变慢)。

我已经为不同站点的大小编写了刮板(有些站点的大小与8+ TB一样大)。Python将很难在单个脚本上获得完整的行速率,您最好的选择是使用一个适当的作业队列(如celery),然后运行多个工作人员来实现并发。

如果您不想要celery,那么另一种麻木不仁的方法是使用subprocess调用多个curl/wget/axel实例,然后阻塞它们直到它们返回,检查退出代码,检查文件是否存在等等。然而,如果您的脚本没有干净地退出,那么您就会出现僵尸进程(即即使在您关闭脚本之后下载也会继续)。如果您不喜欢subprocess的想法,那么您可以使用类似eventletgevent之类的东西,但是在单个脚本上不能达到全行率,那么您必须运行多个工作人员。

有些站点有速率限制,因此使用作业队列通常是一种很好的解决方法(例如,许多带有随机IP的EC2实例),每个站点都有X个工作人员,以获得最大的吞吐量。

Python是一个非常好的工具,可以抓取大量的数据,您只需要正确地完成它。

此外,在许多情况下,pyquery比BeautifulSoup处理结果的速度快得多。至少,不要依赖BeautifulSoup库为您请求数据。使用类似于python-requests的方法来获取结果,然后将其传递到解析器中(如soup或pyquery等)。

如果您计划抓取/存储大量数据,例如处理作业和下载内容时的带宽优化,也需要考虑可伸缩性。有一些存储集群允许您将URL发送到它们的API,它们负责为您下载内容。这节省了浪费带宽下载,然后上传文件到你的后端-这可以削减你的带宽费用的一半。

值得一提的是,threading+BeautifulSoup已经被讨论过了;

Urllib2 & BeautifulSoup :不错的一对,但是太慢了- urllib3和线程?

票数 4
EN

Stack Overflow用户

发布于 2014-01-24 14:30:22

如果您正在寻找DIY解决方案,请使用这些方法:

我想您可以用池在整个soup.findall()上映射您的循环体。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21334624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档