Scrapy - cómo administrar las cookies / sesiones


Estoy un poco confundido en cuanto a cómo funcionan las cookies con Scrapy, y cómo administras esas cookies.

Esto es básicamente una versión simplificada de lo que estoy tratando de hacer: introduzca la descripción de la imagen aquí


La forma en que funciona el sitio web:

Cuando visita el sitio web, obtiene una cookie de sesión.

Cuando haces una búsqueda, el sitio web recuerda lo que buscaste, por lo que cuando haces algo como ir a la siguiente página de resultados, sabe la búsqueda con la que está tratando.


Mi script:

Mi araña tiene una url de inicio de searchpage_url

La página de búsqueda es solicitada por parse() y la respuesta del formulario de búsqueda se pasa a search_generator()

search_generator() entonces yield s un montón de solicitudes de búsqueda utilizando FormRequest y la respuesta del formulario de búsqueda.

Cada una de esas solicitudes de formulario y las solicitudes secundarias posteriores deben tener su propia sesión, por lo que debe tener su propio cookiejar individual y su propia cookie de sesión.


He visto la sección de los documentos que habla acerca de una meta opción que impide que las cookies se fusionen. ¿Qué significa eso en realidad? ¿Significa que la araña que hace la petición tendrá su propio cookiejar por el resto de su vida?

Si las galletas están en un nivel por araña, entonces ¿cómo funciona cuando se generan varias arañas? ¿Es posible hacer que solo el primer generador de solicitudes genere nuevas arañas y asegurarse de que a partir de entonces solo esa araña se ocupe de las solicitudes futuras?

Asumo que tengo que desactivar múltiples solicitudes simultáneas.. de lo contrario, una araña estaría haciendo múltiples búsquedas bajo la misma cookie de sesión, y las solicitudes futuras solo se relacionarán con la búsqueda más reciente realizada?

Estoy confundido, cualquier aclaración sería muy bien recibida!


EDITAR:

Otra opción que acabo de pensar es administrar la cookie de sesión completamente manualmente y pasarla de una solicitud a otra.

Supongo que eso significaría deshabilitar las cookies.. y luego tomar la cookie de sesión de la respuesta de búsqueda y pasarla a cada solicitud posterior.

¿Es esto lo que debe hacer en esta situación?

Author: Acorn, 2011-02-13

4 answers

Tres años después, creo que esto es exactamente lo que estabas buscando: http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#std:reqmeta-cookiejar

Simplemente usa algo como esto en el método start_requests de tu araña:

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

Y recuerde que para las solicitudes posteriores, debe volver a conectar explícitamente el cookiejar cada vez:

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)
 29
Author: Noah_S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-26 22:33:09
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)
 4
Author: warvariuc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-22 08:46:39

Creo que el enfoque más simple sería ejecutar varias instancias de la misma araña utilizando la consulta de búsqueda como un argumento de araña (que se recibiría en el constructor), con el fin de reutilizar la función de gestión de cookies de Scrapy. Así que tendrás múltiples instancias de araña, cada una rastreando una consulta de búsqueda específica y sus resultados. Pero necesitas ejecutar las arañas tú mismo con:

scrapy crawl myspider -a search_query=something

O puede usar Scrapyd para ejecutar todas las arañas a través de la API JSON.

 1
Author: Pablo Hoffman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-13 14:33:43
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
Author: MKatleast3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-12 07:57:58