Selenium-wire与seleniumrequests兼容问题解决求助
问题场景
原本代码如下:
from seleniumwire import webdriver driver = webdriver.Firefox(options=self.web_options) driver.get(user_site) ret = list(driver.requests) verify = extract_verify(ret) driver.requests.clear() driver.get(self.root + '?verify={}'.format(urllib.parse.quote(verify))) resp = self.driver.page_source
由于API变更,需要将最后一步的driver.get替换为driver.request('POST', root, data={"verify": urllib.parse.quote(verify)}),但该方法来自seleniumrequests——它依赖标准Selenium WebDriver,换成标准Driver后,Selenium-wire核心的driver.requests属性会直接失效,因为标准Selenium没有该功能。
环境版本:
selenium=4.6.0 selenium-wire=5.1.0 selenium-requests=2.0.1 Python=3.8.10
解决方案
方案1:用Selenium-wire原生能力发送POST请求
Selenium-wire本身支持直接构造HTTP请求,无需依赖seleniumrequests。通过driver.backend.send_request方法即可实现POST请求,同时保留driver.requests的功能。
示例代码:
from seleniumwire import webdriver import urllib.parse driver = webdriver.Firefox(options=self.web_options) driver.get(user_site) ret = list(driver.requests) verify = extract_verify(ret) driver.requests.clear() # 构造POST请求参数 url = self.root headers = {'Content-Type': 'application/x-www-form-urlencoded'} # 对表单数据进行URL编码并转成字节流 data = urllib.parse.urlencode({"verify": urllib.parse.quote(verify)}).encode('utf-8') # 用Selenium-wire发送POST请求 response = driver.backend.send_request( method='POST', url=url, headers=headers, body=data ) # 获取响应内容(根据实际编码调整decode参数) resp = response.body.decode('utf-8')
如果需要让浏览器加载该POST请求的页面,可以在发送请求后调用driver.get(url),或手动构造页面表单提交;若仅需获取响应数据,直接使用response.body即可。
方案2:扩展Selenium-wire Driver类,兼容request语法
如果习惯driver.request的调用方式,可以自行扩展Selenium-wire的Driver类,添加对应方法:
from seleniumwire import webdriver import urllib.parse class ExtendedFirefoxDriver(webdriver.Firefox): def request(self, method, url, data=None, headers=None): headers = headers or {} if data and method.upper() == 'POST': # 默认添加表单编码头,可根据需求调整 headers.setdefault('Content-Type', 'application/x-www-form-urlencoded') data = urllib.parse.urlencode(data).encode('utf-8') return self.backend.send_request(method=method, url=url, headers=headers, body=data) # 使用扩展后的Driver driver = ExtendedFirefoxDriver(options=self.web_options) driver.get(user_site) ret = list(driver.requests) verify = extract_verify(ret) driver.requests.clear() # 用熟悉的request语法发送POST response = driver.request('POST', self.root, data={"verify": urllib.parse.quote(verify)}) resp = response.body.decode('utf-8')
方案3:同时使用两个Driver(不推荐)
如果一定要用seleniumrequests的request方法,可以同时初始化两个Driver,但会打开独立的浏览器实例,资源消耗大且会话不共享,需手动同步Cookie才能保证验证通过,仅作参考:
from seleniumwire import webdriver as wire_webdriver from seleniumrequests import Firefox as RequestsFirefox # 用Selenium-wire获取verify参数 wire_driver = wire_webdriver.Firefox(options=self.web_options) wire_driver.get(user_site) ret = list(wire_driver.requests) verify = extract_verify(ret) # 复制Cookie到新Driver cookies = wire_driver.get_cookies() wire_driver.quit() # 用seleniumrequests发送POST请求 requests_driver = RequestsFirefox(options=self.web_options) for cookie in cookies: requests_driver.add_cookie(cookie) response = requests_driver.request('POST', self.root, data={"verify": urllib.parse.quote(verify)}) resp = response.text requests_driver.quit()
内容的提问来源于stack exchange,提问作者Joshua Snider
相关产品推荐
相关产品推荐

