2017-04-13 2 views
0

Um scrapy zu lernen, versuche ich einige innere URLs von einer Liste start_urls zu kriechen. Das Problem ist, dass nicht alle Elemente von start_urls innere urls haben (hier möchte ich NaN zurückgeben). So wie kann ich die folgenden 2 Spalte Datenrahmen zurückgeben (**):Probleme beim Crawlen von Links in verlinkten Links mit scrapy?

visited_link, extracted_link 
https://www.example1.com, NaN 
https://www.example2.com, NaN 
https://www.example3.com, https://www.extracted-link3.com 

Bisher habe ich versucht zu:

In:

# -*- coding: utf-8 -*- 


class ToySpider(scrapy.Spider): 
    name = "toy_example" 

    allowed_domains = ["www.example.com"] 

    start_urls = ['https:example1.com', 
        'https:example2.com', 
        'https:example3.com'] 


    def parse(self, response): 
     links = response.xpath(".//*[@id='object']//tbody//tr//td//span//a") 

     lis_ = [] 

     for l in links: 
      item = ToyCrawlerItem() 
      item['visited_link'] = response.url 
      item['extracted_link'] = l.xpath('@href').extract_first() 
      yield item 

     lis_.append(item) 
     df = pd.DataFrame(lis_) 

     print('\n\n\n\n\n', df, '\n\n\n\n\n') 

     df.to_csv('/Users/user/Desktop/crawled_table.csv', index=False) 

jedoch der obige Code its me Rückkehr:

Out:

extracted_link,visited_link 
https://www.extracted-link.com,https://www.example1.com 

Ich versuchte, die None Ausgabe Werte mit verwalten:

if l == None: 
       item['visited_link'] = 'NaN' 
      else: 
       item['visited_link'] = response.url 

Aber es funktioniert nicht, eine Ahnung davon, wie (**)

* ja ein Datenrahmen zu bekommen, ich weiß, dass ich -o tun können, aber Ich werde Datenframeoperationen durchführen.

UPDATE

Nach @rrschmidt Antwort Lesen habe ich versucht zu:

def parse(self, response): 
    links = response.xpath(".//*[@id='object']//tbody//tr//td//span//a[2]") 

    lis_ = [] 

    for l in links: 

     item = ToyItem() 

     if len(l) == 0: 
      item['visited_link'] = 'NaN' 
     else: 
      item['visited_link'] = response.url 

     #item['visited_link'] = response.url 

     item['extracted_link'] = l.xpath('@href').extract_first() 

     yield item 

     print('\n\n\n Aqui:\n\n', item, "\n\n\n") 

    lis_.append(item) 
    df = pd.DataFrame(lis_) 

    print('\n\n\n\n\n', df, '\n\n\n\n\n') 

    df.to_csv('/Users/user/Desktop/crawled_table.csv', index=False) 

Trotzdem ist es mir immer noch die gleiche falsche Ausgabe zurückgegeben. Könnte mir jemand helfen, dieses Problem zu klären?

Antwort

0

Soweit ich mit dem Schaber gibt es zwei Probleme sehen kann:

  1. als parse für jedes Element in start_urls genannt wird und Sie erstellen und einen neuen Datenrahmen für jeden Link zu speichern, der Datenrahmen Sie sind Generieren überschreibt sich gegenseitig.

Deshalb sollten Sie immer nur ein Ergebnis haben in Ihrem crawled_table.csv

Lösung hierfür: die Datenrahmen nur einmal erstellen und alle Elemente in das gleiche Datenrahmen Objekt schieben.

Dann speichern Sie den Datenrahmen in jedem parse Aufruf, nur für den Fall, dass der Schaber vor dem Beenden stoppen muss.

  1. if l == None: funktioniert nicht, da response.xpath eine leere Liste zurückgibt, wenn keine Übereinstimmungen gefunden wurden. So if len(l) == 0: tun

In einem Kern tun sollten, ist hier, wie ich den Schaber strukturieren würde (Code nicht getestet!)

# -*- coding: utf-8 -*- 

class ToySpider(scrapy.Spider): 
    name = "toy_example" 

    allowed_domains = ["www.example.com"] 

    start_urls = ['https:example1.com', 
        'https:example2.com', 
        'https:example3.com'] 

    df = pd.DataFrame() 

    def parse(self, response): 
     links = response.xpath(".//*[@id='object']//tbody//tr//td//span//a[2]") 
     items = [] 

     if len(links) == 0: 
      item = ToyItem() 
      # build item with visited_link = NaN here 
      item['visited_link'] = response.url 
      item['extracted_link'] = 'NaN' 
      items.append(item) 
     else: 
      for l in links: 
       item = ToyItem() 
       # build the item as you previously did here 
       item['visited_link'] = response.url 
       item['extracted_link'] = l.xpath('@href').extract_first() 
       items.append(item) 

     items_df = pd.DataFrame(items) 
     self.df = self.df.append(items_df, ignore_index=True) 

     print('\n\n\n\n\n', self.df, '\n\n\n\n\n') 
     self.df.to_csv('/Users/user/Desktop/crawled_table.csv', index=False) 

     return items 
+0

Danke für die Hilfe. Ich habe versucht, die Einrückung zu beheben, um den Datenrahmen nicht mehr zu überschreiben, aber anscheinend hat das nicht geklappt.Außerdem habe ich versucht, den "len (l) == 0" Trick zu machen und es hat auch nicht funktioniert ... Könnten Sie ein Beispiel dafür geben? –

+1

Entschuldigung für die Verwirrung, ich habe einen Code hinzugefügt Beispiel, um die Struktur klar zu machen. – rrschmidt

+0

Wenn ich das 'df = pd.DataFrame()' -Objekt außerhalb der Parse-Funktion belasse, bekomme ich 'NameError: Name 'df' ist nicht definiert 'Ich lege es in die Funktion und checke die .csv-Datei aus und sie ist leer. .. eine Idee, was zu tun ist? –

Verwandte Themen