2016-07-09 1 views
3

у меня есть это правило для Scrapy CrawlSpiderправила Scrapy не работает, когда process_request и параметр обратного вызова установлены

rules = [ 
     Rule(LinkExtractor(
        allow= '/topic/\d+/organize$', 
        restrict_xpaths = '//div[@id= "zh-topic-organize-child-editor"]' 
        ), 
      process_request='request_tagPage', callback = "parse_tagPage", follow = True) 
    ] 

request_tagePage() относится к функции, чтобы добавить печенье в запросы и parse_tagPage() относится к функции для анализа целевых страниц. Согласно documentation, CrawlSpider должен использовать request_tagPage для выполнения запросов и после получения ответов он вызывает parse_tagPage() для его анализа. Однако я понял, что когда используется request_tagPage(), паук вообще не вызывает parse_tagPage(). Таким образом, в настоящем коде, я вручную добавить parse_tagPage() функцию обратного вызова в качестве обратного вызова в request_tagPage, как это:

def request_tagPage(self, request): 
    return Request(request.url, meta = {"cookiejar": 1}, \ # attach cookie to the request otherwise I can't login 
      headers = self.headers,\ 
      callback=self.parse_tagPage) # manually add a callback function. 

Он работал, но теперь паук не использует правила, чтобы расширить его ползать. Он закрывается после обхода ссылок с start_urls. Однако, прежде чем вручную установить parse_tagPage() в качестве обратного вызова в request_tagPage(), правила будут работать. Значит, я думаю, что это может быть ошибка? Можно ли включить request_tagPage(), который мне нужно приложить к файлу cookie в запросе, parse_tagPage(), который использовался для разбора страницы и rules, который направляет паука на сканирование?

+1

Вы уверены, что ваш linkextactor даже работает? откройте веб-сайт с помощью 'scrapy shell url' и импортируйте LinkExtractor и попробуйте использовать его с теми же аргументами в' response.body'. – Granitosaurus

+0

Это работает. Когда parse_tagPage() не используется как функция обратного вызова в request_tagPage(), я вижу на консоли, что паук сканирует, как и должно быть. Из документа scrapy [document on Rule object] (http://doc.scrapy.org/en/latest/topics/spiders.html?highlight=rule#scrapy.spiders.Rule) я думал, что set parse_tagPage() является обратным вызовом для Правило достаточно, оказалось, что функция обратного вызова вообще не вызывалась. Поэтому мне нужно поставить обратный вызов в request_tagPage(). Затем вызывается callbback, но паук теряет способность следить за ссылками, за исключением тех, что указаны в start_urls. – Skywalker326

+0

Вы пытались не создавать совершенно новый объект 'Request', а вместо этого использовать метод' Request.replace() '? Например. 'return request.replace (meta = {'cookiejar': 1}, headers = self.headers)'. 'CrawlSpider' обрабатывает все страницы в своем собственном обратном вызове' parse() ', который обрабатывает правила обхода контента, поэтому изменение« обратного вызова »по-мужски не кажется хорошим способом. – shirk3y

ответ

1

Я нашел проблему. CrawlSpider использует по умолчанию parse() для применения правил. Поэтому, когда вызывается мой обычай parse_tagPage(), больше нет parse() следует за продолжением применения правил. Решение состоит в том, чтобы просто добавить значение по умолчанию parse() в мой заказ parse_tagPage(). Она теперь выглядит следующим образом:

def parse_tagPage(self, response): 
    # parse the response, get the information I want... 
    # save the information into a local file... 
    return self.parse(response) # simply calls the default parse() function to enable the rules 
2

Запросы, генерируемые CrawlSpider правилами использования internal callbacks and use meta to do their "magic".

Я предлагаю вам не воссоздавать запросы с нуля в ваших правилах. process_request крючки (или вы, вероятно, сможете переопределить то, что CrawlSpider делает для вас уже).

Вместо этого, если вы просто хотите добавить печенье и специальные заголовки, вы можете использовать .replace() method on the request, который передается request_tagPage, так что «магия» из CrawlSpider сохраняется.

Что-то вроде этого должно быть достаточно:

def request_tagPage(self, request): 
    tagged = request.replace(headers=self.headers) 
    tagged.meta.update(cookiejar=1) 
    return tagged 
Смежные вопросы