2017-04-13 2 views
3

나는 www.apkmirror.com에 대한 스크레이퍼를 Scrapy (SitemapSpider 거미와 함께)으로 만들고 있습니다. 지금까지 다음 작품을 다음과 같이 ApkMirrorScraperItemitems.py에 정의되어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 

:

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

내가 명령

scrapy crawl apkmirror-spider -o data.json 
를 사용하여 프로젝트 디렉토리에서 실행하면 결과 JSON 출력

url, titledeveloper 키가있는 JSON 사전의 배열이며 t 그는 해당 문자열을 값으로 사용합니다.

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

을 그러나 내가 이것을하려고하면 내가 KeyError의를 얻을 : 나는 developer의 값 자체가 name 필드 사전 수 있도록 내가 이런 식으로 채울 수 있도록, 그러나,이 문제를 수정하고 싶습니다 , developerField (https://doc.scrapy.org/en/latest/topics/items.html#item-fields에 따른 dict에 따른)을 developer = scrapy.Field(name=None)으로 초기화하는 경우에도 마찬가지입니다. 이 문제를 어떻게 해결할 수 있습니까?

답변

3

스쿠버 레이션은 필드를 내부적으로 dicts로 구현하지만 이것이 dicts로 액세스되어야한다는 것을 의미하지는 않습니다. 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 

희망 하시겠습니까?

관련 문제