我想写一个查询话费和流量的爬虫,关键是实现模拟登陆的这个部分。 在登陆过程中,点击登陆之后,登陆表单会 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 1
遇到类似问题,表示关注。。
|
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 。可以注意一下。 |
4
scnace 2016-07-31 22:59:18 +08:00 via Android 1
我之前爬学校也遇到过 302 Object moved here 的问题 要 header 里面设置下 Referer 你可以试试(
|
5
digihero 2016-07-31 23:01:22 +08:00 1
python 不了解。不过用 PHP 来模拟的时候,碰到 302 ,是可以设置 CURL 的参数来实现跟踪跳转的。到跳那儿就跟到那儿。 python 一样可以,看看参数。
|
6
aeshfawre 2016-07-31 23:04:43 +08:00 1
你这三个问题等于一个问题,就是 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 1
|
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
coolloves 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
一个很好的问题。的确,会经常碰到临时重定向的情况。
|