Ich crawle 6 verschiedene allowed_domains und möchte die Tiefe von 1 Domain begrenzen. Wie würde ich die Tiefe dieser 1 Domäne in scrapy begrenzen? Oder wäre es möglich, nur eine Tiefe einer Offsite-Domain zu crawlen?Scrapy Set Tiefenlimit pro erlaubte_Domänen
5
A
Antwort
8
Scrapy bietet nichts dergleichen. Sie können set the DEPTH_LIMIT
per-spider, aber nicht per-Domäne.
Was können wir tun? Read the code, Kaffee trinken und lösen (Bestellung ist wichtig).
Die Idee ist, Scrapy eingebaute DepthMiddleware
und provide our custom one stattdessen zu deaktivieren.
Lassen Sie uns zunächst Einstellungen definieren:
DOMAIN_DEPTHS
ein Wörterbuch mit Tiefengrenzen pro DomainDEPTH_LIMIT
Einstellung sein würden wir als Standard ein, falls verlassen werde eine Domäne nicht konfiguriert ist
Beispiel Einstellungen:
DOMAIN_DEPTHS = {'amazon.com': 1, 'homedepot.com': 4}
DEPTH_LIMIT = 3
Okay, jetzt die benutzerdefinierte Middleware (basierend auf DepthMiddleware
):
from scrapy import log
from scrapy.http import Request
import tldextract
class DomainDepthMiddleware(object):
def __init__(self, domain_depths, default_depth):
self.domain_depths = domain_depths
self.default_depth = default_depth
@classmethod
def from_crawler(cls, crawler):
settings = crawler.settings
domain_depths = settings.getdict('DOMAIN_DEPTHS', default={})
default_depth = settings.getint('DEPTH_LIMIT', 1)
return cls(domain_depths, default_depth)
def process_spider_output(self, response, result, spider):
def _filter(request):
if isinstance(request, Request):
# get max depth per domain
domain = tldextract.extract(request.url).registered_domain
maxdepth = self.domain_depths.get(domain, self.default_depth)
depth = response.meta.get('depth', 0) + 1
request.meta['depth'] = depth
if maxdepth and depth > maxdepth:
log.msg(format="Ignoring link (depth > %(maxdepth)d): %(requrl)s ",
level=log.DEBUG, spider=spider,
maxdepth=maxdepth, requrl=request.url)
return False
return True
return (r for r in result or() if _filter(r))
Beachten Sie, dass es tldextract
Modul (verwendet, um einen Domain-Namen von URL zum Extrahieren) installiert werden benötigt:
>>> import tldextract
>>> url = 'http://stackoverflow.com/questions/27805952/scrapy-set-depth-limit-per-allowed-domains'
>>> tldextract.extract(url).registered_domain
'stackoverflow.com'
Jetzt brauchen wir um die Standard-Middleware auszuschalten und die von uns implementierte zu verwenden:
SPIDER_MIDDLEWARES = {
'myproject.middlewares.DomainDepthMiddleware': 900,
'scrapy.contrib.spidermiddleware.depth.DepthMiddleware': None
}
Verwandte Themen
- 1. Set-Header für Scrapy Shell-Anfrage
- 2. django Logging Set Kontext global pro Anfrage?
- 3. Set Ablauf pro Nachricht mit SpringJMS
- 4. set css übergang zu pixel pro sekunde
- 5. Scrapy, wie kann man die Zeit pro Domain begrenzen?
- 6. Wie Scrapy zeigen Benutzer Agent pro Download-Anfrage im Protokoll?
- 7. Scrapy Shell und Scrapy Splash
- 8. OpenGL Vertex Shader Set boolesch pro Vertex (glVertexAttribPointer)
- 9. Set Emacs defaut Schriftart Gesicht pro Puffer/Modus
- 10. Set Jackson DeserializationContext Attribut in pro-Anfrage, thread-sichere Weise
- 11. Python & Scrapy: Ausgabe mit Scrapy Version
- 12. Wie benutze ich scrapy-jsonrpc mit Scrapy
- 13. Wie viele Gegenstände wurden pro start_url geschabt
- 14. Dynamisch pipelline Präsenz in scrapy
- 15. Scrapy - Eingangsprozessor
- 16. Scrapy HtmlXPathSelector
- 17. Scrapy Pipeline
- 18. Anmelden Scrapy
- 19. Wie Anzahl gefolgt Seiten pro Website in Python Scrapy zu begrenzen
- 20. Crawlen mehrerer Sites mit Python Scrapy mit begrenzter Tiefe pro Site
- 21. Django benutzerdefinierte Management-Befehl ausgeführt Scrapy: Wie Scrapy-Optionen enthalten?
- 22. Set assoziativen Cache
- 23. Set vs. set python
- 24. Zeitquantum pro Prozess pro Thread
- 25. Scrap Website mit scrapy
- 26. Scrapy: Objekte dynamisch definieren
- 27. Mehrere Crawling mit Scrapy
- 28. Link Extractor in scrapy
- 29. Scrapy lieferte keine Daten
- 30. Scrapy Tutorial Ausnahmen
Wie unterscheidet sich tldextract von dem bekannteren Python-Paket 'tld'? –
@FredericBazin Ich bin mir nicht wirklich sicher, habe sie nicht verglichen. Ich denke hier ist es nicht sehr wichtig. Sie können jedes von ihnen verwenden oder es sogar mit 'urlparse()' lösen, das eine Gewohnheit 'extract_domain()' Funktion hat. Vielen Dank. – alecxe
Vielen Dank für eine großartige Erklärung! Sollte 'response.meta ['depth'] = 0 'über' depth = response.meta [' depth '] + 1' Else, ist' response.meta ['depth'] 'leer und würde einen Keyerror geben –