it-swarm-ru.tech

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

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

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


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

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

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


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

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

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

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

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


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

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

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

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


Правка:

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

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

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

45
Acorn

Три года спустя, я думаю, это именно то, что вы искали: 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)
35
Noah_S
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)
5
warvariuc

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

scrapy crawl myspider -a search_query=something

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

1
Pablo Hoffman
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
    )
0
MKatleast3