Scrapy – 如何pipe理Cookie /会话
对于Scrapy如何使用Cookie以及如何pipe理这些Cookie,我有点困惑。
这基本上是我想要做的简化版本:
网站的工作方式:
当你访问网站时,你会得到一个会话cookie。
当你进行search时,网站会记住你search的内容,所以当你进入下一页的search结果时,它会知道search结果。
我的脚本:
我的蜘蛛有一个searchpage_url的开始url
search页面被parse()
请求,search表单响应被传递给search_generator()
search_generator()
然后使用FormRequest
和search表单响应yield
大量的search请求。
每个FormRequests和后续的子请求都需要拥有它自己的会话,所以需要拥有它自己的cookiejar和它自己的会话cookie。
我已经看到文档的部分,谈论一个元选项,停止被合并的Cookie。 这实际上是什么意思? 这是否意味着使请求的蜘蛛在其余生命中将拥有自己的cookiejar?
如果每个蜘蛛级别的cookie都是这样的,那么当多个蜘蛛产生时它是如何工作的? 是否有可能只让第一个请求生成器产生新的蜘蛛,并确保从那时起只有蜘蛛处理未来的请求?
我假设我必须禁用多个并发请求。否则,一个蜘蛛会在相同的会话cookie下进行多次search,而将来的请求只会涉及到最近的search?
我很困惑,任何澄清将大受欢迎!
编辑:
我刚刚想到的另一个选项是完全手动pipe理会话cookie,并将其从一个请求传递给另一个。
我想这将意味着禁用cookies ..然后从search响应抓取会话cookie,并将其传递给每个后续请求。
这是你在这种情况下应该做的吗?
三年后,我想这正是你所期待的: 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)
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)
我认为最简单的方法是使用search查询作为蜘蛛参数(将在构造函数中接收)运行同一个蜘蛛的多个实例,以重用Scrapy的cookiespipe理function。 所以你将有多个蜘蛛实例,每一个抓取一个特定的search查询及其结果。 但是你需要自己运行蜘蛛:
scrapy crawl myspider -a search_query=something
或者您可以使用Scrapyd通过JSON API运行所有的蜘蛛。
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 )