我有一个项目管道,它从项目中获取一个 url 并下载它。问题是我有另一个管道,我在其中手动检查这个文件并添加一些关于它的信息。我真的需要在下载文件之前完成它。
class VideoCommentPipeline(object):
def process_item(self, item, spider):
os.system("vlc -vvv %s > /dev/null 2>&1 &" % item['file'])
item['comment'] = raw_input('Your comment:')
return item
class VideoDownloadPipeline(object):
def process_item(self, item, spider):
video_basename = item['file'].split('/')[-1]
new_filename = os.path.join(VIDEOS_DIR, video_basename)
downloaded = False
for i in range(5):
try:
video = urllib2.urlopen(item['file']).read()
downloaded = True
break
except:
continue
if not downloaded:
raise DropItem("Couldn't download file from %s" % item)
f = open(new_filename, 'wb')
f.write(video)
f.close()
item['file'] = video_basename
return item
但现在我总是不得不等待另一个项目,因为尚未下载上一个项目的文件。我宁愿检查所有项目,然后全部下载。我该怎么做?
最佳答案
Scrapy 提供 media pipeline可以在这里用于您的目的。它没有很好的记录,但它存在并且可以使用,至少在最近的 scrapy 版本中是这样。要了解它的工作原理,您需要阅读代码,IMO 非常直观。你可以查看image pipeline了解媒体管道如何工作的界面。
要在下载之前检查每个视频,您可以写类似这样的内容(您需要将其与您的项目字段名称相匹配)
from scrapy.contrib.pipeline.media import MediaPipeline
class VideoPipeline(MediaPipeline):
VIDEOS_DIR = "/stack/scrapy/video/video/store"
def get_media_requests(self, item, info):
"""
Evaluate file and, if you like it, download it.
"""
os.system("vlc -vvv %s > /dev/null 2>&1 &" % item['video_url'][0])
your_opinion = raw_input("how does it look?")
item["comment"] = your_opinion
if your_opinion == "hot":
# issue request download video
return Request(item["video_url"][0], meta={"item":item})
def media_downloaded(self, response, request, info):
"""
File is downloaded available as response.body save it.
"""
item = response.meta.get("item")
video = response.body
video_basename = item['title'][0]
new_filename = os.path.join(self.VIDEOS_DIR, video_basename)
f = open(new_filename, 'wb')
f.write(video)
f.close()
关于python - 不要等待文件用 Scrapy 下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23815324/