2016-08-10 4 views
0

Ich behaupte, dass ich bereits einige Antworten über das gleiche Problem gelesen habe, aber das ich konnte mein Problem nicht lösen. Ich bin neu in Python, ich versuche, Daten von Aptoide über Apps und Stores zu extrahieren, und ich möchte ein Ergebnis als .json-Datei (oder CSV), aber die Datei, die ich bekomme, ist leer, weiß ich nicht der Grund.Leere Datei JSON als Ausgabe in Scrapy

Dies ist mein Code:

import scrapy 

    from scrapy.spiders import CrawlSpider, Rule 
    from scrapy.linkextractors import LinkExtractor 
    from scrapy.contrib.spiders import CrawlSpider, Rule 
    from scrapy.selector import HtmlXPathSelector 

    class ApptoideItem(scrapy.Item): 
     app_name = scrapy.Field() 
     rating = scrapy.Field() 
     security_status = scrapy.Field() 
     good_flag = scrapy.Field() 
     licence_flag = scrapy.Field() 
     fake_flag = scrapy.Field() 
     freeze_flag = scrapy.Field() 
     virus_flag = scrapy.Field() 
     five_stars = scrapy.Field() 
     four_stars = scrapy.Field() 
     three_stars = scrapy.Field() 
     two_stars = scrapy.Field() 
     one_stars = scrapy.Field() 
     info = scrapy.Field() 
     download = scrapy.Field() 
     version = scrapy.Field() 
     size = scrapy.Field() 
     link = scrapy.Field() 
     store = scrapy.Field() 

class AppSpider(CrawlSpider): 
    name = "second" 
    allowed_domains = ["aptoide.com"] 
    start_urls = [ "http://www.aptoide.com/page/morestores/type:top" ] 

    rules = (
     Rule(LinkExtractor(allow=(r'\w+\.store\.aptoide\.com$'))), 

     Rule(LinkExtractor(allow=(r'\w+\.store\.aptoide\.com/app/market')), callback='parse_item') 
     ) 


def parse_item(self, response): 

    item = ApptoideItem() 
    item['app_name']= str(response.css(".app_name::text").extract()[0]) 
    item['rating']= str(response.css(".app_rating_number::text").extract()[0]) 
    item['security_status']= str(response.css("#show_app_malware_data::text").extract()[0]) 
    item['good_flag']= int(response.css(".good > div:nth-child(3)::text").extract()[0]) 
    item['licence_flag']= int(response.css(".license > div:nth-child(3)::text").extract()[0]) 
    item['fake_flag']= int(response.css(".fake > div:nth-child(3)::text").extract()[0]) 
    item['freeze_flag']= int(response.css(".freeze > div:nth-child(3)::text").extract()[0]) 
    item['virus_flag']= int(response.css(".virus > div:nth-child(3)::text").extract()[0]) 
    item['five_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(1) > div:nth-child(3)::text").extract()[0]) 
    item['four_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(2) > div:nth-child(3)::text").extract()[0]) 
    item['three_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(3) > div:nth-child(3)::text").extract()[0]) 
    item['two_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(4) > div:nth-child(3)::text").extract()[0]) 
    item['link']= response.url 
    item['one_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(5) > div:nth-child(3)::text").extract()[0]) 
    item['download']= int(response.css("p.app_meta::text").re('(\d[\w\.]*)')[0].replace('.', '')) 
    item['version']= str(response.css("p.app_meta::text").re('(\d[\w\.]*)')[1]) 
    item['size']= str(response.css("p.app_meta::text").re('(\d[\w\.]*)')[2]) 
    item['store_name']= str(response.css(".sec_header_txt::text").extract()[0]) 
    item['info_store']= str(response.css(".ter_header2::text").extract()[0]) 
    yield item 

Ich bin mir ziemlich sicher, dass die problema, dass parse_item Methode nie aufgerufen, und ich weiß nicht den Grund. Die erste Regel folgt den Geschäften, während die zweite den Apps in Geschäften folgt. Ich denke, die Syntax von regulären Ausdrücken ist richtig.

Einstellung sind:

CLOSESPIDER_PAGECOUNT = 1000 
CLOSESPIDER_ITEMCOUNT = 500 
CONCURRENT_REQUESTS = 1 
CONCURRENT_ITEMS = 1 

BOT_NAME = 'nuovo' 


SPIDER_MODULES = ['nuovo.spiders'] 
NEWSPIDER_MODULE = 'nuovo.spiders' 

Könnte jemand das Problem und schlagen mir eine Lösung finden?

+0

Haben Sie überprüft, dass Ihre Xpath-Ausdrücke über 'scrapy shell' funktionieren? Kommt die Ausgabe vielleicht über 'JavaScript'? Außerdem bietet 'scrapy' eine Methode namens' extract_first() ', so dass Sie sich nicht mit den Indizes herumärgern müssen. – Jan

Antwort

0

Ihr Code ist voller Fehler, wenn Sie die Spinne laufen können Sie das Protokoll speichern und durch die es mit grep:

scrapy crawl spidername 2>&1 | tee crawl.log 

Ein paar Fehler, die ich gefunden:

  • Ihre ApptoideItem ist fehlende Felder wie store_name und einige andere.
  • Ihre gesamte int() Konvertierung ist unsicher, was bedeutet, wenn Ihre response.css None zurückgibt, was es tut, wenn es nichts findet, erhalten Sie einen Fehler.

den zweiten Punkt beheben Ich schlage vor, in scrapy ItemLoaders suchen, die Sie Standardverhalten für einige Felder, wie wiederum Elemente in Feldern _flag boolean usw.
auch als @Jan erwähnt in den Kommentaren Sie angeben können, sollte extract_first() Methode anstelle von extract()[0] verwenden, extract_first können Sie angeben, Standard-Attribut für, wenn nichts gefunden wird, dh .extract_first(default=0)