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

2016-07-31 21:32:29 +08:00
 Huayx9

我想写一个查询话费和流量的爬虫,关键是实现模拟登陆的这个部分。 在登陆过程中,点击登陆之后,登陆表单会 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

我有三个问题

代码如下,谢谢大家

#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

11537 次点击
所在节点    Python
29 条回复
Huayx9
2016-07-31 21:33:05 +08:00
图片显示不成功好像。。。。
iluhcm
2016-07-31 22:24:41 +08:00
遇到类似问题,表示关注。。
lxy
2016-07-31 22:56:45 +08:00
懒得具体分析了,简单说下经验。
1 、 cookies 在任何时候都能够被设置。如果是我来做这个,我会先获取( get )登录的页面(大多数时候会在这里设置 cookies 和 token ),模拟人工操作,而不是一开始就提交( post )数据。顺便注意 JS 也可以设置 cookies 。
2 、 requests 会自动处理 cookies 和 302 。
3 、同上。不过好像 requests 有个坑,不知道是不是因为自己项目中对 requests 封装过度导致的,在访问多个不同的子域名的时候,貌似会混淆*同名的*cookies ,需要手动指定 cookies 。可以注意一下。
scnace
2016-07-31 22:59:18 +08:00
我之前爬学校也遇到过 302 Object moved here 的问题 要 header 里面设置下 Referer 你可以试试(
digihero
2016-07-31 23:01:22 +08:00
python 不了解。不过用 PHP 来模拟的时候,碰到 302 ,是可以设置 CURL 的参数来实现跟踪跳转的。到跳那儿就跟到那儿。 python 一样可以,看看参数。
aeshfawre
2016-07-31 23:04:43 +08:00
你这三个问题等于一个问题,就是 cookie. 用了 Session(),你就不需要管任何 cookie 的问题了.

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

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

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

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

谢谢你一直的耐心解答。。 cookies 这一关我过不了啊。。
scnace
2016-08-01 07:36:34 +08:00
@Huayx9 额 碰到 302 了再 referer 啊 network 里应该有写吧 我在 blog 里写过的 你可以参考下 差不多场景 http://scnace.cc/wordpress/archives/1117
jackyspy
2016-08-01 08:12:54 +08:00
@Huayx9 你这个需求, selenium2 也是一个不错的选择
Huayx9
2016-08-01 08:23:14 +08:00
@jackyspy 验证码我准备假如一个 OCR 模块, selenium2 能够拓展么?
Huayx9
2016-08-01 08:24:15 +08:00
@scnace 咿呀,加个什么其他好友吧,有机会交流学习~
scnace
2016-08-01 08:31:26 +08:00
@Huayx9 wechat:c2NiaXp1Cg==
Huayx9
2016-08-01 08:37:32 +08:00
@scnace 有没有等号。。
scnace
2016-08-01 08:54:16 +08:00
@Huayx9 我稍微 base64 加了下密 你去 decode 一下 就行了😂

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/296195

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX