Scrapy – cómo gestionar cookies / sesiones

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

Esta 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 visitas el sitio web obtienes una cookie de sesión.

Cuando realiza una búsqueda, el sitio web recuerda lo que buscó, por lo que cuando hace algo como ir a la siguiente página de resultados, conoce la búsqueda con la que se está tratando.


Mi guion:

Mi araña tiene un inicio url 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() luego yield una gran cantidad 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 subsiguientes deben tener su propia sesión, por lo que deben tener su propia cookiejar individual y su propia cookie de sesión.


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

Si las cookies están en un nivel por Spider, entonces, ¿cómo funciona cuando se generan múltiples arañas? ¿Es posible hacer que solo el primer generador de solicitudes genere nuevas arañas y asegurarse de que a partir de ese momento solo la araña se encargue de futuras solicitudes?

Supongo que tengo que deshabilitar varias solicitudes concurrentes … de lo contrario, una araña estaría haciendo múltiples búsquedas en 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 recibida!


EDITAR:

Otra de las opciones que acabo de pensar es administrar la cookie de sesión de forma completamente manual 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 debes hacer en esta situación?

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

Solo 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 solicitudes posteriores, debe volver a adjuntar explícitamente el cookiejar cada vez que:

 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) 
 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) 

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), para reutilizar la función de administración de cookies de Scrapy. Por lo tanto, tendrá varias instancias de spider, cada una de las cuales rastreará una consulta de búsqueda específica y sus resultados. Pero necesitas correr las arañas 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.

 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 )