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

Scrapy可下载HTML文件却无法下载XML文件的问题排查

Scrapy爬虫XML文件无法下载的问题及修复方案

问题描述

当前爬虫仅提取已爬页面中的XML链接,但未适配URL存在差异的实际可访问XML页面,需调整爬虫规则;同时脚本虽能抓取所有链接并将XML链接写入CSV,但无法成功下载XML文件,仅HTML文件保存正常。

URL差异示例

  • 页面提取的原始XML链接:http://www.digitalhumanities.org/dhq/vol/12/4/000401/000401.xml
  • 实际可访问的XML页面URL:http://www.digitalhumanities.org/dhq/vol/12/4/000401.xml

报错日志

2022-12-22 12:33:30 [scrapy.pipelines.files] WARNING: File (code: 302): Error downloading file from <GET http://www.digitalhumanities.org/dhq/vol/12/4/000407.xml> referred in <None>
2022-12-22 12:33:30 [scrapy.core.engine] DEBUG: Crawled (302) <GET http://www.digitalhumanities.org/dhq/vol/12/4/000408.xml> (referer: None)
2022-12-22 12:33:30 [scrapy.pipelines.files] WARNING: File (code: 302): Error downloading file from <GET http://www.digitalhumanities.org/dhq/vol/12/4/000408.xml> referred in <None>

现有爬虫代码

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor

class DhqSpider(CrawlSpider):
    name = 'dhqfiles'
    allowed_domains = ['digitalhumanities.org']
    start_urls = ['http://www.digitalhumanities.org/dhq/vol/16/3/index.html']

    rules = (
            Rule(LinkExtractor(allow = 'index.html')), 
            Rule(LinkExtractor(allow = 'vol'), callback='parse_article'),        
        )

    def parse_article(self, response):
        article = { 
            'xmllink' : response.urljoin(response.xpath('(//div[@class="toolbar"]/a[contains(@href, ".xml")]/@href)[1]').get()),
        }
        yield {'file_urls':[article['xmllink']]}

修复方案

1. 修正XML链接格式

针对提取的链接存在冗余目录的问题,通过字符串处理去除重复路径部分:

def parse_article(self, response):
    raw_xml_href = response.xpath('(//div[@class="toolbar"]/a[contains(@href, ".xml")]/@href)[1]').get()
    if raw_xml_href:
        # 拆分链接路径,去除冗余的同名子目录
        path_parts = raw_xml_href.split('/')
        filename = path_parts[-1].replace('.xml', '')
        if len(path_parts) >= 2 and path_parts[-2] == filename:
            corrected_href = '/'.join(path_parts[:-2] + [path_parts[-1]])
        else:
            corrected_href = raw_xml_href
        xmllink = response.urljoin(corrected_href)
        yield {'file_urls': [xmllink]}

2. 处理302重定向与Referer缺失问题

在settings.py中添加配置,确保爬虫自动跟随重定向并携带Referer:

# 基础配置
DOWNLOAD_DELAY = 1
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'

# 文件存储配置
FILES_STORE = './downloaded_files'
FILES_URLS_FIELD = 'file_urls'
FILES_RESULT_FIELD = 'files'

# 启用Referer中间件
DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.referer.RefererMiddleware': 700,
}

3. 优化爬虫规则

缩小链接匹配范围,避免无效页面抓取,确保遍历所有文章详情页:

rules = (
    # 跟进卷期索引页面
    Rule(LinkExtractor(allow=r'/vol/\d+/\d+/index\.html$'), follow=True),
    # 匹配文章详情页并调用解析函数
    Rule(LinkExtractor(allow=r'/vol/\d+/\d+/\d+$'), callback='parse_article'),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 02:50:30