python 产生的数据比处理的速度快造成堵塞怎样处理?

例如:

# -*- coding: utf-8 -*-
import requests
import re
for i in range(5000,5484):
    url = 'http://www.meizitu.com/a/'+str(i)+'.html'

    headers = {
        'User-Agent': 'Mozilla/5.0 (Linux;u;Android 4.2.2;zh-cn;) AppleWebKit/534.46 (KHTML,like Gecko) Version/5.1 Mobile Safari/10600.6.3 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)'
    }

    r = requests.get(url, headers=headers)
    r.encoding = 'gb2312'
    par = re.compile('<img alt="(.*?)" src="(.*?)" /><br />', re.S)
    items = re.findall(par, r.text)
    for item in items:
        print item[0], item[1]
        down = requests.get(item[1], headers=headers)
        with open('img3/%s.jpg' % item[0], 'wb') as f:
            f.write(down.content)

for迭代产生的数据 比解析下载的速度快造成堵塞

主要讲讲方法不局限示例代码。

阅读 4.8k
9 个回答

io操作肯定是要比正常的操作的慢的。
提供一下我的思路,首先我觉得多线程或者多进程不合适。可以将解析和下载抽象为两个方法,两者通过消息队列通信,这就是生产者消费者模型。如果你的的程序小到实现消息队列太复杂,可以先运行解析函数,将解析后的url写入一个文本,数据库或者干脆在内存维护一个列表,完成之后再启动下载函数,从文本,数据库或则列表读取参数。

我觉得多开几个线程可能不一定有效率的优化,但是至少可以解决当前面对的问题。

虽然对python不是很熟,但是也了解过这个问题,让代码异步执行,python也有相应的库的

题主能否解释一下【for迭代产生的数据 比解析下载的速度快造成堵塞】这句话?

IO操作的话当然速度会慢些。以题主这种网络IO为例,在3.x中最好的解决方案自然是asyncio+aiohttp,requests并不支持异步,aiohttp的client部分的api接口其实和requests也是类似。

对于一种常见的说法:IO(网络,数据库,磁盘)任务使用线程,计算使用进程。做了一些实验,建议是如果不使用异步的话尽量都使用进程。

解析页面获取图片链接和从图片链接下载图片是两个步骤,可以分开处理,将匹配到的链接都存进redis等内容的队列里面,第一步结束,然后再从队列里面拿链接下载图片,第二部结束

你可以使用 celery 来异步处理,把获取的图片都分配给 celery 的 worker 去处理。

想让你的下载速度提速一倍吗?如果想的话,就不要再写 requests.get 这种代码了!

使用 requests.Session 预先创建一个 Session 对象,然后请求时使用 Session.get 等方法,对于同服务器的大量下载可提速一倍以上(当然服务器需要支持 Keep-Alive;一般服务器都支持的)。

你并没有遇到任何关于生产比消费快的问题,因为你根本就没有队列!任务根本堆不起来嘛。所以,你应该考虑的是怎么提高下载速度,而不是处理并不存在的「堵塞」。

消息队列可破

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题