Scrapy中如何将Session传递至Requests?附相关代码
实现Scrapy Session向Requests的传递方案
嘿,我来帮你搞定Scrapy里把Session传递给Requests的问题!核心思路是先让Scrapy完成登录流程,拿到有效的会话Cookie,再把这些Cookie同步给Requests的Session对象,这样Requests就能用同一个会话访问需要登录权限的页面了。结合你现有的代码,我整理了完整的实现方案:
关键步骤说明
- 完善Scrapy登录流程:处理验证码、提交登录表单,确保Scrapy成功获取登录后的会话Cookie。
- Cookie格式转换:把Scrapy返回的Cookie转换成Requests能识别的格式。
- 同步Session到Requests:用Requests的
Session对象加载Scrapy的Cookie,实现会话共享。
完整代码实现
from scrapy.http import Request, FormRequest from scrapy.spiders import CrawlSpider import requests from retrieve_image import retrieve_image # 假设这个函数负责验证码识别 class LoginSpider(CrawlSpider): name = 'loginspider' login_page = 'http://145.100.108.148/login5/login.php' start_urls = ['http://145.100.108.148/login5/index.php'] username = 'test@hotmail.com' password = 'test' def start_requests(self): print("\nstart_request is here\n") # 先请求登录页面,获取初始Cookie和验证码资源 yield Request( url=self.login_page, callback=self.login, dont_filter=True ) def login(self, response): # 1. 提取验证码图片URL并识别验证码(根据实际页面调整XPath) captcha_img_xpath = '//img[contains(@src, "captcha")]/@src' captcha_img_url = response.xpath(captcha_img_xpath).get() # 拼接完整的验证码URL(避免相对路径问题) full_captcha_url = response.urljoin(captcha_img_url) # 调用你的retrieve_image函数获取识别后的验证码 captcha_code = retrieve_image(full_captcha_url) # 2. 构造登录表单数据(注意补充页面上的隐藏字段,比如token) form_data = { 'username': self.username, 'password': self.password, 'captcha': captcha_code, 'token': response.xpath('//input[@name="token"]/@value').get() or '' } # 3. 提交登录请求,Scrapy会自动维护Cookie会话 yield FormRequest.from_response( response, formdata=form_data, callback=self.post_login, dont_filter=True ) def post_login(self, response): # 验证登录是否成功(根据实际页面调整判断逻辑) if "欢迎登录" in response.text or response.url == self.start_urls[0]: print("✅ 登录成功,开始同步Session到Requests") # --- 核心:同步Scrapy的Session到Requests --- # 1. 转换Scrapy Cookie格式为Requests可用的字典 scrapy_cookies = response.cookies requests_cookies = {} if isinstance(scrapy_cookies, list): # 当Scrapy返回的是Cookie列表时,转成键值对字典 for cookie in scrapy_cookies: requests_cookies[cookie['name']] = cookie['value'] else: requests_cookies = scrapy_cookies # 2. 创建Requests Session并加载Cookie req_session = requests.Session() req_session.cookies.update(requests_cookies) # 3. 用Requests Session访问需要登录的页面 protected_page_url = 'http://145.100.108.148/login5/protected_content.php' req_response = req_session.get(protected_page_url) # 处理Requests返回的结果(示例:打印状态码和部分内容) print(f"Requests请求状态码:{req_response.status_code}") print(f"页面内容片段:{req_response.text[:500]}...") # 继续Scrapy的正常爬取流程 yield from self.parse_start_url(response) else: print("❌ 登录失败,重试中...") # 登录失败时重试登录请求 yield Request(url=self.login_page, callback=self.login, dont_filter=True) def parse_start_url(self, response): # 这里编写Scrapy爬取页面的业务逻辑,比如提取数据、跟进链接等 pass
重点细节说明
FormRequest.from_response的优势:自动从登录页面提取表单的action和隐藏字段(比如token),比手动构造表单更稳定,适配页面变化。- Cookie格式兼容:Scrapy的
response.cookies可能返回列表或字典,需要做格式转换,确保Requests能正确加载。 - 会话持久化:使用
requests.Session()会自动维护Cookie,后续用这个Session对象发起的请求都会带上登录后的Cookie,和Scrapy的会话完全同步。 - 登录验证逻辑:一定要根据目标网站的实际情况调整登录成功的判断条件(比如页面关键词、跳转URL),避免无效的会话同步。
内容的提问来源于stack exchange,提问作者Kevin C
相关产品推荐
相关产品推荐

