python - 如何将 scrapy.Field 填充为字典

标签 python scrapy

我正在为 www.apkmirror.com 构建一个抓取工具使用 Scrapy (与 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

ApkMirrorScraperItemitems.py中定义如下:

class ApkmirrorScraperItem(scrapy.Item):
    url = scrapy.Field()
    title = scrapy.Field()
    developer = scrapy.Field()

如果我使用命令从项目目录运行它,生成的 JSON 输出

scrapy crawl apkmirror-spider -o data.json

是一个 JSON 字典数组,键为 urltitledeveloper,相应的字符串作为值。但是,我想修改它,以便 developer 的值本身是一个带有 name 字段的字典,这样我就可以像这样填充它:

item['developer']['name'] = response.xpath('//h3[@title]/a/text()').extract_first()

但是,如果我尝试这样做,我会得到 KeyError,如果我初始化 developerField(这是一个 dict 根据 https://doc.scrapy.org/en/latest/topics/items.html#item-fields ) 作为 developer = scrapy.Field(name=None)。我该怎么做?

最佳答案

Scrapy 在内部将字段实现为字典,但这并不意味着它们应该作为字典访问。当您调用 item['developer'] 时,您真正做的是获取字段的,而不是字段本身。因此,如果尚未设置该值,则会抛出 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 类并将 developer 值设置为该类的一个实例:

# 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

希望对您有所帮助:)

关于python - 如何将 scrapy.Field 填充为字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43396753/

相关文章:

python - 将 while 语句与 WebDriverWait 和 Expected_conditions 一起使用

python - 变量变化时的 Panel/Hvplot 交互

python - 改变bqplot中Fig的大小?

python - Scrapy Spider 记录我需要的文本(也可以在 scrapy shell 中工作),但不会将它们写入 JSON 文件

python - 使用带有日期/时间的 CSV 文件的 loadtext

python - 在正交投影中用 cartopy 绘制圆圈

python - Scrapy process.crawl() 导出数据到json

python - 使用 Privoxy Proxy for Tor 时,Scrapy 出现 NoneType 错误

python - 网页抓取错误: exceptions. MemoryError

python - 使用 Amazon Web Services 自动安排 Scrapy 爬虫