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

Scrapy - как управлять куки файлами/сеансами

Я немного смущен тем, как файлы cookie работают с Scrapy, и как вы управляете этими кукисами.

Это в основном упрощенная версия того, что я пытаюсь сделать: enter image description here


Как работает сайт:

При посещении веб-сайта вы получаете файл cookie сеанса.

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


Мой script:

Мой паук имеет начальный URL-адрес searchpage_url

Поисковая страница запрашивается parse(), и ответ формы поиска передается search_generator()

search_generator(), затем yield множество поисковых запросов с использованием FormRequest и ответ формы поиска.

Каждый из этих FormRequests и последующих дочерних запросов должен иметь собственный сеанс, поэтому ему необходимо иметь собственный cookiejar и собственный cookie сеанса.


Я видел раздел документов, в котором говорится о мета-опции, которая запрещает объединение файлов cookie. Что это значит? Означает ли это, что у паука, у которого запрос будет иметь свой собственный cookiejar на всю оставшуюся жизнь?

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

Я предполагаю, что мне нужно отключить несколько одновременных запросов. В противном случае один паук будет выполнять несколько запросов в одном и том же файле cookie сессии, а будущие запросы будут касаться только самого последнего выполненного поиска?

Я в замешательстве, любые разъяснения будут получены очень сильно!


EDIT:

Другие параметры, о которых я только что подумал, полностью управляют cookie сеанса вручную и передают его от одного запроса другому.

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

Это то, что вы должны делать в этой ситуации?

4b9b3361

Ответ 1

Спустя три года, я думаю, это именно то, что вы искали: http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#std:reqmeta-cookiejar

Просто используйте что-то вроде этого в методе spider start_requests:

for i, url in enumerate(urls):
    yield scrapy.Request("http://www.example.com", meta={'cookiejar': i},
        callback=self.parse_page)

И помните, что для последующих запросов вам нужно явно привязывать cookiejar каждый раз:

def parse_page(self, response):
    # do some processing
    return scrapy.Request("http://www.example.com/otherpage",
        meta={'cookiejar': response.meta['cookiejar']},
        callback=self.parse_other_page)

Ответ 2

from scrapy.http.cookies import CookieJar
...

class Spider(BaseSpider):
    def parse(self, response):
        '''Parse category page, extract subcategories links.'''

        hxs = HtmlXPathSelector(response)
        subcategories = hxs.select(".../@href")
        for subcategorySearchLink in subcategories:
            subcategorySearchLink = urlparse.urljoin(response.url, subcategorySearchLink)
            self.log('Found subcategory link: ' + subcategorySearchLink), log.DEBUG)
            yield Request(subcategorySearchLink, callback = self.extractItemLinks,
                          meta = {'dont_merge_cookies': True})
            '''Use dont_merge_cookies to force site generate new PHPSESSID cookie.
            This is needed because the site uses sessions to remember the search parameters.'''

    def extractItemLinks(self, response):
        '''Extract item links from subcategory page and go to next page.'''
        hxs = HtmlXPathSelector(response)
        for itemLink in hxs.select(".../a/@href"):
            itemLink = urlparse.urljoin(response.url, itemLink)
            print 'Requesting item page %s' % itemLink
            yield Request(...)

        nextPageLink = self.getFirst(".../@href", hxs)
        if nextPageLink:
            nextPageLink = urlparse.urljoin(response.url, nextPageLink)
            self.log('\nGoing to next search page: ' + nextPageLink + '\n', log.DEBUG)
            cookieJar = response.meta.setdefault('cookie_jar', CookieJar())
            cookieJar.extract_cookies(response, response.request)
            request = Request(nextPageLink, callback = self.extractItemLinks,
                          meta = {'dont_merge_cookies': True, 'cookie_jar': cookieJar})
            cookieJar.add_cookie_header(request) # apply Set-Cookie ourselves
            yield request
        else:
            self.log('Whole subcategory scraped.', log.DEBUG)

Ответ 3

Я думаю, что самым простым подходом было бы запустить несколько экземпляров одного и того же паука, используя поисковый запрос в качестве аргумента паука (который будет получен в конструкторе), чтобы повторно использовать функцию управления cookie Scrapy. Таким образом, у вас будет несколько экземпляров spider, каждый из которых сканирует один конкретный поисковый запрос и его результаты. Но вам нужно запускать пауков самостоятельно:

scrapy crawl myspider -a search_query=something

Или вы можете использовать Scrapyd для запуска всех пауков через API JSON.

Ответ 4

def parse(self, response):
    # do something
    yield scrapy.Request(
        url= "http://new-page-to-parse.com/page/4/",
        cookies= {
            'h0':'blah',
            'taeyeon':'pretty'
        },
        callback= self.parse
    )