7 Stimmen

Wie man die Start-URL in der "allow" Regel in SgmlLinkExtractor unter Verwendung eines Scrapy-Crawl-Spiders einbezieht.

Ich habe viele Themen durchsucht, aber scheine keine Antwort auf meine spezifische Frage zu finden. Ich habe einen Crawl-Spider für eine Website erstellt und es funktioniert perfekt. Dann habe ich einen ähnlichen erstellt, um eine ähnliche Website zu durchsuchen, aber diesmal habe ich ein kleines Problem. Gehen wir zum Geschäft:

Meine Start-URL sieht wie folgt aus: www.example.com. Die Seite enthält die Links, auf die ich meinen Spider anwenden möchte, sehen aus wie:

  • www.example.com/locationA
  • www.example.com/locationB
  • www.example.com/locationC

...

Ich habe jetzt ein Problem: Jedes Mal, wenn ich die Start-URL aufrufe, wird automatisch zu www.example.com/locationA weitergeleitet und alle Links, auf denen mein Spider funktioniert, enthalten

  • www.example.com/locationB
  • www.example.com/locationC ...

Also mein Problem ist, wie ich die www.example.com/locationA in den zurückgegebenen URLs einbeziehen kann. Ich habe sogar die Protokollinformationen wie folgt erhalten:

-2011-11-28 21:25:33+1300 [example.com] DEBUG: Umleiten (302) zu von http://www.example.com/>

-2011-11-28 21:25:34+1300 [example.com] DEBUG: Umleiten (302) zu (Referer: Keiner)

  • 2011-11-28 21:25:37+1300 [example.com] DEBUG: Umleiten (302) zu (Referer: www.example.com/locationB)

Ausgabe aus parse_item: www.example.com/locationB

....

Ich denke, das Problem könnte damit zusammenhängen, dass (Referer: Keiner) irgendwie ist. Könnte bitte jemand etwas Licht darauf werfen??

Ich habe dieses Problem eingegrenzt, indem ich die Start-URL auf www.example.com/locationB geändert habe. Da alle Seiten die Listen aller Standorte enthalten, funktioniert mein Spider diesmal auf:

-www.example.com/locationA

-www.example.com/locationC ...

Kurz gesagt, ich suche nach dem Weg, die URL, die mit der Start-URL übereinstimmt (oder von ihr umgeleitet wird), in die Liste aufzunehmen, auf der der parse_item-Callback arbeiten wird.

14voto

mindcast Punkte 717

Für andere, die das gleiche Problem haben, nach viel Suchen, müssen Sie einfach Ihre Rückruffunktion auf parse_start_url benennen.

Zum Beispiel:

rules = (
        Rule(LinkExtractor(allow=(), restrict_xpaths=(
            '//*[contains(concat( " ", @class, " " ), concat( " ", "pagination-next", " " ))]//a',)), callback="parse_start_url", follow=True),
    )

3voto

totoro Punkte 195

Füge Beispielcode basierend auf Mindcast-Vorschlag hinzu:

Ich verwende den folgenden Ansatz:

class ExampleSpider(CrawlSpider):
name = "examplespider"
allowed_domains = ["example.com"]
start_urls = ['http://example.com/A']

rules = (Rule (SgmlLinkExtractor(restrict_xpaths=("//div[@id='tag_cloud']/a",)), callback="parse_items", follow= True),)

def parse_start_url(self, response):
    self.log('>>>>>>>> PARSE START URL: %s' % response)
    # www.example.com/A wird hier geparst
    return self.parse_items(response)

def parse_items(self, response):
    self.log('>>>>>>>> PARSE ITEM FROM %s' % response.url)
    """Daten von Links basierend auf Crawling-Regeln abkratzen"""

1voto

reclosedev Punkte 9172

Zuerst dachte ich, dass es eine einfache Lösung gibt, die start_requests() verwendet, wie:

def start_requests(self):
    yield Request('START_URL_HERE', callback=self.parse_item)    

Aber Tests haben gezeigt, dass, wenn start_requests() anstelle einer start_urls-Liste verwendet wird, die Spider die rules ignoriert, weil CrawlSpider.parse(response) nicht aufgerufen wird.

Also, hier ist meine Lösung:

import itertools
class SomeSpider(CrawlSpider):
    ....
    start_urls = ('DEINE_START_URL',)
    rules = (
        Rule(
            SgmlLinkExtractor(allow=(r'DEIN_REGEXP',),),
            follow=True,
            callback='parse_item'),
        ),
    )
    def parse(self, response):
        return itertools.chain(
                     CrawlSpider.parse(self, response), 
                     self.parse_item(response))

    def parse_item(self, response):
        yield item

Vielleicht gibt es einen besseren Weg.

0voto

K.Andy Wang Punkte 382

Ein einfacher Workaround besteht darin, eine Regel speziell für die start_urls hinzuzufügen (in Ihrem Fall: http://example.com/locationA )(Bitte ignorieren Sie das Einrückungsproblem):

class ExampleSpider(CrawlSpider):
  name = "examplespider"
  allowed_domains = ["example.com"]
  start_urls = ['http://example.com/locationA']

  rules = (
    Rule(LinkExtractor(allow=('locationA')), callback='parse_item'),
    Rule(LinkExtractor(allow=('location\.*?'),restrict_css=('.pagination-next',)), callback='parse_item', follow=True),
  )

  def parse_item(self, response):
       self.log('>>>>>>>> PARSE ITEM FROM %s' % response.url)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X