如何在scrapy爬行时跳过某些文件类型?

fxp*_*fxp 5 mime scrapy

我想在使用scrapy爬行时跳过一些文件类型链接.exe .zip .pdf,但是不想将规则与特定网址一起使用规则.怎么样?

更新:

由于在未下载正文时,很难决定是否仅通过Content-Type来关注此链接.我在下载中间件中更改为drop url.谢谢彼得和利奥.

Pet*_*rby 11

如果您转到Scrapy根目录中的linkextractor.py,您将看到以下内容:

"""
Common code and definitions used by Link extractors (located in
scrapy.contrib.linkextractor).
"""

# common file extensions that are not followed if they occur in links
IGNORED_EXTENSIONS = [
    # images
    'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',
    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',

    # audio
    'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',

    # video
    '3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',
    'm4a',

    # other
    'css', 'pdf', 'doc', 'exe', 'bin', 'rss', 'zip', 'rar',
]
Run Code Online (Sandbox Code Playgroud)

但是,因为这适用于linkextractor(并且你不想使用规则),我不确定这会解决你的问题(我刚才意识到你指定你不想使用规则.我以为你有询问如何更改文件扩展名限制,而无需直接在规则中指定).

好消息是,您还可以构建自己的下载中间件,并将任何/所有请求丢弃到具有不良扩展名的URL.请参阅Downloader Middlerware

您可以通过访问request对象的url属性来获取请求的URL,如下所示:request.url

基本上,在字符串的末尾搜索".exe"或您要删除的任何扩展名,如果它包含所述扩展名,则返回IgnoreRequest异常,并立即删除该请求.

UPDATE

为了在下载之前处理请求,您需要确保在自定义下载器中间件中定义"process_request"方法.

根据Scrapy文档

process_request

对于通过下载中间件的每个请求,都会调用此方法.

process_request()应该返回None,Response对象或Request对象.

如果它返回None,Scrapy将继续处理此请求,执行所有其他中间件,直到最后,相应的下载程序处理程序被称为执行的请求(并且其响应已下载).

如果它返回一个Response对象,Scrapy将不会打扰调用任何其他请求或异常中间件或适当的下载功能; 它将返回该响应.每个响应始终会调用响应中间件.

如果它返回一个Request对象,则将重新安排返回的请求(在Scheduler中),以便将来下载.始终会调用原始请求的回调.如果新请求有回调,则会在下载响应的情况下调用它,然后该回调的输出将传递给原始回调.如果新请求没有回调,则下载的响应将仅传递给原始请求回调.

如果它返回一个IgnoreRequest异常,整个请求将被完全删除,并且永远不会调用它的回调.

基本上,只需创建一个下载器类,添加一个方法类process_request,它将请求对象和蜘蛛对象作为参数.如果网址包含不需要的扩展名,则返回IgnoreRequest异常.

这应该都是在下载页面之前发生的.但是,如果您想要处理响应标头,则必须对网页进行请求.

您可以随时在下载程序中实现process_request和process_response方法,其想法是立即删除明显的扩展,并且如果由于某种原因url不包含文件扩展名,则请求将被处理并被捕获process_request方法(因为你可以在标题中验证)?


Leo*_*Leo 5

默认情况下,scrapy会忽略 .zip 和 .pdf 。

作为一般规则,您可以配置规则以仅包含与您的正则表达式匹配的 url(在本例中为 .htm*):

rules = (Rule(SgmlLinkExtractor(allow=('\.htm')), callback='parse_page', follow=True, ), )
Run Code Online (Sandbox Code Playgroud)

或排除与正则表达式匹配的内容:

rules = (Rule(SgmlLinkExtractor(allow=('.*'), deny=('\.pdf', '\.zip')), callback='parse_page', follow=True, ), )
Run Code Online (Sandbox Code Playgroud)

阅读文档以获取更多信息。