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

Scrapy爬取招标网站遇访客页面拦截,求解决方案

问题分析与修复方案

核心问题点

  1. allowed_domains配置错误:写成了单数形式allowed_domain,且值为完整URL,正确写法应为域名列表allowed_domains = ['aji-france.com']
  2. 爬取逻辑顺序颠倒:当前代码直接跳转匿名访问链接,未先请求招标详情页,正确流程是先访问详情页,遇到拦截时再触发匿名访问
  3. 拦截处理缺失会话关联:匿名访问后需重新请求原详情页,而非直接在匿名访问的响应中提取内容
  4. XPath提取冗余:原代码提取的是HTML标签而非纯文本,需要优化XPath确保获取实体名称的文本内容

修正后的代码

import scrapy

BASE_DOMAIN = "aji-france.com"

class TendersSpider(scrapy.Spider):
    name = "tenders_spider"
    allowed_domains = [BASE_DOMAIN]
    start_urls = [
        'https://mapa.aji-france.com/mapa/marche/',
    ]

    def parse(self, response):
        # 遍历所有招标卡片,提取详情页链接
        for tender_card in response.xpath("//div[@class='card mb-2']"):
            detail_url = tender_card.xpath(".//a[@class='stretched-link']/@href").get()
            if detail_url:
                # 先请求详情页,遇到拦截时处理
                yield scrapy.Request(
                    response.urljoin(detail_url),
                    callback=self.parse_tender_detail,
                    meta={'original_url': detail_url}  # 保存原详情页URL,用于后续重访
                )

    def parse_tender_detail(self, response):
        # 检查是否是拦截页面(存在匿名访问按钮)
        anonymous_link = response.xpath("//a[contains(text(), 'Continuer la visite anonymement')]/@href").get()
        if anonymous_link:
            # 触发匿名访问,完成后重访原详情页
            yield scrapy.Request(
                response.urljoin(anonymous_link),
                callback=self.handle_anonymous_access,
                meta={'original_url': response.meta['original_url']},
                dont_filter=True
            )
            return
        
        # 正常页面,提取Etablissement信息
        entity_xpath = "//div[normalize-space()='Etablissement']/following-sibling::div//td/text()"
        entity_name = response.xpath(entity_xpath).get(default="未找到实体名称")
        yield {
            'entity': entity_name.strip() if entity_name else "未找到实体名称",
            'detail_url': response.url
        }

    def handle_anonymous_access(self, response):
        # 匿名访问完成后,重新请求原详情页
        original_url = response.meta['original_url']
        yield scrapy.Request(
            response.urljoin(original_url),
            callback=self.parse_tender_detail,
            dont_filter=True
        )

关键修复说明

  • 会话保持:Scrapy自动维护CookieJar,匿名访问后Cookie会被保留,重访详情页时即可正常访问
  • 逻辑调整:先请求详情页,判断是否被拦截,再触发匿名访问,最后重访详情页,符合网站访问流程
  • XPath优化:提取text()而非直接获取标签,确保拿到纯文本的实体名称
  • 错误处理:用default参数处理找不到内容的情况,保证输出稳定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:45:36