我应该创建管道以使用scrapy保存文件吗?
Posted
技术标签:
【中文标题】我应该创建管道以使用scrapy保存文件吗?【英文标题】:Should I create pipeline to save files with scrapy? 【发布时间】:2011-10-30 16:54:42 【问题描述】:我需要保存一个文件 (.pdf),但我不确定如何保存。我需要保存.pdf 并将它们存储在一个目录中,就像它们存储在我正在刮掉它们的网站上一样。
据我所知,我需要制作一个管道,但据我了解,管道保存的“项目”和“项目”只是基本数据,如字符串/数字。保存文件是正确使用管道,还是应该将文件保存在蜘蛛中?
【问题讨论】:
为什么不使用 FEED_EXPORTER 而不是 PIPELINE ? 【参考方案1】:是和否[1]。如果您获取 pdf,它将存储在内存中,但如果 pdf 不够大,无法填满您的可用内存,则可以。
您可以将 pdf 保存在蜘蛛回调中:
def parse_listing(self, response):
# ... extract pdf urls
for url in pdf_urls:
yield Request(url, callback=self.save_pdf)
def save_pdf(self, response):
path = self.get_path(response.url)
with open(path, "wb") as f:
f.write(response.body)
如果您选择在管道中进行:
# in the spider
def parse_pdf(self, response):
i = MyItem()
i['body'] = response.body
i['url'] = response.url
# you can add more metadata to the item
return i
# in your pipeline
def process_item(self, item, spider):
path = self.get_path(item['url'])
with open(path, "wb") as f:
f.write(item['body'])
# remove body and add path as reference
del item['body']
item['path'] = path
# let item be processed by other pipelines. ie. db store
return item
[1] 另一种方法可能是只存储 pdf 的 url 并使用另一个进程来获取文档而不缓冲到内存中。 (例如wget
)
【讨论】:
这是否适用于 CrawlSpider,因为我花了几个小时试图在蜘蛛中实现 pdf 的保存,而回调函数永远不会被调用。 @Kex 很难在没有看到您的代码的情况下判断出什么问题。一个常见的陷阱是覆盖parse
回调或在链接提取器中未使用正确的模式。
我没有这个问题就解决了,现在我在规则中使用 SgmlLinkExtractor 下载 pdf 文件并将响应保存到 pdf 文件中。
@Kex:我正在尝试构建一个类似的系统。你能告诉我你是如何让 SgmlLinkExtractor 为你做到这一点的吗?
@bi0s.kidd0,也许你正在寻找类似Rule(SgmlLinkExtractor(allow=r"\.pdf"), callback="save_pdf")
的东西。【参考方案2】:
有一个FilesPipeline可以直接使用,假设你已经有了文件url,链接说明如何使用FilesPipeline:
https://groups.google.com/forum/print/msg/scrapy-users/kzGHFjXywuY/O6PIhoT3thsJ
【讨论】:
FilesPipeline 链接已弃用。改用这个:github.com/scrapy/scrapy/blob/master/scrapy/pipelines/files.py【参考方案3】:这是完成这项工作的完美工具。 Scrapy 的工作方式是您拥有将网页转换为结构化数据(项目)的蜘蛛。管道是后处理器,但它们使用与蜘蛛相同的异步基础架构,因此非常适合获取媒体文件。
在您的情况下,您首先在蜘蛛中提取 PDF 的位置,在管道中获取它们并使用另一个管道来保存项目。
【讨论】:
以上是关于我应该创建管道以使用scrapy保存文件吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 PHP 从 sendmail 管道创建目录并写入文件以进行编程