Um CrawlSpider Arbeit mit URLs in Sitemaps zu machen, können Sie einen benutzerdefinierten Link-Extraktor für XML-Antworten kochen, aber es sieht wie CrawlSpider
does not process XML responses. Sie müssen also auch _requests_to_follow
überschreiben, um sie zu akzeptieren.
Hier ist ein Beispiel Spinne ich mit einem sitemap.gz
URL versucht, mit (enthaltend ein Sitemap)
from scrapy.spiders.crawl import CrawlSpider, Rule
from scrapy.link import Link
from scrapy.http import Request
class XmlLinkExtractor():
def __init__(self, xpath, namespaces):
self.xpath = xpath
self.namespaces = namespaces
def extract_links(self, response):
selector = response.selector
if self.namespaces:
for i, ns in self.namespaces.items():
selector.register_namespace(i, ns)
for link in selector.xpath(self.xpath).extract():
yield Link(link)
class ExampleSitemapCrawlSpider(CrawlSpider):
name = "myspider"
start_urls = (
# link to a sitemap index file
'http://www.example.com/sitemap.gz',
# link to a sitemap file
#'http://www.example.com/sitemaps/sitemap-general.xml',
)
rules = (
# this handles sitemap indexes, following links to other sitemaps
Rule(XmlLinkExtractor('/sm:sitemapindex/sm:sitemap/sm:loc/text()',
{"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}),),
# this is for "leaf" pages in sitemaps
Rule(XmlLinkExtractor('/sm:urlset/sm:url/sm:loc/text()',
{"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}),
# here, defining the callback without follow=True
# makes the crawler stop at these pages level,
# not following deeper links
# unset the callback if you want those pages
# to go through other rules once downloaded
callback='parse_loc'),
# ... other rules
)
def _requests_to_follow(self, response):
# we need to override `_requests_to_follow`
# and comment these 2 lines, because they filter XML responses
#if not isinstance(response, HtmlResponse):
# return
seen = set()
for n, rule in enumerate(self._rules):
links = [lnk for lnk in rule.link_extractor.extract_links(response)
if lnk not in seen]
if links and rule.process_links:
links = rule.process_links(links)
for link in links:
seen.add(link)
r = Request(url=link.url, callback=self._response_downloaded)
r.meta.update(rule=n, link_text=link.text)
yield rule.process_request(r)
def parse_loc(self, response):
self.logger.debug("parsing %r" % response)
Je nachdem, wie Sie von /urlset/url/loc
Seiten analysieren beginnen soll, können Sie verschiedene URLs zu verschiedenen Rückrufe umleiten (Hinzufügen von unterschiedlichen Regeln und Anpassen XmlLinkExtractor
Filterung zu ermöglichen (oder XPath zu verwenden, um Filter)
Danke Paul, auch eine andere Sache, die ich bemerkt habe ist, dass Steven auch die richtige Antwort hat. Das Problem besteht, wenn ich mit xml pages starte (wenn ich start_urls als xml gesetzt habe) in crawlspider. Wenn ich mit einer HTML-Seite anfange, dann gehe ich zu einer XML-Seite, die Crawlspider scheint mit Steven's Antwort den Trick zu machen. Danke Ihnen allen, dass Sie mir geholfen haben. Entschuldigung für die späte Antwort. – Saitx