2017-03-14 1 views
0

Ich bin neu in Python sowie Scrapy. Ich versuche, eine Seed-URL zu crawlen https://www.health.com/patients/status/.This Seed-URL enthält viele URLs. Aber ich will nur URLs holen, die Faci/Details/# somenumber aus dem Samen url .Die URL enthalten wie unten sein:web Crawlen und Extrahieren von Daten mit scrapy

https://www.health.com/patients/status/ ->https://www.health.com/Faci/Details/2                           
            -> https://www.health.com/Faci/Details/3 
            -> https://www.health.com/Faci/Details/4 



https://www.health.com/Faci/Details/2 -> https://www.health.com/provi/details/64 
           -> https://www.health.com/provi/details/65 


https://www.health.com/Faci/Details/3 -> https://www.health.com/provi/details/70 
           -> https://www.health.com/provi/details/71 

Innerhalb jeder https://www.health.com/Faci/Details/2 Seite gibt es https://www.health.com/provi/details/64 https://www.health.com/provi/details/65 ... .Schließlich Ich möchte um einige Daten von https://www.health.com/provi/details/#somenumber url.Wie kann ich das gleiche erreichen?

Ab jetzt habe ich den Code unten aus scrapy Tutorial versucht, und nur in der Lage URL zu kriechen, die https://www.health.com/Faci/Details/#somenumber .Seine nicht zu gehen https://www.health.com/provi/details/#somenumber .Ich enthält versucht Grenze zu setzen Tiefe in settings.py file.But hat es nicht funktioniert .

import scrapy 
from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 
from news.items import NewsItem 


class MySpider(CrawlSpider): 
name = 'provdetails.com' 
allowed_domains = ['health.com'] 
start_urls = ['https://www.health.com/patients/status/'] 

rules = (

    Rule(LinkExtractor(allow=('/Faci/Details/\d+',)), follow=True), 

    Rule(LinkExtractor(allow=('/provi/details/\d+',)),callback='parse_item'),     
) 

def parse_item(self, response): 
    self.logger.info('Hi, this is an item page! %s', response.url) 
    item = NewsItem() 
    item['id'] = response.xpath("//title/text()").extract() 
    item['name'] = response.xpath("//title/text()").extract() 
    item['description'] = response.css('p.introduction::text').extract() 
    filename='details.txt' 
    with open(filename, 'wb') as f: 
     f.write(item) 
    self.log('Saved file %s' % filename) 
    return item 

Bitte helfen Sie mir weiter vorgehen?

Antwort

1

Um ehrlich zu sein, gab mir die Regex-basierte und mächtige Rule/LinkExtractor oft eine harte Zeit. Für ein einfaches Projekt ist es vielleicht ein Ansatz, um alle Links auf der Seite zu extrahieren und dann auf das href Attribut zu schauen. Wenn die href Ihren Anforderungen entspricht, yield ein neues Response Objekt mit ihm. Zum Beispiel:

from scrapy.http import Request 
from scrapy.selector import Selector 
... 
    # follow links 
    for href in sel.xpath('//div[@class="contentLeft"]//div[@class="pageNavigation nobr"]//a').extract(): 
      linktext = Selector(text=href).xpath('//a/text()').extract_first() 
      if linktext and linktext[0] == "Weiter": 
        link = Selector(text=href).xpath('//a/@href').extract()[0] 
        url = response.urljoin(link) 
        print url 
        yield Request(url, callback=self.parse) 

Einige Anmerkungen zum Code:

response.xpath(...).extract() 

Dies wird eine Liste zurück, vielleicht mögen Sie einen Blick auf extract_first() haben, die das erste Element zur Verfügung stellen (oder None).

with open(filename, 'wb') as f: 

Dadurch wird die Datei mehrmals überschrieben werden. Du erhältst nur den letzten gespeicherten Gegenstand. Außerdem öffnen Sie die Datei im Binärmodus ('b'). Aus dem Dateinamen schätze ich, dass Sie es als Text lesen möchten? Verwenden Sie 'a' zum Anhängen? Siehe open() docs Eine Alternative ist die Verwendung der -o flag, um Scrapys-Einrichtungen zu verwenden, um die Elemente in JSON oder CSV zu speichern.

return item 

Es ist ein guter Stil zu yield Artikel, anstatt sie zurückzugeben. Zumindest, wenn Sie mehrere Elemente von einer Seite erstellen müssen, müssen Sie yield ihnen.

Ein anderer guter Ansatz ist: Verwenden Sie eine parse() - Funktion für einen Typ/Art der Seite.

Zum Beispiel jede Seite in start_urls füllen Ende in parse(). Von diesem extrahieren Sie konnte die Links und yieldRequest s für jede /Faci/Details/N Seite mit einem Rückruf parse_faci_details() extrahieren. In parse_faci_details() extrahieren Sie erneut die Links von Interesse, erstellen Sie Request s und übergeben Sie sie über callback= an z. parse_provi_details(). In dieser Funktion erstellen Sie die benötigten Artikel.

Verwandte Themen