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

如何用Python Scrapy解析XML站点地图?解析无结果求助

问题:Scrapy爬取XML站点地图时选择器无效、XMLFeedSpider无输出

尝试爬取XML站点地图:https://comercialtrevino.com/sitemap/sitemaprssatom_products.xml,先通过Scrapy Shell调试再编写爬虫提取目标URL,但遇到以下问题:

  1. Scrapy Shell选择器全部返回空数组
    执行过的命令:
scrapy shell "https://comercialtrevino.com/sitemap/sitemaprssatom_products.xml"
scrapy shell -s ROBOTSTXT_OBEY=False "https://comercialtrevino.com/sitemap/sitemaprssatom_products.xml"

尝试的选择器:

response.css("body")
response.css("entry")
response.css("url")
response.css("span.html-tag")
response.css("title")
response.xpath("//entry")
response.xpath("//loc")
response.xpath("//url")
response.xpath("//span")
response.xpath("//title")

所有输出都是空数组,但浏览器打开能看到大量<entry>标签,开发者工具有span.html-tag,view(response)也能看到<loc>标签。

  1. XMLFeedSpider无日志/打印输出
    编写的爬虫代码:
from scrapy.spiders import XMLFeedSpider
from scrapy.item import Item

class Trevi_Spider(XMLFeedSpider):
    name = 'trevi'
    start_urls = ["https://comercialtrevino.com/sitemap/sitemaprssatom_products.xml",]
    iterator = 'iternodes'
    namespaces = ['g', "http://base.google.com/ns/1.0"]
    #itertag = "g:link"
    itertag = 'entry'

    def parse_node(self, response, node):
        self.log('oiiiiiiiiiiiiiiiiiiiiiii ----------------> ', node, self.itertag)
        self.logger.info(f"Hi this is a {self.itertag} node!: {''.join(node.getall())}")

        item = Item()
        #item["src"] = node.xpath("/text()").get()
        item["src"] = node.xpath("//g:link/text()").get()
        print('oiiiiiiiiiiiiiiiiiiiii ------------------>', item)
        return item

控制台看不到任何打印或日志。


解决方案

一、Scrapy Shell选择器无效的修复

该XML站点地图带有XML命名空间,直接用标签名选择会失效,必须指定命名空间前缀:

  1. 先在Shell中查看XML的根命名空间:
response.xpath('namespace-uri(/*)').get()

会得到Atom标准命名空间:http://www.w3.org/2005/Atom。

  1. 正确的选择器写法:
  • XPath方式:先注册命名空间,再带前缀选择
    # 注册Atom命名空间
    response.selector.register_namespace('atom', 'http://www.w3.org/2005/Atom')
    # 选择所有entry标签
    response.xpath('//atom:entry')
    # 提取entry下的loc标签文本(商品URL)
    response.xpath('//atom:entry/atom:loc/text()').getall()
    
  • CSS方式:用|分隔命名空间前缀和标签名
    response.css('atom|entry')
    response.css('atom|entry atom|loc::text').getall()
    

注意:浏览器看到的span.html-tag是XML的渲染元素,不是原始响应内容,Scrapy抓取的是原始XML,所以无法通过选择器定位到它。

二、XMLFeedSpider无输出的修复

爬虫的核心问题是命名空间配置错误和itertag未指定命名空间前缀,修正后的代码如下:

from scrapy.spiders import XMLFeedSpider
from scrapy.item import Item, Field

class Trevi_Spider(XMLFeedSpider):
    name = 'trevi'
    start_urls = ["https://comercialtrevino.com/sitemap/sitemaprssatom_products.xml"]
    iterator = 'iternodes'
    # 命名空间需配置为字典:键是前缀,值是命名空间URI
    namespaces = {
        'atom': 'http://www.w3.org/2005/Atom',
        'g': 'http://base.google.com/ns/1.0'
    }
    # itertag必须带命名空间前缀,否则无法匹配节点
    itertag = 'atom:entry'

    def parse_node(self, response, node):
        self.log(f'找到entry节点: {node.xpath("atom:loc/text()").get()}')
        self.logger.info(f"当前entry的URL: {node.xpath('atom:loc/text()').get()}")

        item = Item()
        item.fields['src'] = Field()
        # 用相对路径选择当前entry下的g:link,避免全局重复搜索
        item["src"] = node.xpath('g:link/text()').get()
        print(f'提取的商品链接: {item["src"]}')
        return item

关键修复点:

  • namespaces必须是字典格式,而非列表;
  • itertag需添加atom:前缀,指定命名空间下的entry节点;
  • 提取子节点时用相对路径(去掉//),避免全局搜索导致的重复或错误;
  • 给Item添加Field定义,确保数据能正常存储。

三、额外注意事项

  • 先确认请求成功:在Shell中执行response.status,确保返回200;
  • 若遇反爬,可添加自定义User-Agent:
    scrapy shell -s USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "https://comercialtrevino.com/sitemap/sitemaprssatom_products.xml"
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:04:52