Получение нового идентификатора сессии ASP.NET после истечения срока действия в Scrapy - PullRequest
0 голосов
/ 15 мая 2018

Я написал скребок в Scrapy 1.5, который успешно переходит на веб-страницу (работает ASP.NET под управлением IIS версии 8.5), отправляет форму, а затем переходит к очистке.Через несколько часов все страницы начинают возвращать пустые данные.Я считаю, что мой идентификатор сеанса ASP.NET истекает, когда это происходит.Я никогда не смогу пройти через всю таблицу (несколько тысяч страниц) при сканировании с уважительной скоростью, но таблица не меняется от сессии к сессии.Мой подход состоял в том, чтобы очистить, пока страницы не были возвращены пустыми, а затем вернуться на страницу отправки формы и повторно отправить форму.Я отслеживаю номер страницы, чтобы я мог выбрать, где я остановился.Проблема в том, что при повторной отправке формы страницы по-прежнему возвращаются пустыми.Если я останавливаю скребок и устанавливаю переменную count вручную на последнюю очищенную страницу, она прекрасно работает, когда я перезагружаю скребок.Используя fiddler, я вижу, что отличается только то, что у меня есть новый идентификатор сеанса ASP.NET.Итак, мой вопрос: как я могу очистить свой идентификатор сеанса ASP.NET, чтобы мне дали новый, и я мог продолжить очистку?Вот отредактированная версия паука:

class assessorSpider(scrapy.Spider):
    name = 'redacted'
    allowed_domains = ['redacted.redacted']
    start_urls = ['http://redacted.redacted/search.aspx']
    base_url = start_urls[0]
    rows_selector = '#T1 > tbody:nth-child(3) > tr'
    numberOfPages = -1
    count = 1

    def parse(self, response):
        #ASP.NET Session Id gets stored in the headers after initial search

        frmdata = {'id':'frmSearch', 'SearchField':'%','cmdGo':'Go'}
        yield scrapy.FormRequest(url = self.base_url, formdata = frmdata, callback = self.parse_index)
        self.log('Search submitted')

    def parse_index(self, response):
        self.log('proceeding to next page')
        rows = response.css(self.rows_selector)
        if (len(rows) < 50 and self.count != self.numberOfPages):
            self.log('Deficient rows. Resubmitting')
            yield scrapy.Request(callback=self.parse, url = self.base_url, headers='')
        self.log('Ready to yield value')
        for row in rows:
            value = {
               #a whole bunch of css selectors
            }
            yield value
        if self.numberOfPages == -1:
            self.numberOfPages = response.css('a.button::attr(href)')[2].extract().split('=')[-1]
        self.count = self.count + 1
        if self.count <= self.numberOfPages:
                self.log( self.base_url + '?page=' + str(self.count))
                yield scrapy.Request(callback=self.parse_index, url = self.base_url + '?page=' + str(self.count))

Примечание. Я прочитал, что выполнение запроса с просроченным идентификатором сеанса ASP.NET должно привести к созданию нового (в зависимости от того, как работает сайт).настроен), поэтому возможно, что scrapy не принимает новый идентификатор сеанса.Я не уверен, как диагностировать эту проблему.

1 Ответ

0 голосов
/ 16 мая 2018

На ум приходят две вещи:

1) Ваш запрос «начать новый сеанс» может быть отклонен загрузчиком: По умолчанию он фильтрует URL-адреса, которые он уже видел , например, ваш базовый URL. Попробуйте yield scrapy.Request(callback=self.parse, url = self.base_url, dont_filter=True, headers='') в своем "сбросе запроса сеанса"

2) Если это не работает (или, возможно, в дополнение к):

Я довольно новичок в Scrapy и Python, так что может быть более прямой метод "сбросить ваши куки", но указание свежего cookiejar должно сработать.

Cookiejar - это по существу диктованный объект, который отслеживает файлы cookie текущего сеанса. Вы можете указать ключ cookiejar, используя meta.

    # Set up a new session if bad news:
    if (len(rows) < 50 and self.count != self.numberOfPages):
        self.log('Deficient rows. Resubmitting')
        yield scrapy.Request(
            callback=self.parse,
            url=self.base_url,
            dont_filter=True,
            meta={
                # Since you are already tracking a counter,
                # this might make for a reasonable "next cookiejar id" 
                'cookiejar': self.count
            }
        )

Теперь, когда вы указываете новый cookiejar, вы находитесь в новом сеансе. Вы должны учитывать это в других ваших запросах, проверяя, установлен ли cookiejar, и продолжая передавать это значение. В противном случае вы вернетесь в cookiejar по умолчанию. Возможно, проще всего управлять этим ожиданием с самого начала, определив start_requests :

    def start_requests(self):
        return [
            scrapy.Request(
                url,
                dont_filter=True,
                meta={'cookiejar': self.count}
            ) for url in self.start_urls
        ]

Теперь вашим другим объектам запроса нужно просто реализовать следующий шаблон для «пребывания в том же сеансе», например, в вашем методе синтаксического анализа:

    yield scrapy.FormRequest(
        url = self.base_url,
        formdata = frmdata,
        callback = self.parse_index,
        meta={
            'cookiejar': response.meta.get('cookiejar')
        }
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...