2017-04-13 73 views
3

我正在使用Scrapy(与SitemapSpider蜘蛛)构建www.apkmirror.com的刮板。到目前为止以下工作:如何填充作为字典的scrapy.Field

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() 

,如果我使用命令

scrapy crawl apkmirror-spider -o data.json 
从项目目录运行它产生的JSON输出

是JSON字典数组,其密钥为url,titledeveloper,以及t他将相应的字符串作为值。我想不过来修改这个,从而使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)。我怎么去解决这个问题?

回答

3

Scrapy在内部将字段实现为字符串,但这并不意味着它们应该作为字符串来访问。当你打电话给item['developer']时,你真正在做的是获取该字段的,而不是字段本身。所以,如果该值尚未设置,这将抛出一个KeyError。

考虑到这一点,有两种方法可以解决您的问题。

首先一个,只是开发商字段的值设置为一个字典:

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 

第二个,建立新的开发类,并设置开发值是这个类的一个实例:

# 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 

希望它有帮助:)