我想写一个查询话费和流量的爬虫,关键是实现模拟登陆的这个部分。 在登陆过程中,点击登陆之后,登陆表单会 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
1 Huayx9 OP 图片显示不成功好像。。。。 |
![]() | 2 iluhcm 2016-07-31 22:24:41 +08:00 ![]() 遇到类似问题,表示关注。。 |
3 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 。可以注意一下。 |
4 scnace 2016-07-31 22:59:18 +08:00 via Android ![]() 我之前爬学校也遇到过 302 Object moved here 的问题 要 header 里面设置下 Referer 你可以试试( |
5 digihero 2016-07-31 23:01:22 +08:00 ![]() python 不了解。不过用 PHP 来模拟的时候,碰到 302 ,是可以设置 CURL 的参数来实现跟踪跳转的。到跳那儿就跟到那儿。 python 一样可以,看看参数。 |
6 aeshfawre 2016-07-31 23:04:43 +08:00 ![]() 你这三个问题等于一个问题,就是 cookie. 用了 Session(),你就不需要管任何 cookie 的问题了. 问个问题,你这是做出来自用的么,还是拿出去卖的,python 代码写出来的会被倒卖吧.静态编译的才适合出售. |
8 Huayx9 OP @lxy 我是先 get 登陆页面, get 验证码,然后再 post 表单,用了 session()不是会自动管理 cookies 么, post 之后的 cookies 不是自动更新么。难道是 post 之后再 get 混淆类 cookies 了?在 post 之后获取 cookies 参数,再指定给( get 登陆成功页面)这个操作? |
11 aeshfawre 2016-07-31 23:17:18 +08:00 ![]() |
12 Huayx9 OP |
13 Huayx9 OP @aeshfawre 还有,我做的过程中,巩固 python 水平,掌握基础的写爬虫技能,熟悉 http 协议,如果写好了,我哥给我一点好处那更好不过了。。 我现在一直就是模拟登陆不成功, post 表单之后就抓瞎了。。。 cookies 总是不正常,也就 get 不到登陆成功的页面的信息。 谢谢你一直的耐心解答。。 cookies 这一关我过不了啊。。 |
14 scnace 2016-08-01 07:36:34 +08:00 via Android @Huayx9 额 碰到 302 了再 referer 啊 network 里应该有写吧 我在 blog 里写过的 你可以参考下 差不多场景 http://scnace.cc/wordpress/archives/1117 |
25 HFcbyqP0iVO5KM05 2016-08-01 18:53:14 +08:00 via Android 我只是提醒一下,题主你试过 allow_redirects=True 了吗? |
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 。 |
![]() | 27 sparkssssssss 2016-08-01 23:11:36 +08:00 via iPhone mark |
28 lxy 2016-08-04 10:51:41 +08:00 @Huayx9 抽空检查了一下项目代码,是我自己的问题…… 某处调用了 requests.cookies.get_dict() 未指定域名且返回的信息不包括域名信息,进而导致了同名 cookies 混淆…… |
![]() | 29 shanechiu 2017-12-05 16:10:44 +08:00 一个很好的问题。的确,会经常碰到临时重定向的情况。 |