Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我应该创建管道来用scrapy保存文件吗?_Python_Scrapy_Web Crawler_Pipeline - Fatal编程技术网

Python 我应该创建管道来用scrapy保存文件吗?

Python 我应该创建管道来用scrapy保存文件吗?,python,scrapy,web-crawler,pipeline,Python,Scrapy,Web Crawler,Pipeline,我需要保存一个文件(.pdf),但我不确定如何保存。我需要保存.pdf并以这样的方式存储它们:它们被组织在一个目录中,就像它们被存储在我正在删除的站点上一样 从我能收集到的信息来看,我需要创建一个管道,但从我的理解来看,管道保存的“项目”和“项目”只是字符串/数字等基本数据。保存文件是对管道的正确使用,还是应该改为将文件保存在spider中?这是一个完美的工作工具。Scrapy的工作方式是使用爬行器将网页转换为结构化数据(项目)。管道是后处理器,但它们使用与spider相同的异步基础结构,因此非

我需要保存一个文件(.pdf),但我不确定如何保存。我需要保存.pdf并以这样的方式存储它们:它们被组织在一个目录中,就像它们被存储在我正在删除的站点上一样


从我能收集到的信息来看,我需要创建一个管道,但从我的理解来看,管道保存的“项目”和“项目”只是字符串/数字等基本数据。保存文件是对管道的正确使用,还是应该改为将文件保存在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链接已被弃用。改用这个: