模拟登陆中 302 重定向和 cookies 的一些困惑 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Huayx9
V2EX    Python

模拟登陆中 302 重定向和 cookies 的一些困惑

  •  
  •   Huayx9 2016-07-31 21:32:29 +08:00 11939 次点击
    这是一个创建于 3360 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想写一个查询话费和流量的爬虫,关键是实现模拟登陆的这个部分。 在登陆过程中,点击登陆之后,登陆表单会 post 到一个地址(这一步浏览器不显示),然后会 302 跳转到登陆成功的页面。

    我现在想得到登陆成功的 cookies ,不知道该怎么提取,requests.session()并没有得到登陆成功的 cookies. 得不到登陆成功的 cookies ,代码就不能爬取登陆之后的查询信息。

    post 表单的地址 http://i.imgur.com/2OS1Zi1.png

    登陆过程中的重定向 1 http://i.imgur.com/cI6wBCV.png

    登陆过程中的重定向 2 http://i.imgur.com/3c19Y38.png

    再跳转登陆成功的页面 http://i.imgur.com/uAZsUdI.png

    我有三个问题

    • 1.post 表单这个过程,也就是图一中的 cookies 是怎么生成的,因为我发现 post 表单过程中的 cookies 比在进入登陆页面中的多。
    • 2.登陆过程中有两次 302 ,最后再 200 到登陆成功页面,我该怎么得到 200 的这个 cookie 。
    • 3.request.sission()是会自动管理登陆过程中的 cookies 吗,用不用单独提取登陆之后的 cookies 。

    代码如下,谢谢大家

    #coding=utf-8 import requests import re # request headers Head ={'Accept-Language': 'zh-CN,zh;q=0.8', 'Accept-Encoding': 'gzip, deflate, sdch', 'Host': 'ah.189.cn', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Upgrade-Insecure-Requests': '1', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36'} # Chrome 打开登陆页面提取的 cookies Cook = {'Hm_lvt_333c7327dca1d300fd7235c159b7da04': '1469964315', 'lid': '', '_gscu_1758414200': '69964315ee6pb621', 'v_lasttime': '1469964315502', '_gscs_1758414200': '69964315tq317521|pv:1', 'Hm_lvt_c7c8eed8670bd7fffefc8b202fe0904d': '1469964315', 'v_url_code': 'http%3A//ah.189.cn/sso/login%3FreturnUrl%3D%252Fbiz%252Fservice%252Faccount%252Finit.action', 'JSESSIONID_SSO': 'Jh1GXdgDZJqdZqpLvRQvZzdlvT7y6BxHhCny9MhbKh1Kw1hSLNt2Q1c6231LrHQWrpDL4m115pz0YTLJN7jx2fmpTfPBx1JwlYvvkLBRySmy18tnW1c2Q7qPvQqK9kJP!463350529', 'v_trackId': '1BD7B46E79FE234CE9C67E49D95245FB', 'Hm_lpvt_333c7327dca1d300fd7235c159b7da04': '1469964315', '_gscbrs_1758414200': '1', 'Hm_lpvt_c7c8eed8670bd7fffefc8b202fe0904d': '1469964315', 'JSESSIONID_PERSONWEB': 'p2MyXdgGd8f5phjTTv2CJMr6J8QYhSyLX0kkZHlSwpppjhYGf3qm!1538637772'} #登陆提交的表单 postdata = {'remPwd': '0', 'loginName': '', 'returnUrl': '/biz/service/account/init.action', 'validCode': '', 'loginType': '4', 'sysId': '1003', 'passType': '0', 'csrftoken': '', 'accountType': '9', 'ssoAuth': '0', 'passWord': '', 'latnId': '551'} #登陆页面 baseurl = 'http://ah.189.cn/sso/login?returnUrl=%2Fbiz%2Fservice%2Faccount%2Finit.action' #登陆表单 post 的地址 posturl = 'http://ah.189.cn/sso/LoginServlet' sess = requests.session() sess.headers.update(Head) def getP(url,cookies): """带 session()requests 的 get 方法""" pre = sess.get(url,cookies = cookies) return pre def getVerifyURL(url): """从主页提取验证码地址""" reg = r'/sso/VImage.servlet\?random=0\.[0-9]+' #正则表达式匹配验证码图片链接 img = re.search(reg,getP(url,cookies = Cook).content).group() imge = "http://ah.189.cn" + img #得到验证码图片链接 return imge def getCodePic(): """下载验证码图片""" verifyURL = getVerifyURL(baseurl) codePic = getP(verifyURL,cookies = Cook).content print verifyURL with open('x.jpeg','wb') as jpg: jpg.write(codePic) def postData(): """post 表单信息更新""" username = raw_input("输入手机号") code = raw_input("输入密码") passwd = raw_input("输入验证码") postdata['loginName'] = str(username) postdata['validCode'] = str(code) postdata['passWord'] = str(passwd) getCodePic() postData() postover = sess.post(posturl,postdata) #post 表单 cookLogin = postover.cookies #查看 post 表单之后的 cookies print cookLogin con = sess.get('http://ah.189.cn/biz/service/account/init.action') #登陆成功的页面 print "登陆成功",con 
    29 条回复    2017-12-05 16:10:44 +08:00
    Huayx9
        1
    Huayx9  
    OP
       2016-07-31 21:33:05 +08:00
    图片显示不成功好像。。。。
    iluhcm
        2
    iluhcm  
       2016-07-31 22:24:41 +08:00   1
    遇到类似问题,表示关注。。
    lxy
        3
    lxy  
       2016-07-31 22:56:45 +08:00   1
    懒得具体分析了,简单说下经验。
    1 、 cookies 在任何时候都能够被设置。如果是我来做这个,我会先获取( get )登录的页面(大多数时候会在这里设置 cookies 和 token ),模拟人工操作,而不是一开始就提交( post )数据。顺便注意 JS 也可以设置 cookies 。
    2 、 requests 会自动处理 cookies 和 302 。
    3 、同上。不过好像 requests 有个坑,不知道是不是因为自己项目中对 requests 封装过度导致的,在访问多个不同的子域名的时候,貌似会混淆*同名的*cookies ,需要手动指定 cookies 。可以注意一下。
    scnace
        4
    scnace  
       2016-07-31 22:59:18 +08:00 via Android   1
    我之前爬学校也遇到过 302 Object moved here 的问题 要 header 里面设置下 Referer 你可以试试(
    digihero
        5
    digihero  
       2016-07-31 23:01:22 +08:00   1
    python 不了解。不过用 PHP 来模拟的时候,碰到 302 ,是可以设置 CURL 的参数来实现跟踪跳转的。到跳那儿就跟到那儿。 python 一样可以,看看参数。
    aeshfawre
        6
    aeshfawre  
       2016-07-31 23:04:43 +08:00   1
    你这三个问题等于一个问题,就是 cookie. 用了 Session(),你就不需要管任何 cookie 的问题了.

    问个问题,你这是做出来自用的么,还是拿出去卖的,python 代码写出来的会被倒卖吧.静态编译的才适合出售.
    Huayx9
        7
    Huayx9  
    OP
       2016-07-31 23:07:58 +08:00
    @aeshfawre 我是做出来自用的。。还是学生,写的这么蹩脚
    Huayx9
        8
    Huayx9  
    OP
       2016-07-31 23:12:39 +08:00
    @lxy 我是先 get 登陆页面, get 验证码,然后再 post 表单,用了 session()不是会自动管理 cookies 么, post 之后的 cookies 不是自动更新么。难道是 post 之后再 get 混淆类 cookies 了?在 post 之后获取 cookies 参数,再指定给( get 登陆成功页面)这个操作?
    Huayx9
        9
    Huayx9  
    OP
       2016-07-31 23:14:04 +08:00
    @scnace 是每一步都要设置 referer 吗,那岂不是每一个 requests 的 headers 都不同了?
    Huayx9
        10
    Huayx9  
    OP
       2016-07-31 23:14:48 +08:00
    @digihero 谢谢啦,那么现在的主要问题是,怎么得到登陆成功的 cookies 。。
    aeshfawre
        11
    aeshfawre  
       2016-07-31 23:17:18 +08:00   1
    @Huayx9 学生怎么会有这需求,以前是养卡或者开移动营业厅的人买我软件,我人生最大的遗憾就是没去了解自己处于这个食物链的哪一层.

    现在都还不明白这软件具体有啥用途,你能告诉我不?
    Huayx9
        12
    Huayx9  
    OP
       2016-07-31 23:29:01 +08:00
    @aeshfawre 我哥哥让我做一个软件,帮他批量查询他的电信号的余额和消费情况,他开公司的。

    然后,我就想到用爬虫来做,难不成我还能是盗卡的么,就我这破水平。。
    Huayx9
        13
    Huayx9  
    OP
       2016-07-31 23:35:14 +08:00
    @aeshfawre 还有,我做的过程中,巩固 python 水平,掌握基础的写爬虫技能,熟悉 http 协议,如果写好了,我哥给我一点好处那更好不过了。。

    我现在一直就是模拟登陆不成功, post 表单之后就抓瞎了。。。 cookies 总是不正常,也就 get 不到登陆成功的页面的信息。

    谢谢你一直的耐心解答。。 cookies 这一关我过不了啊。。
    scnace
        14
    scnace  
       2016-08-01 07:36:34 +08:00 via Android
    @Huayx9 额 碰到 302 了再 referer 啊 network 里应该有写吧 我在 blog 里写过的 你可以参考下 差不多场景 http://scnace.cc/wordpress/archives/1117
    jackyspy
        15
    jackyspy  
       2016-08-01 08:12:54 +08:00
    @Huayx9 你这个需求, selenium2 也是一个不错的选择
    Huayx9
        16
    Huayx9  
    OP
       2016-08-01 08:23:14 +08:00 via iPhone
    @jackyspy 验证码我准备假如一个 OCR 模块, selenium2 能够拓展么?
    Huayx9
        17
    Huayx9  
    OP
       2016-08-01 08:24:15 +08:00 via iPhone
    @scnace 咿呀,加个什么其他好友吧,有机会交流学习~
    scnace
        18
    scnace  
       2016-08-01 08:31:26 +08:00 via Android
    @Huayx9 wechat:c2NiaXp1Cg==
    Huayx9
        19
    Huayx9  
    OP
       2016-08-01 08:37:32 +08:00 via iPhone
    @scnace 有没有等号。。
    scnace
        20
    scnace  
       2016-08-01 08:54:16 +08:00 via Android
    @Huayx9 我稍微 base64 加了下密 你去 decode 一下 就行了
    Huayx9
        21
    Huayx9  
    OP
       2016-08-01 09:06:38 +08:00 via iPhone
    @scnace 等号。。有的没的
    lslqtz
        22
    lslqtz  
       2016-08-01 09:47:28 +08:00
    @scnace 话说 wechat 为啥要 base64 不是只有邮件防爬虫 base64 么。。
    jackyspy
        23
    jackyspy  
       2016-08-01 09:55:06 +08:00
    @Huayx9 selenium2 只是操控浏览器
    Huayx9
        24
    Huayx9  
    OP
       2016-08-01 10:43:33 +08:00 via iPhone   1
    @lslqtz 太直接了,也容易暴露
    HFcbyqP0iVO5KM05
        25
    HFcbyqP0iVO5KM05  
       2016-08-01 18:53:14 +08:00 via Android
    我只是提醒一下,题主你试过 allow_redirects=True 了吗?
    HFcbyqP0iVO5KM05
        26
    HFcbyqP0iVO5KM05  
       2016-08-01 18:58:02 +08:00 via Android
    @lxy 你说的 cookie 同名应该是同样的 name=value pair 吧。 严格来说 cookie 更像一个 OrderedDict , 里面的 name=value 相同,但其它的什么 path, hosts, expire 信息不同的话算两个 cookie 。
    sparkssssssss
        27
    sparkssssssss  
       2016-08-01 23:11:36 +08:00 via iPhone
    mark
    lxy
        28
    lxy  
       2016-08-04 10:51:41 +08:00
    @Huayx9 抽空检查了一下项目代码,是我自己的问题…… 某处调用了 requests.cookies.get_dict() 未指定域名且返回的信息不包括域名信息,进而导致了同名 cookies 混淆……
    shanechiu
        29
    shanechiu  
       2017-12-05 16:10:44 +08:00
    一个很好的问题。的确,会经常碰到临时重定向的情况。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2987 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 13:30 PVG 21:30 LAX 06:30 JFK 09:30
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86