如何将 scrapy.Field 填充为字典
How to populate a scrapy.Field as a dictionary
我正在为 www.apkmirror.com using Scrapy (with the SitemapSpider 蜘蛛构建一个抓取工具)。到目前为止,以下作品:
DEBUG = True
from scrapy.spiders import SitemapSpider
from apkmirror_scraper.items import ApkmirrorScraperItem
class ApkmirrorSitemapSpider(SitemapSpider):
name = 'apkmirror-spider'
sitemap_urls = ['http://www.apkmirror.com/sitemap_index.xml']
sitemap_rules = [(r'.*-android-apk-download/$', 'parse')]
if DEBUG:
custom_settings = {'CLOSESPIDER_PAGECOUNT': 20}
def parse(self, response):
item = ApkmirrorScraperItem()
item['url'] = response.url
item['title'] = response.xpath('//h1[@title]/text()').extract_first()
item['developer'] = response.xpath('//h3[@title]/a/text()').extract_first()
return item
其中ApkMirrorScraperItem
在items.py
中的定义如下:
class ApkmirrorScraperItem(scrapy.Item):
url = scrapy.Field()
title = scrapy.Field()
developer = scrapy.Field()
结果JSON输出如果我运行它从项目目录使用命令
scrapy crawl apkmirror-spider -o data.json
是一个包含 JSON 个字典的数组,键为 url
、title
和 developer
,相应的字符串作为值。但是,我想修改它,以便 developer
的值本身就是一个带有 name
字段的字典,这样我就可以像这样填充它:
item['developer']['name'] = response.xpath('//h3[@title]/a/text()').extract_first()
但是,如果我尝试这样做,我会得到 KeyError
s,如果我初始化 developer
的 Field
(根据 https://doc.scrapy.org/en/latest/topics/items.html#item-fields) 为 developer = scrapy.Field(name=None)
。我该怎么做?
Scrapy 在内部将字段实现为字典,但这并不意味着它们应该作为字典访问。当您调用 item['developer']
时,您真正做的是获取字段的 value,而不是字段本身。因此,如果尚未设置该值,则会抛出 KeyError。
考虑到这一点,有两种方法可以解决您的问题。
第一个,将 developer 字段值设置为字典:
def parse(self, response):
item = ApkmirrorScraperItem()
item['url'] = response.url
item['title'] = response.xpath('//h1[@title]/text()').extract_first()
item['developer'] = {'name': response.xpath('//h3[@title]/a/text()').extract_first()}
return item
第二个,创建一个新的 Developer class 并将 developer 值设置为这个 class 的一个实例:
# this can go to items.py
class Developer(scrapy.Item):
name = scrapy.Field()
def parse(self, response):
item = ApkmirrorScraperItem()
item['url'] = response.url
item['title'] = response.xpath('//h1[@title]/text()').extract_first()
dev = Developer()
dev['name'] = response.xpath('//h3[@title]/a/text()').extract_first()
item['developer'] = dev
return item
希望对您有所帮助:)
我正在为 www.apkmirror.com using Scrapy (with the SitemapSpider 蜘蛛构建一个抓取工具)。到目前为止,以下作品:
DEBUG = True
from scrapy.spiders import SitemapSpider
from apkmirror_scraper.items import ApkmirrorScraperItem
class ApkmirrorSitemapSpider(SitemapSpider):
name = 'apkmirror-spider'
sitemap_urls = ['http://www.apkmirror.com/sitemap_index.xml']
sitemap_rules = [(r'.*-android-apk-download/$', 'parse')]
if DEBUG:
custom_settings = {'CLOSESPIDER_PAGECOUNT': 20}
def parse(self, response):
item = ApkmirrorScraperItem()
item['url'] = response.url
item['title'] = response.xpath('//h1[@title]/text()').extract_first()
item['developer'] = response.xpath('//h3[@title]/a/text()').extract_first()
return item
其中ApkMirrorScraperItem
在items.py
中的定义如下:
class ApkmirrorScraperItem(scrapy.Item):
url = scrapy.Field()
title = scrapy.Field()
developer = scrapy.Field()
结果JSON输出如果我运行它从项目目录使用命令
scrapy crawl apkmirror-spider -o data.json
是一个包含 JSON 个字典的数组,键为 url
、title
和 developer
,相应的字符串作为值。但是,我想修改它,以便 developer
的值本身就是一个带有 name
字段的字典,这样我就可以像这样填充它:
item['developer']['name'] = response.xpath('//h3[@title]/a/text()').extract_first()
但是,如果我尝试这样做,我会得到 KeyError
s,如果我初始化 developer
的 Field
(根据 https://doc.scrapy.org/en/latest/topics/items.html#item-fields) 为 developer = scrapy.Field(name=None)
。我该怎么做?
Scrapy 在内部将字段实现为字典,但这并不意味着它们应该作为字典访问。当您调用 item['developer']
时,您真正做的是获取字段的 value,而不是字段本身。因此,如果尚未设置该值,则会抛出 KeyError。
考虑到这一点,有两种方法可以解决您的问题。
第一个,将 developer 字段值设置为字典:
def parse(self, response):
item = ApkmirrorScraperItem()
item['url'] = response.url
item['title'] = response.xpath('//h1[@title]/text()').extract_first()
item['developer'] = {'name': response.xpath('//h3[@title]/a/text()').extract_first()}
return item
第二个,创建一个新的 Developer class 并将 developer 值设置为这个 class 的一个实例:
# this can go to items.py
class Developer(scrapy.Item):
name = scrapy.Field()
def parse(self, response):
item = ApkmirrorScraperItem()
item['url'] = response.url
item['title'] = response.xpath('//h1[@title]/text()').extract_first()
dev = Developer()
dev['name'] = response.xpath('//h3[@title]/a/text()').extract_first()
item['developer'] = dev
return item
希望对您有所帮助:)