2017-04-13 72 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 

希望它有幫助:)