鱼C论坛

 找回密码
 立即注册
查看: 1413|回复: 7

[已解决]求助cookies操作

[复制链接]
发表于 2020-7-29 20:52:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 johnnyb 于 2020-7-29 20:57 编辑

问题描述:
我用selenium模拟登陆douban.登陆成功. 用webdriver.get_cookies()方法 取得登陆成功的cookies为
[{'domain': 'accounts.douban.com', 'httpOnly': False, 'name': 'login_start_time', 'path': '/', 'secure': False, 'value': '1596025621029'}, {'domain': 'accounts.douban.com', 'httpOnly': False, 'name': 'apiKey', 'path': '/', 'secure': False, 'value': ''}, {'domain': '.douban.com', 'expiry': 1627561620, 'httpOnly': False, 'name': 'bid', 'path': '/', 'secure': False, 'value': '-dDW2CjywbM'}]
我把他直接放到headers中. requests.get(url) 可以取得登陆成功页面. 但是我的目标是把这个cookies传递给requests.Session对象s用.  让它一直维持登陆状态. 获取需要登陆才能取到的个人主页.  
当我用.
for cookie in cookies:
    s.cookies.set(cookie['name'], cookie['value'])
发现. selenium的get_cookies()方法. 传回来的是一个列表. 列表中有3个字典.  这样for他就循环3次. 就完事了. 所以就过去3个值
('apiKey', '')
('bid', '-dDW2CjywbM')
('login_start_time', '1596025621029')
我如何能让所有的 name,value 全部过去呢?
尝试了把3个字典合成1个.. 但是里面存在多个重复name  会被顶替成最后一个. 很无解..
或者有没有更好的转换方案? 或者模块?
最佳答案
2020-7-30 10:01:49
纠正一下我在2楼的说法,我仔细看了一些requests的cookie,和selenium虽然对象类型不同,但是内容是差不多的。
>>> s = requests.session()
>>> s.cookies
<RequestsCookieJar[]>
>>> s.cookies.set('BID','123')
Cookie(version=0, name='BID', value='123', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)
>>> 
可以看出也有domain,path等参数,所以从selenium获得的cookie字典,需要看看是否与默认值相同,不同就需要传入:
s.cookies.set('BID', '123', domain='www.aidu.com', expires='')



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-29 22:45:16 | 显示全部楼层
本帖最后由 suchocolate 于 2020-7-30 09:51 编辑

你的代码key是'name'和'value'的已经正确添加在cookie里了,是没问题的。
selenium的cookie和urllib的不同,它的cookie由多个key相同的字典组成。 # 说法有误请忽略
每个字典的key不仅仅有name和value,还有有expire和domain等等。
存储建议使用pickle:
driver.get(url)
time.sleep(10)
pickle.dump(driver.get_cookies(), open("cookies.pkl", "wb"))
读取时时遍历列表即可:
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
    driver.add_cookie(cookie)
driver.get(url)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-30 08:07:46 | 显示全部楼层
suchocolate 发表于 2020-7-29 22:45
你的代码key是'name'和'value'的已经正确添加在cookie里了,是没问题的。
selenium的cookie和urllib的不同 ...

意思明白了. 但是我的核心是. 取到的cookies传递给 Session对象用.. 比如s.cookie.set()   我要怎么保证传进去是可用呢?  2天了. 还在研究这个问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-30 09:08:58 | 显示全部楼层
johnnyb 发表于 2020-7-30 08:07
意思明白了. 但是我的核心是. 取到的cookies传递给 Session对象用.. 比如s.cookie.set()   我要怎么保证 ...

cookie能不能用这个不敢保证,但你的cookie代码是没问题的。
一次请求,header的字段有很多,cookie是其中之一,有时cookie正确,其他字段没设对也可请求不成功。
另外自己构建cookie,尽量以【浏览器f12】-【网络】中实际的cookie为模板,即使是用selenium获取的,也print的参考一下模板。这样headers正确的情况下测试才比较稳妥。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-30 10:01:49 | 显示全部楼层    本楼为最佳答案   
纠正一下我在2楼的说法,我仔细看了一些requests的cookie,和selenium虽然对象类型不同,但是内容是差不多的。
>>> s = requests.session()
>>> s.cookies
<RequestsCookieJar[]>
>>> s.cookies.set('BID','123')
Cookie(version=0, name='BID', value='123', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)
>>> 
可以看出也有domain,path等参数,所以从selenium获得的cookie字典,需要看看是否与默认值相同,不同就需要传入:
s.cookies.set('BID', '123', domain='www.aidu.com', expires='')



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-30 15:12:39 | 显示全部楼层
本帖最后由 johnnyb 于 2020-7-30 15:14 编辑
suchocolate 发表于 2020-7-30 10:01
纠正一下我在2楼的说法,我仔细看了一些requests的cookie,和selenium虽然对象类型不同,但是内容是差不多 ...


以下是我的全部代码.
我的目的是模拟登陆. 获取cookie然后给Session.get用

截图的cookies是我用抓包软件抓出来的. 完全可以验证登陆状态. 问题还是出在转换上.
QQ图片20200730151023.png
from selenium import webdriver
import requests
import pickle

# 创建webdriver对象wd  实例化参数是浏览器驱动地址(r'd:\chromedriver.exe')
wd = webdriver.Chrome('chromedriver.exe')


def get_cookies():
    # 隐式等待10秒
    wd.implicitly_wait(5)
    # 在运行的时候不弹出浏览器窗口
    # 
    # 使用对象wd控制浏览器 打开网址
    print('opened login page....')
    wd.get('https://www.douban.com')

    wd.switch_to.frame(wd.find_element_by_tag_name("iframe"))
    print('进入iframe')
    wd.find_element_by_class_name('account-tab-account').click()
    print('输入模式')
    wd.find_element_by_class_name('account-form-input').send_keys('账号')
    print('输入账号完毕')
    wd.find_element_by_id('password').send_keys('密码')
    print('输入密码完毕')
    wd.find_element_by_xpath('/html/body/div[1]/div[2]/div[1]/div[5]/a').click()
    print('点击登录完毕')
    return wd.get_cookies()


# 创建一个Session对象
s = requests.Session()
# 取得driver里面的cookies
cookies = get_cookies()
print('get方法获取到的cookies',cookies)
# 遍历cookies里面各项,同时设置给Session对象s的cookie属性
for cookie in cookies:
    s.cookies.set(cookie['name'], cookie['value'])
    print('遍历的:', cookie['name'], cookie['value'])

# driver任务完成 关闭

cookie_dict = requests.utils.dict_from_cookiejar(s.cookies)
for i in cookie_dict.items():
    print('展开cookies的内容:',i)

headers = {
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',
    '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-site',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-User': '?1',
    'Sec-Fetch-Dest': 'document',
    'Referer': 'https://www.douban.com/',
    'Accept-Language': 'zh-CN,zh;q=0.9',
}
s.headers = headers
# 使用Session对象s访问网页(内部携带了登录cookies)
res = s.get(url='https://www.douban.com/')
print('s使用的cookies:', res.cookies)
cookie_dict = requests.utils.dict_from_cookiejar(res.cookies)
for i in cookie_dict.items():
    print('展开cookies的内容:', i)
print('s使用的headers:', res.headers)
res.encoding = 'utf-8'
print(res.text[:500])

# 写入文件
with open('html.html', 'w+', encoding='utf-8') as f:
    f.write(res.text)

print('end')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-30 15:19:11 | 显示全部楼层
suchocolate 发表于 2020-7-30 10:01
纠正一下我在2楼的说法,我仔细看了一些requests的cookie,和selenium虽然对象类型不同,但是内容是差不多 ...

那这个get_cookies() 方法还有啥用? 取不全. 还得自己手动去挑. 哪个不一样. 在传进去. 我的理解不是应该. 把当前登陆状态的全部cookie获取到. 保存成一个requestscookie包. 等待处理. 然后创建一个session对象s  s.cookies.set(get_cookies()得到的包) 这样就传递给了s对象让它携带. 现在问题是传过去了. 但少了一大堆. 传过去的没法用.   归根原因我猜是不是 get_cookies()方法取不全?  我百度还没发现有同样问题. 很恼火. 无人解答.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-30 17:40:01 | 显示全部楼层
还是没人知道吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-19 17:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表