Как включить начальный URL в правило «allow» в SgmlLinkExtractor с помощью паука сканирования scrapy - PullRequest
7 голосов
/ 28 ноября 2011

Я искал много тем, но, похоже, не нашел ответа на мой конкретный вопрос.Я создал паук сканирования для веб-сайта, и он отлично работает.Затем я сделал похожий, чтобы сканировать похожий веб-сайт, но на этот раз у меня возникла небольшая проблема.До дела:

мой стартовый URL выглядит следующим образом: www.example.com.Страница содержит ссылки, которые я хочу применить, мой паук выглядит так:

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

...

У меня теперь есть проблема: каждый раз, когда я вношу начальный URL, он автоматически перенаправляется на www.example.com/locationAи все ссылки, которые я получил, работая с моим пауком, включают

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

Поэтому моя проблема заключается в том, как я могу включить www.example.com/locationA в возвращенные URL-адреса. Я даже получил информацию журнала, например:

-2011-11-28 21: 25: 33 + 1300 [пример.com] DEBUG: перенаправление (302) с http://www.example.com/>

-2011-11-28 21: 25: 34 + 1300 [example.com] DEBUG: перенаправление (302) на (реферер: нет)

  • 2011-11-28 21: 25: 37 + 1300 [example.com] ОТЛАДКА: Перенаправление (302) на (реферер: www.example.com/locationB)

Распечатайте с parse_item: www.example.com/locationB

....

Я думаю, что проблема может быть связана с этим (реферер: нет).Может ли кто-нибудь пролить свет на это ??

Я сузил эту проблему, изменив начальный URL-адрес на www.example.com/locationB.Поскольку все страницы содержат списки всех мест, на этот раз мой паук работает на:

-www.example.com / locationA

-www.example.com / locationC ...

В ореховой оболочке я ищу способ включить URL-адрес, который совпадает с (или перенаправляется с) стартовым URL-адресом, в список, над которым будет работать обратный вызов parse_item.

Ответы [ 4 ]

14 голосов
/ 07 февраля 2012

Поскольку у других есть такая же проблема, после большого количества поиска все, что вам нужно сделать, это присвоить вашей функции обратного вызова значение parse_start_url.

Например:

rules = (
        Rule(LinkExtractor(allow=(), restrict_xpaths=(
            '//*[contains(concat( " ", @class, " " ), concat( " ", "pagination-next", " " ))]//a',)), callback="parse_start_url", follow=True),
    )
3 голосов
/ 30 мая 2013

Добавление примера кода на основе подсказки:

I manage using following approach

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 will be parsed here
    return self.parse_items(response)

def parse_items(self, response):
    self.log('>>>>>>>> PARSE ITEM FROM %s' % response.url)
    """Scrape data from links based on Crawl Rules"""
1 голос
/ 28 ноября 2011

Сначала я подумал, что есть простое решение с использованием start_requests(), например:

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

Но тесты показали, что, когда вместо списка start_urls используется start_requests(), паук игнорирует rules, потому что CrawlSpider.parse(response) не вызывается.

Итак, вот мое решение:

import itertools
class SomeSpider(CrawlSpider):
    ....
    start_urls = ('YOUR_START_URL',)
    rules = (
        Rule(
            SgmlLinkExtractor(allow=(r'YOUR_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

Возможно, есть лучший способ.

0 голосов
/ 13 декабря 2017

Простой обходной путь - специально добавить правило для start_urls (в вашем случае: http://example.com/locationA) (не обращайте внимания на проблему с отступами):

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)
...