python - how - scrapy robotstxt_obey
Scrapy: cómo administrar cookies/sesiones (4)
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 administración de cookies de Scrapy. Por lo tanto, tendrá varias instancias de araña, cada una rastreando una consulta de búsqueda específica y sus resultados. Pero necesitas correr 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.
Estoy un poco confundido sobre cómo funcionan las cookies con Scrapy, y cómo administra esas cookies.
Esta es básicamente una versión simplificada de lo que intento hacer:
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 ha buscado, de modo que cuando hace algo como ir a la siguiente página de resultados, conoce la búsqueda con la que está tratando.
Mi guion
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 pasa a search_generator()
search_generator()
luego search_generator()
muchas solicitudes de búsqueda usando FormRequest
y la respuesta del formulario de búsqueda.
Cada una de esas Peticiones de Formulario y las subsiguientes solicitudes de hijos necesitan tener su propia sesión, por lo que deben tener su propio cookiejar individual y su propia cookie de sesión.
He visto la sección de los documentos que habla de una opción de meta que impide que las cookies se fusionen. ¿Qué significa eso realmente? ¿Significa que la araña que realiza la solicitud tendrá su propia cookiejar por el resto de su vida?
Si las cookies están en un nivel por araña, ¿cómo funciona cuando se generan múltiples arañas? ¿Es posible hacer que solo el primer generador de solicitudes engendre nuevas arañas y asegurarse de que a partir de ese momento solo esa araña se encargue de futuras solicitudes?
Supongo que tengo que deshabilitar múltiples solicitudes simultáneas. De lo contrario, una araña haría múltiples búsquedas bajo la misma cookie de sesión, y las futuras solicitudes solo se relacionarán con la búsqueda más reciente realizada.
Estoy confundido, cualquier aclaración sería muy recibida!
EDITAR:
Otra opción en la que he pensado es administrar la cookie de sesión completamente de forma manual y pasarla de una solicitud a la 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 estabas buscando: http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#std:reqmeta-cookiejar
Simplemente use algo como esto en el método start_requests de su 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 vincular 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)
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
)
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)