You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向Scrapy传递非正则表达式的‘禁止爬取’URL列表?

解决Scrapy传入禁止爬取URL列表的问题

方法一:将URL列表转为正则表达式列表

LinkExtractor的deny参数支持正则表达式字符串列表,你可以把每个目标URL转成匹配完整路径的正则规则,避免部分匹配或特殊字符冲突:

  • 用re.escape()处理URL中的特殊符号(如?、&),防止正则语法报错
  • 给每个处理后的URL加上^和$,确保只匹配完整的目标URL

示例代码:

import re
from scrapy.linkextractors import LinkExtractor

# 已索引的URL列表
indexed_urls = [
    "https://example.com/job/123",
    "https://example.com/job/456?source=sitemap"
]

# 转换为符合要求的正则列表
deny_patterns = [f"^{re.escape(url)}$" for url in indexed_urls]

# 在LinkExtractor中使用
link_extractor = LinkExtractor(deny=deny_patterns)

方法二:利用Scrapy内置去重机制(更适配你的场景)

既然你的需求是每日爬取新页面、跳过已索引内容,直接用Scrapy的去重过滤器更高效,不需要手动处理deny参数:

  • 将已索引URL加载到Scrapy的去重队列,框架会自动跳过重复请求
  • 可在爬虫初始化时批量导入历史URL到去重器中

示例代码(基于SitemapSpider):

import scrapy
from scrapy.spiders import SitemapSpider

class JobCrawler(SitemapSpider):
    name = 'job_crawler'
    sitemap_urls = ['https://example.com/sitemap.xml']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 从文件加载已索引URL(假设每行一个URL)
        with open('indexed_urls.txt', 'r') as f:
            indexed_urls = set(f.read().splitlines())
        
        # 获取去重过滤器实例,批量添加已爬URL的指纹
        dupe_filter = self.crawler.engine.downloader.middlewares['scrapy.downloadermiddlewares.duplicates.DupeFilter']
        for url in indexed_urls:
            request_fingerprint = self.crawler.request_fingerprint(scrapy.Request(url))
            dupe_filter.seen.add(request_fingerprint)

两种方法对比

  • 方法一适合少量URL的精确过滤,但URL数量过大时,正则列表会影响提取性能
  • 方法二更符合Scrapy的设计逻辑,适配大规模去重场景,推荐用于你的每日爬取需求

内容的提问来源于stack exchange,提问作者Nash Reilly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:30:38