Подтвердить что ты не робот

Использование Scrapy с аутентифицированной (зарегистрированной) пользовательской сессией

В документации по Scrapy есть следующий пример, иллюстрирующий использование аутентифицированного сеанса в Scrapy:

class LoginSpider(BaseSpider):
    name = 'example.com'
    start_urls = ['http://www.example.com/users/login.php']

    def parse(self, response):
        return [FormRequest.from_response(response,
                    formdata={'username': 'john', 'password': 'secret'},
                    callback=self.after_login)]

    def after_login(self, response):
        # check login succeed before going on
        if "authentication failed" in response.body:
            self.log("Login failed", level=log.ERROR)
            return

        # continue scraping with authenticated session...

У меня это работает, и это нормально. Но мой вопрос: что вы должны сделать, чтобы continue scraping with authenticated session, как говорится в последнем комментарии?

4b9b3361

Ответ 1

В приведенном выше коде для FormRequest, который используется для аутентификации, в качестве обратного вызова установлена функция after_login. Это означает, что функция after_login будет вызвана и передана страница, которую попытка входа получила в ответ.

Затем он проверяет, что вы успешно вошли в систему, выполняя поиск на странице определенной строки, в данном случае "authentication failed". Если он находит это, паук заканчивается.

Теперь, когда паук зашел так далеко, он знает, что он успешно прошел аутентификацию, и вы можете начать создавать новые запросы и/или очищать данные. Итак, в этом случае:

from scrapy.selector import HtmlXPathSelector
from scrapy.http import Request

# ...

def after_login(self, response):
    # check login succeed before going on
    if "authentication failed" in response.body:
        self.log("Login failed", level=log.ERROR)
        return
    # We've successfully authenticated, let have some fun!
    else:
        return Request(url="http://www.example.com/tastypage/",
               callback=self.parse_tastypage)

def parse_tastypage(self, response):
    hxs = HtmlXPathSelector(response)
    yum = hxs.select('//img')

    # etc.

Если вы посмотрите здесь, есть пример паука, который проверяет подлинность перед очисткой.

В этом случае он обрабатывает вещи в функции parse (обратный вызов по умолчанию для любого запроса).

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    if hxs.select("//form[@id='UsernameLoginForm_LoginForm']"):
        return self.login(response)
    else:
        return self.get_section_links(response)

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

Я надеюсь, что это понятно, не стесняйтесь спрашивать, если у вас есть какие-либо другие вопросы!


Редактировать:

Итак, вы хотите сделать больше, чем просто создать один запрос и очистить его. Вы хотите перейти по ссылкам.

Для этого все, что вам нужно сделать, это очистить соответствующие ссылки со страницы и породить запросы, используя эти URL-адреса. Например:

def parse_page(self, response):
    """ Scrape useful stuff from page, and spawn new requests

    """
    hxs = HtmlXPathSelector(response)
    images = hxs.select('//img')
    # .. do something with them
    links = hxs.select('//a/@href')

    # Yield a new request for each link we found
    for link in links:
        yield Request(url=link, callback=self.parse_page)

Как вы можете видеть, он порождает новый запрос для каждого URL-адреса на странице, и каждый из этих запросов будет вызывать одну и ту же функцию со своим ответом, поэтому у нас есть рекурсивный анализ.

То, что я написал выше, это просто пример. Если вы хотите "сканировать" страницы, вы должны смотреть на CrawlSpider а не делать что-то вручную.