Python 我应该创建管道来用scrapy保存文件吗?
我需要保存一个文件(.pdf),但我不确定如何保存。我需要保存.pdf并以这样的方式存储它们:它们被组织在一个目录中,就像它们被存储在我正在删除的站点上一样Python 我应该创建管道来用scrapy保存文件吗?,python,scrapy,web-crawler,pipeline,Python,Scrapy,Web Crawler,Pipeline,我需要保存一个文件(.pdf),但我不确定如何保存。我需要保存.pdf并以这样的方式存储它们:它们被组织在一个目录中,就像它们被存储在我正在删除的站点上一样 从我能收集到的信息来看,我需要创建一个管道,但从我的理解来看,管道保存的“项目”和“项目”只是字符串/数字等基本数据。保存文件是对管道的正确使用,还是应该改为将文件保存在spider中?这是一个完美的工作工具。Scrapy的工作方式是使用爬行器将网页转换为结构化数据(项目)。管道是后处理器,但它们使用与spider相同的异步基础结构,因此非
从我能收集到的信息来看,我需要创建一个管道,但从我的理解来看,管道保存的“项目”和“项目”只是字符串/数字等基本数据。保存文件是对管道的正确使用,还是应该改为将文件保存在spider中?这是一个完美的工作工具。Scrapy的工作方式是使用爬行器将网页转换为结构化数据(项目)。管道是后处理器,但它们使用与spider相同的异步基础结构,因此非常适合获取媒体文件
在您的情况下,您首先在spider中提取PDF的位置,在管道中获取它们,然后使用另一个管道来保存项目。是和否[1]。如果您获取pdf文件,它将存储在内存中,但是如果pdf文件不够大,无法填满可用内存,那么就可以了 您可以将pdf保存在spider回调中:
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
)有一个文件管道可以直接使用,假设您已经有了文件url,该链接显示了如何使用:
爬行器是否能做到这一点,因为我花了数小时试图在爬行器中实现pdf的保存&回调函数从未被调用。@Kex如果不看代码,很难判断出哪里出了问题。一个常见的陷阱是重写
parse
回调或在链接提取器中未使用正确的模式。我解决了这个问题,现在我在规则中使用SGMLLinkedExtractor下载pdf文件并将响应保存到pdf文件中。@Kex:我正在尝试构建一个类似的系统。你能告诉我你是如何让SGMLLinkedExtractor为你做这些的吗?@bi0s.kidd0,也许你正在寻找类似于规则(SGMLLinkedExtractor(allow=r“\.pdf”)、callback=“save\u pdf”)
的东西。为什么不使用提要导出程序而不是管道?FilePipeline链接已被弃用。改用这个: