Scrapy - как управлять куки / сессиями - PullRequest
49 голосов
/ 13 февраля 2011

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

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


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

Когда вы посещаете веб-сайт, вы получаете сессионный cookie.

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


Мой сценарий:

У моего паука есть начальный URL searchpage_url

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

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

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


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

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

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

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


EDIT:

Еще один вариант, о котором я только что подумал, - это управление файлом cookie сеанса полностью вручную и передача его из одного запроса в другой.

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

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

Ответы [ 4 ]

38 голосов
/ 27 августа 2014

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

Просто используйте что-то подобное в методе 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)
6 голосов
/ 22 июня 2011
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)
1 голос
/ 13 февраля 2011

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

scrapy crawl myspider -a search_query=something

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

0 голосов
/ 12 февраля 2016
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
    )
...