求助:利用 requests 模拟登录,中文数据提交 + 两次 302 重定向

2015-01-17 23:31:07 +08:00
 zvDC

如题,想利用python的requests来进行网站的模拟登录,苦于技术太差,纠结了许久,也到处搜索还是没有找到答案,烦请大家帮忙。

问题是:
1、如何处理form data中提交的数据为中文的编码问题?
2、如何处理两次302,"object moved"重定向的问题,在requests中如何写代码?

这是成功登录时的抓包图:
wireshark
http://i.imgur.com/Z1qcWH7.png
Chrome DevTools
http://i.imgur.com/YkEuq1s.png

有问题的代码如下:

import requests

url_login = 'http://www.example.com/RedeployCourse/login.asp'
url_default = 'http://www.example.com/RedeployCourse/default.asp'
url_info = 'http://www.example.com/RedeployCourse/RedeployInfo.asp'

headers = { 'Content-Type': 'application/x-www-form-urlencoded',}
form_data={"username": '中文用户名',"password":'abcdef'}

s = requests.Session()
s.get(url_login)

r = s.post(url_login, data=form_data, headers=headers, allow_redirects=False)

s.get(url_default)
r = s.get(url_info)

14610 次点击
所在节点    Python
16 条回复
14
2015-01-17 23:41:59 +08:00
In [1]: import urllib

In [2]: urllib.quote('中文用户名')
Out[2]: '%E4%B8%AD%E6%96%87%E7%94%A8%E6%88%B7%E5%90%8D'

第二个没明白你的意思,这个可能对你有帮助: http://stackoverflow.com/questions/20475552/python-requests-library-redirect-new-url
aaaa007cn
2015-01-18 01:02:07 +08:00
302 有什么问题?
已经事先知道目标网址的话
最多就是再带上 cookie 和 referer
cookie 已经由 session 处理了
referer 看场合也有不需要的
s.get(url_default, allow_redirects=False, headers={"referer": url_login})
r = s.get(url_info, allow_redirects=False, headers={"referer": url_default})
不知道目标网址的话就从 r.headers["Location"] 来取跳转的网址

不过 requests 默认 allow_redirects 为 True 的
也可以让它自动跳转
ericFork
2015-01-18 06:11:59 +08:00
如果不是非要用 Python 的话,可以试试 casperjs
zvDC
2015-01-18 08:22:36 +08:00
@14 @aaaa007cn @zvDC 谢谢各位的回复

我想还是先把第一个问题解决吧

服务端页面编码为 <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
提交中文的问题,我还有疑问:
拿 “登录”二字举例,

unicode 字符
In [1]: u"登录"
Out[1]: u'\u767b\u5f55'

转换成gb2312格式
In [2]: u'登录'.encode('gb2312 ')
Out[2]: '\xb5\xc7\xc2\xbc'

进行URL编码
In [3]: urllib.quote(u'登录'.encode('gb2312'))
Out[3]: '%B5%C7%C2%BC'

这样转换成gb2312编码之后,与cookie中对应的字符显示是一致的
可是通过wireshark抓包,却发现,正确的值应该是:\265\307\302\274
请问这是如何实现的,或者哪个地方我忽略了,谢谢!
zvDC
2015-01-18 08:31:51 +08:00
@aaaa007cn 你好
使用
s = requests.session()
这个应该是可以把cookies一直保留,直到会话结束。
在这种情况下:
1、是否,只要我post过去的值是正确的,就不需要再添加新的值?
  (因为,我发现用脚本post比真实提交的cookie值少了一些)

2、如果需要添加,如何向cookies中添加新的值,比如{"name":'value'}?
zvDC
2015-01-18 10:48:20 +08:00
在  http://www.v2ex.com/t/97347 中看到修改cookie值的方法

def update_cookie(cookiejar, cookie):
_cookies = requests.cookies
_cookies.remove_cookie_by_name(cookiejar, 'cookie_name')
cookiejar.set_cookie(_cookies.create_cookie('cookie_name', cookie, **{'domain': '.example.com'}))
mringg
2015-01-18 11:14:53 +08:00
redirect这个属性为true就没多大问题吧
Sylv
2015-01-18 12:45:46 +08:00
'\xb5\xc7\xc2\xbc' 和 '\265\307\302\274' 应该是等价的,只是表示方式不一样,不过是一个写成的是16进制,一个写成的是8进制的。所以应该直接提交 u'登录'.encode('gb2312 ') 就好了。

根据 requests 文档,向 requests.Session 的 cookies 中添加新值,应该这样就好了:
s.cookies.update({"name":'value'})

另外我不理解为什么你在 r = s.post(url_login) 之前还要 s.get(url_login) 一次?同样的还有 s.get(url_default)?看样子你不需要这两个的 response,那为什么要多此一举地 get 一下呢?
mengskysama
2015-01-18 14:39:34 +08:00
楼主其实昨天我看了下,我没敢给你贴上来,这样真的好吗?

登陆很简单,因为web后端吃的是gb2312所以中文必须要先编码成2312,然后再让他做urlencode,这个requests能自己帮你做好。你不用urllib.quote

还有就是requests会自动做decode成unicode,如果返回的头部没有指定ISO-XXX什么的,这样.text获取到的就是错误的unicode r.encoding = 'gb2312'


url_login = 'http://os.ningboerji.com:82/RedeployCourse/login.asp'
headers = { 'Content-Type': 'application/x-www-form-urlencoded'}
form_data={"UserName": '\'or\' = \'or\'',"Pwd":'','B1':u'登录'.encode('gb2312')}
s = requests.Session()
r = s.post(url_login, data=form_data, headers=headers)
r.encoding = 'gb2312'
print r.text.encode('utf-8')
exit(1)
zvDC
2015-01-18 14:40:53 +08:00
@mringg 谢谢回复,requests 默认 allow_redirects 为 True,没能成功。

@Sylv 谢谢。如你所说,'\xb5\xc7\xc2\xbc' 和 '\265\307\302\274' 应该是等价的,没有想到。是否有方法指定要生成的进制模式。

之所以在post之前,先 s.get(url_login) 一下的原因,是想获得一个session cookie的值,后边要用到。

后边的s.get(url_default),是因为在F12或者抓包里看到的都是在这样一个地址……

(对于上面的做法,我都不确定是否有用,刚刚开始学习,只是在尝试)
mengskysama
2015-01-18 14:51:21 +08:00
如果没猜错你的系统和上面的一样有注入漏洞,在登录'or' = 'or'试试?迟早被人捅
zvDC
2015-01-18 14:51:23 +08:00
@mengskysama 太感谢了。谢谢你。
“这样好吗?”,放心,不是做坏事。
只是地址链接能否修改一下,不公开呀?

v2不能发私信,也不知道你现在还可以修改吗?
mengskysama
2015-01-18 15:11:38 +08:00
@zvDC V2不能编辑也不能删除
我看你的DEST IP 和这个不匹配我就贴了..本想给你做个完成的例子..并不是有意冒犯。
如果你是管理员,还是赶紧补掉吧。
zvDC
2015-01-18 15:16:46 +08:00
@mengskysama 没事,谢谢。
我不是管理员,只是不想因为我给别人带来不必要的麻烦。
关注你了,向你学习。
aaaa007cn
2015-01-20 00:16:37 +08:00
>> 是否,只要我post过去的值是正确的,就不需要再添加新的值?
session 已经自动处理了 cookie
一般不需要手动更新

>> 因为,我发现用脚本post比真实提交的cookie值少了一些
可能是你先前少请求了某些页面
也可能是真实提交时多了一些
建议清掉浏览器 cookie 或者新开隐身模式去测试

>> requests 默认 allow_redirects 为 True,没能成功
怎么不成功
贴出相关信息
比如出错信息
比如 r.history
比如 r.text
zvDC
2015-01-23 05:27:23 +08:00
@aaaa007cn 谢谢!
对隐身模式测试,以前不知道,下次可以试试。
问题出在我对编码这块了解不清,这块问题解决了,后面就没有问题了。

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

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

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

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

© 2021 V2EX