将 cookie 加载到 Python 请求会话时出错
- 2025-04-15 09:20:00
- admin 原创
- 35
问题描述:
我正在尝试从 selenium 导出的 cookie 将 cookie 加载到 Python 中的请求会话中,但是当我这样做时,它返回以下错误:“'list' 对象没有属性 'extract_cookies'”
def load_cookies(filename):
with open(filename, 'rb') as f:
return pickle.load(f)
initial_state= requests.Session()
initial_state.cookies=load_cookies(time_cookie_file)
search_requests = initial_state.get(search_url)
我看到的所有方法都应该可以正常工作,但是我的 Cookie 是一个字典列表,我理解所有 Cookie 都是字典列表,这也是我假设 Selenium 可以使用的原因。然而,由于某种原因,它无法与请求配合使用,任何这方面的帮助都非常有用,感觉我忽略了一些显而易见的东西!
已使用以下方法从 Selenium 转储 Cookies:
with open("Filepath.pkl", 'wb') as f:
pickle.dump(driver.get_cookies(), f)
以下是 Cookie 的一个示例(略有混淆):
[{'domain': '.website.com',
'expiry': 1640787949,
'httpOnly': False,
'name': '_ga',
'path': '/',
'secure': False,
'value': 'GA1.2.1111111111.1111111111'},
{'domain': 'website.com',
'expiry': 1585488346,
'httpOnly': False,
'name': '__pnahc',
'path': '/',
'secure': False,
'value': '0'}]
我现在已经设法按照下面的答案加载 cookie,但是由于它们不记得任何东西,所以 cookie 似乎没有被正确加载,但是如果我在通过 Selenium 浏览时加载 cookie,它们就可以正常工作。
解决方案 1:
曲奇饼
HTTPCookie
请求标头包含HTTP cookie
服务器先前随Set-Cookie
标头发送的已存储信息。HTTP Cookie是服务器发送给用户 Web 浏览器的一小段数据。浏览器可能会存储这些Cookie,并在下次向同一服务器发出请求时将其发送回。通常,曲奇饼判断两个请求是否来自同一个浏览器,保持用户登录状态。
使用 Selenium 进行演示
为了演示使用Selenium 的cookie 用法,我们使用以下方式存储 cookie泡菜一旦用户登录到网站http://demo.guru99.com/test/cookie/selenium_aut.php。在下一步中,我们打开同一个网站,添加 cookie,并能够以登录用户的身份登陆。
存储 cookie 的代码块:
from selenium import webdriver
import pickle
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:UtilityBrowserDriverschromedriver.exe')
driver.get('http://demo.guru99.com/test/cookie/selenium_aut.php')
driver.find_element_by_name("username").send_keys("abc123")
driver.find_element_by_name("password").send_keys("123xyz")
driver.find_element_by_name("submit").click()
pickle.dump( driver.get_cookies() , open("cookies.pkl","wb"))
使用存储的 cookies 进行自动身份验证的代码块:
from selenium import webdriver
import pickle
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:UtilityBrowserDriverschromedriver.exe')
driver.get('http://demo.guru99.com/test/cookie/selenium_aut.php')
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
driver.add_cookie(cookie)
driver.get('http://demo.guru99.com/test/cookie/selenium_cookie.php')
使用请求进行演示
为了演示使用 cookies会议和请求我们访问了网站https://www.google.com,添加了一个新的 cookie 词典:
{'name':'my_own_cookie','value': 'debanjan' ,'domain':'.stackoverflow.com'}
接下来,我们使用相同的请求会话发送另一个请求,该请求成功如下:
代码块:
import requests
s1 = requests.session()
s1.get('https://www.google.com')
print("Original Cookies")
print(s1.cookies)
print("==========")
cookie = {'name':'my_own_cookie','value': 'debanjan' ,'domain':'.stackoverflow.com'}
s1.cookies.update(cookie)
print("After new Cookie added")
print(s1.cookies)
控制台输出:
Original Cookies
<RequestsCookieJar[<Cookie 1P_JAR=2020-01-21-14 for .google.com/>, <Cookie NID=196=NvZMMRzKeV6VI1xEqjgbzJ4r_3WCeWWjitKhllxwXUwQcXZHIMRNz_BPo6ujQduYCJMOJgChTQmXSs6yKX7lxcfusbrBMVBN_qLxLIEah5iSBlkdBxotbwfaFHMd-z5E540x02-YZtCm-rAIx-MRCJeFGK2E_EKdZaxTw-StRYg for .google.com/>]>
==========
After new Cookie added
<RequestsCookieJar[<Cookie domain=.stackoverflow.com for />, <Cookie name=my_own_cookie for />, <Cookie value=debanjan for />, <Cookie 1P_JAR=2020-01-21-14 for .google.com/>, <Cookie NID=196=NvZMMRzKeV6VI1xEqjgbzJ4r_3WCeWWjitKhllxwXUwQcXZHIMRNz_BPo6ujQduYCJMOJgChTQmXSs6yKX7lxcfusbrBMVBN_qLxLIEah5iSBlkdBxotbwfaFHMd-z5E540x02-YZtCm-rAIx-MRCJeFGK2E_EKdZaxTw-StRYg for .google.com/>]>
结论
显然,新添加的 cookie 字典{'name':'my_own_cookie','value': 'debanjan' ,'domain':'.stackoverflow.com'}
在第二个请求中得到了充分利用。
将 Selenium Cookies 传递给 Python 请求
现在,如果您的用例是将 Selenium Cookies 传递给 Python 请求,则可以使用以下解决方案:
from selenium import webdriver
import pickle
import requests
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:UtilityBrowserDriverschromedriver.exe')
driver.get('http://demo.guru99.com/test/cookie/selenium_aut.php')
driver.find_element_by_name("username").send_keys("abc123")
driver.find_element_by_name("password").send_keys("123xyz")
driver.find_element_by_name("submit").click()
# Storing cookies through Selenium
pickle.dump( driver.get_cookies() , open("cookies.pkl","wb"))
driver.quit()
# Passing cookies to Session
session = requests.session() # or an existing session
with open('cookies.pkl', 'rb') as f:
session.cookies.update(pickle.load(f))
search_requests = session.get('https://www.google.com/')
print(session.cookies)
解决方案 2:
RequestsCookieJar
由于您用不具有这些属性的 session.cookies ()替换了list
它,因此它将不起作用。
您可以使用以下方式逐个导入这些 cookie:
for c in your_cookies_list:
initial_state.cookies.set(name=c['name'], value=c['value'])
我尝试加载整个 cookie,但似乎请求无法识别这些 cookie 并返回:
TypeError: create_cookie() got unexpected keyword arguments: ['expiry', 'httpOnly']
请求接受expires
并HttpOnly
嵌套在rest
更新:
我们还可以更改和的字典键expiry
,以便httpOnly
请求正确加载它们而不是抛出异常,通过使用dict.pop()
它从字典中删除一个项目key
并返回value
已删除的,key
因此在我们添加一个key
带有已删除项目的新项目后value
,解包并将它们传递为kwargs
:
for c in your_cookies_list:
c['expires'] = c.pop('expiry')
c['rest'] = {'HttpOnly': c.pop('httpOnly')}
initial_state.cookies.set(**c)
解决方案 3:
您可以获取 Cookie 并仅使用名称/值。您还需要标头。您可以从开发工具或使用代理获取它们。
基本示例:
driver.get('https://website.com/')
# ... login or do anything
cookies = {}
for cookie in driver.get_cookies():
cookies[cookie['name']] = cookie['value']
# Write to a file if need or do something
# import json
# with open("cookies.txt", 'w') as f:
# f.write(json.dumps(cookies))
和用法:
# Read cookies from file as Dict
# with open('cookies.txt') as reader:
# cookies = json.loads(reader.read())
# use cookies
response = requests.get('https://website.com/', headers=headers, cookies=cookies)
Stackoverflow 标头示例,有些标头是必需的,有些则不是。您可以在这里和这里找到相关信息。您可以使用开发工具的“网络”选项卡获取请求标头:
headers = {
'authority': 'stackoverflow.com',
'pragma': 'no-cache',
'cache-control': 'no-cache',
'dnt': '1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',
'sec-fetch-user': '?1',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'navigate',
'referer': 'https://stackoverflow.com/questions/tagged?sort=Newest&tagMode=Watched&uqlId=8338',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'ru,en-US;q=0.9,en;q=0.8,tr;q=0.7',
}
解决方案 4:
您可以创建会话。会话类用于处理请求之间的 Cookie。
s = requests.Session()
login_resp = s.post('https://example.com/login', login_data)
self.cookies = self.login_resp.cookies
cookiedictreceived = {}
cookiedictreceived=requests.utils.dict_from_cookiejar(self.login_resp.cookies)
解决方案 5:
因此,Requests 希望 Cookie 中的所有“值”都是字符串。“键”可能也是如此。Cookies 也不希望函数load_cookies
返回一个列表。可以使用 request.utils 创建 Cookie cookies = requests.utils.cookiejar_from_dict(...
。
假设我使用 selenium 访问“ https://stackoverflow.com/ ”并像您一样保存 cookie。
from selenium import webdriver
import pickle
import requests
#Go to the website
driver = webdriver.Chrome(executable_path=r'C:Path\\To\\Your\\chromedriver.exe')
driver.get('https://stackoverflow.com/')
#Save the cookies in a file
with open("C:PathToYourFilepath.pkl", 'wb') as f:
pickle.dump(driver.get_cookies(), f)
driver.quit()
#you function to get the cookies from the file.
def load_cookies(filename):
with open(filename, 'rb') as f:
return pickle.load(f)
saved_cookies_list = load_cookies("C:PathToYourFilepath.pkl")
#Set request session
initial_state = requests.Session()
#Function to fix cookie values and add cookies to request_session
def fix_cookies_and_load_to_requests(cookie_list, request_session):
for index in range(len(cookie_list)):
for item in cookie_list[index]:
if type(cookie_list[index][item]) != str:
print("Fix cookie value: ", cookie_list[index][item])
cookie_list[index][item] = str(cookie_list[index][item])
cookies = requests.utils.cookiejar_from_dict(cookie_list[index])
request_session.cookies.update(cookies)
return request_session
initial_state_with_cookies = fix_cookies_and_load_to_requests(cookie_list=saved_cookies_list, request_session=initial_state)
search_requests = initial_state_with_cookies.get("https://stackoverflow.com/")
print("search_requests:", search_requests)
解决方案 6:
请求也接受http.cookiejar.CookieJar
对象:
https://docs.python.org/3.8/library/http.cookiejar.html#cookiejar-and-filecookiejar-objects
扫码咨询,免费领取项目管理大礼包!