Scrapy SitemapSpider 从站点地图获取附加信息
Scrapy SitemapSpider get additional information from sitemap
我尝试使用SitemapSpider 来解析站点地图。请参阅以下代码,如何从站点地图的解析函数中获取其他信息。例如,站点地图已包含 news:keywords
和 news: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,
}
请告诉我你的想法,如果我能帮你做任何其他事情。
我尝试使用SitemapSpider 来解析站点地图。请参阅以下代码,如何从站点地图的解析函数中获取其他信息。例如,站点地图已包含 news:keywords
和 news: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,
}
请告诉我你的想法,如果我能帮你做任何其他事情。