Scrapy SitemapSpider 从站点地图获取附加信息

Scrapy SitemapSpider get additional information from sitemap

我尝试使用SitemapSpider 来解析站点地图。请参阅以下代码,如何从站点地图的解析函数中获取其他信息。例如,站点地图已包含 news:keywordsnews:stock_tickers。我如何获取这些数据并传递给解析函数?

from scrapy.spiders import SitemapSpider
class ReutersSpider(SitemapSpider):
    name = 'reuters'
    sitemap_urls = ['https://www.reuters.com/sitemap_news_index1.xml']

    def parse(self, response):
        # How can I get data like news:stock_tickers from sitemap for this item? I only have url from the sitemap here.
        yield {
            'title': response.css("title ::text").extract_first(),
            'url': response.url
        }

站点地图项目示例

<url>
<loc>
https://www.reuters.com/article/micron-tech-results/update-6-micron-sales-profit-miss-estimates-as-chip-glut-hurts-prices-idUSL3N1YN50N
</loc>
<news:news>
<news:publication>
<news:name>Reuters</news:name>
<news:language>eng</news:language>
</news:publication>
<news:publication_date>2018-12-19T03:50:10+00:00</news:publication_date>
<news:title>
UPDATE 6-Micron sales, profit miss estimates as chip glut hurts prices
</news:title>
<news:keywords>Headlines,Industrial Conglomerates</news:keywords>
<news:stock_tickers>
SEO:000660,SEO:005930,TYO:6502,NASDAQ:AAPL,NASDAQ:AMZN
</news:stock_tickers>
</news:news>
</url>

SitemapSpider 专用于提取链接,仅此而已,因此它不提供从站点地图中提取额外数据的方法。

可以覆盖其_parse_sitemap方法以在生成的请求的元数据中传递数据。
但是,如果您的站点地图足够简单,那么您自己进行站点地图解析可能会更简单。

AS @stranac 指出,Scrapy(以及所有相关的蜘蛛)是为了从网络上获取信息而开发的,站点地图是在每个网站上找到产品链接的好方法,但事实并非如此擅长直接从站点地图中实际抓取信息。

所以按照建议,你需要创建自己的蜘蛛,应该是这样的:

from scrapy import Spider
from lxml import etree


class MySpider(Spider):
    name = 'sitemap_example'

    def start_requests(self):
        yield Request('https://www.reuters.com/sitemap_news_index1.xml')

    def parse(self, response):
        sitemap = etree.fromstring(response.body)
        for child in sitemap.getchildren():
            inner_children = child.getchildren()
            news_child = [x for x in inner_children if 'news' in x.tag]
            if not news_child:
                continue
            else:
                news_child = news_child[0]
                stock_child = [x for x in news_child if 'stock_tickers' in x.tag]
                keywords_child = [x for x in news_child if 'keywords' in x.tag]
                title_child = [x for x in news_child if 'title' in x.tag]
                if stock_child:
                    yield {
                        'stock_tickers': stock_child[0].text,
                        'keywords': keywords_child[0].text,
                        'title': title_child[0].text,
                    }

请告诉我你的想法,如果我能帮你做任何其他事情。