gpt4 book ai didi

Python Scrapy - 基于 mimetype 的过滤器以避免非文本文件下载

转载 作者:太空狗 更新时间:2023-10-30 00:56:56 24 4
gpt4 key购买 nike

我有一个正在运行的 scrapy 项目,但它会占用大量带宽,因为它会尝试下载大量二进制文件(zip、tar、mp3 等)。

我认为最好的解决方案是根据 mimetype (Content-Type:) HTTP header 过滤请求。我查看了 scrapy 代码,发现了这个设置:

DOWNLOADER_HTTPCLIENTFACTORY = 'scrapy.core.downloader.webclient.ScrapyHTTPClientFactory'

我改成: DOWNLOADER_HTTPCLIENTFACTORY = 'myproject.webclients.ScrapyHTTPClientFactory'

并使用了一些 ScrapyHTTPPageGetter,这里是突出显示的编辑:

class ScrapyHTTPPageGetter(HTTPClient):
# this is my edit
def handleEndHeaders(self):
if 'Content-Type' in self.headers.keys():
mimetype = str(self.headers['Content-Type'])
# Actually I need only the html, but just in
# case I've preserved all the text
if mimetype.find('text/') > -1:
# Good, this page is needed
self.factory.gotHeaders(self.headers)
else:
self.factory.noPage(Exception('Incorrect Content-Type'))

我觉得这是错误的,我需要更友好的方式来在确定它是不需要的 mimetype 后立即取消/删除请求。而不是等待下载全部数据。

编辑:
我特别询问这部分 self.factory.noPage(Exception('Incorrect Content-Type')) 是取消请求的正确方法。

更新 1:
我目前的设置已经让 Scrapy 服务器崩溃了,所以请不要尝试使用上面相同的代码来解决问题。

更新 2:
我已经使用以下结构设置了一个基于 Apache 的网站进行测试:

/var/www/scrapper-test/Zend -> /var/www/scrapper-test/Zend.zip (symlink)
/var/www/scrapper-test/Zend.zip

我注意到 Scrapy 会丢弃带有 .zip 扩展名的那些,但会丢弃没有 .zip 的那些,即使它只是指向它的符号链接(symbolic link)。

最佳答案

我构建这个中间件是为了排除任何不在正则表达式白名单中的响应类型:

from scrapy.http.response.html import HtmlResponse
from scrapy.exceptions import IgnoreRequest
from scrapy import log
import re

class FilterResponses(object):
"""Limit the HTTP response types that Scrapy dowloads."""

@staticmethod
def is_valid_response(type_whitelist, content_type_header):
for type_regex in type_whitelist:
if re.search(type_regex, content_type_header):
return True
return False

def process_response(self, request, response, spider):
"""
Only allow HTTP response types that that match the given list of
filtering regexs
"""
# each spider must define the variable response_type_whitelist as an
# iterable of regular expressions. ex. (r'text', )
type_whitelist = getattr(spider, "response_type_whitelist", None)
content_type_header = response.headers.get('content-type', None)
if not type_whitelist:
return response
elif not content_type_header:
log.msg("no content type header: {}".format(response.url), level=log.DEBUG, spider=spider)
raise IgnoreRequest()
elif self.is_valid_response(type_whitelist, content_type_header):
log.msg("valid response {}".format(response.url), level=log.DEBUG, spider=spider)
return response
else:
msg = "Ignoring request {}, content-type was not in whitelist".format(response.url)
log.msg(msg, level=log.DEBUG, spider=spider)
raise IgnoreRequest()

要使用它,请将它添加到 settings.py 中:

DOWNLOADER_MIDDLEWARES = {
'[project_name].middlewares.FilterResponses': 999,
}

关于Python Scrapy - 基于 mimetype 的过滤器以避免非文本文件下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13401382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com