2017-03-27 27 views
1

Ich benutze Scrapy, um URLs von einer Website zu entfernen. Im Moment gibt es alle URLs zurück, aber ich möchte nur URLs zurückgeben, die das Wort "Download" enthalten. Wie kann ich das machen?Zurückgeben bestimmter URLs nur in scrapy

from scrapy.selector import HtmlXPathSelector 
from scrapy.spider import BaseSpider 
from scrapy.http import Request 
import scrapy 

DOMAIN = 'somedomain.com' 
URL = 'http://' +str(DOMAIN) 

class MySpider(scrapy.Spider): 
    name = DOMAIN 
    allowed_domains = [DOMAIN] 
    start_urls = [ 
     URL 
    ] 

    def parse(self, response): 
     hxs = HtmlXPathSelector(response) 
     for url in hxs.select('//a/@href').extract(): 
      if not (url.startswith('http://') or url.startswith('https://')): 
       url= URL + url 
      print url 
      yield Request(url, callback=self.parse) 

EDIT:

I implementiert die folgenden Vorschläge. Es gibt immer noch einige Fehler, aber zumindest gibt dies nur die Links zurück, die den Download enthalten.

from scrapy.selector import HtmlXPathSelector 
from scrapy.spider import BaseSpider 
from scrapy.http import Request 
import scrapy 
from scrapy.linkextractors import LinkExtractor 


DOMAIN = 'somedomain.com' 
URL = 'http://' +str(DOMAIN) 

class MySpider(scrapy.Spider): 
    name = DOMAIN 
    allowed_domains = [DOMAIN] 
    start_urls = [ 
     URL 
    ] 

# First parse returns all the links of the website and feeds them to parse2 

    def parse(self, response): 
     hxs = HtmlXPathSelector(response) 
     for url in hxs.select('//a/@href').extract(): 
      if not (url.startswith('http://') or url.startswith('https://')): 
       url= URL + url 
      yield Request(url, callback=self.parse2) 

# Second parse selects only the links that contains download 

    def parse2(self, response): 
     le = LinkExtractor(allow=("download")) 
     for link in le.extract_links(response): 
       yield Request(url=link.url, callback=self.parse2) 
       print link.url 

Antwort

2

eine pythonic und saubere Lösung wäre LinkExtractor zu verwenden:

from scrapy.linkextractors import LinkExtractor 

... 

le = LinkExtractor(deny="download") 
for link in le.extract_links(response): 
    yield Request(url=link.url, callback=self.parse) 
+0

Vielen Dank, ich habe es funktioniert, aber auf diese Weise verweigert der Code jeden Link mit "Download", also das ist mindestens auf halbem Weg, aber wie kann ich es umgekehrt tun? – LuukS

+0

überprüfen Sie [LinkExtractor Dokumentation] (https://doc.scrapy.org/en/latest/topics/link-extractors.html), es bietet auch das 'allow' Attribut, so dass Sie eine andere LinkExtractor-Instanz damit erstellen können. – eLRuLL

+0

Probier es einfach, ich bekomme die gleiche Warnung wie mit dot.Py's Antwort: ScrapyDeprecationWarning: Modul 'scrapy.spider' ist veraltet, benutze' scrapy.spiders' statt von scrapy.spider import BaseSpider – LuukS

1

Sie versuchen zu überprüfen, ob eine Teilzeichenfolge in einer Zeichenfolge vorhanden ist.

Beispiel:

string = 'this is a simple string' 

'simple' in string 
True 

'zimple' in string 
False 

So haben Sie gerade wie eine if Anweisung hinzuzufügen:

if 'download' in url:

Nach der Zeile:

for url in hxs.select('//a/@href').extract():

d.h .:

for url in hxs.select('//a/@href').extract(): 
    if 'download' in url: 
     if not (url.startswith('http://') or url.startswith('https://')): 
      url = URL + url 
     print url 
     yield Request(url, callback=self.parse) 

So wird der Code nur überprüfen, ob Verbindung mit http:// beginnt, wenn die Bedingung 'download' in url kehrt True.

+0

Vielen Dank, habe ich versucht, so etwas wie diese selbst. Wenn ich es so mache, löst scrapy einen Fehler aus und sagt mir, dass ich stattdessen einen seiner Selektoren, css oder xpath, verwenden soll ... – LuukS

+0

Gelöst, es funktioniert, aber mein Crawler blockierte seinen eigenen Crawling-Pfad. – LuukS