Python用post方法登陆知乎

在以往的文章中,我们主要使用了requests的get方法来直接获取网页的内容。支持GET方法的网页,接受我们的URL, 从URL里面取出参数,然后再将结果返回给浏览器。由于URL的长度是有限制的,所以只能接收少量的参数。而支持POST方法的网页,可以传递大量的参数和大量的信息。如果一个网页只支持POST方法,那这个网页是没有办法在浏览器里面直接输入网址访问的。requests的post方法支持将参数以POST方式提交给网页,并得到网页的返回信息。

大多数的网站,登录的用户名和密码都是通过POST方式提交给服务器的,因此如果可以模拟网站的这个提交行为,就可以模拟登录网站。

我们首先进入知乎的登录页面,打开Chrome的开发者工具的Network选项卡,勾选“Preserve log”并故意输入错误的账号和密码尝试登录,从Chrome抓取到的数据中我们可以找到我们需要的信息:

network

form data

从以上两张图中,我们可以看到,当我们点击了登录按钮以后,程序会将图二红框中的Form Data下面四个数据使用POST方式发送给图一红框中的https://www.zhihu.com/login/email 这个URL。

注意:如果你输入的账号不是手机号,而是邮箱,数据将会发送到的URL为:https://www.zhihu.com/login/phone_num

上图中的Form Data,后三项的意义显而易见,email: 邮箱, password: 密码, remember_me: 记住我。但是第一项”_xsrf”是什么意思?它后面的一长串数据是哪里来的?

这个时候大家打开登录页面的源代码,你将会找到这样内容:

html

那么事情就简单了,使用正则表达式或者XPath先从源代码里面把这个xsrf提取出来,然后再和登录信息一起提交即可。

还有一点需要注意:在Form Data中,remember_me后面的值是true, 首字母是小写的。但是在Python里面的布尔值True, 首字母需要大写。

在一般情况下是不需要使用验证码登录的,所以只需要提供图二列出的信息,将它们写成一个字典并POST提交就能实现登录。那么如果遇到验证码怎么办呢?后面我们会有专门的课程将验证码的处理。

现在,我们已经知道了登录知乎的原理,于是就可以通过代码来实现登录。核心代码如下:

data = {'_xsrf': xsrf, 'email': '邮箱', 'password': '密码',
        'remember_me': True}
session = requests.Session()
result = session.post('https://www.zhihu.com/login/email', headers=header, data=data) #这里的result是一个json格式的字符串,里面包含了登录结果

#之后访问知乎的其他页面,只需要使用session.get('网址', headers=header)这种格式

front_page = session.get('https://www.zhihu.com', headers=header)
print(front_page.content.decode())

其运行效果如下图所示:

运行效果

网址返回的登录结果是登录成功,并且查看源代码可以证明是登录成功。

对于其他的网站,整个流程是完全一样的,只是POST提交的参数各有不同。有些网址只需要POST提交用户名和密码就可以了,而另外一些网址,可能还需要从源代码里面提取更多的参数。

#encoding=utf-8
import requests,re,json
header={
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding':'gzip, deflate, br',
    'Accept-Language':'zh-CN,zh;q=0.8',
    'Connection':'keep-alive',
    'Cookie':'d_c0="ACCAy9ov2AqPTgAkDUuZ-jOeEf8VkJ1jWMw=|1479086751"; q_c1=e0f6b8a4ef414520a96569286788849c|1479086751000|1479086751000; l_cap_id="ODBlM2QzZWJkZDU2NDVmYjk5OGFmMWExZjdlNjE4MTY=|1481529404|b0aa35ca238d60c9b42bc90af950abc75ea7e55f"; cap_id="NTczOGViM2Q2MDAyNDAwYjg0MDI5MGIzYjczM2IwZWM=|1481529404|38baca19c5b6c320d61de3c1a5c57b33622a2bf5"; __utmt=1; r_cap_id="Y2U3ZjRkOTk1MDIwNDNiODgzM2IzNGI2NTZjMzNhNDY=|1481529405|3a5d3af6d915fb0a79cf2dcd925e1cf503cf4ab2"; login="YmVlYzExYThjNWE3NDMzZmEzNzgwMTdhZjc4YTg1M2M=|1481529422|a8210cba1dba488ebfb262877ffd44d9d3e42964"; _xsrf=cf55698c3c4c7b8ae72ee3bc5027c134; __utma=51854390.89943953.1479086837.1481248499.1481529486.8; __utmb=51854390.8.10.1481529486; __utmc=51854390; __utmz=51854390.1481248499.7.7.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmv=51854390.000--|2=registration_date=20151125=1^3=entry_date=20161114=1; _zap=b81df854-46a4-4559-9da4-32dc69f33f7c; n_c=1',
    'Host':'www.zhihu.com',
    'Upgrade-Insecure-Requests':'1',
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36',
}
html=requests.get('https://www.zhihu.com/#signin',headers=header).content
# print html

re_data=re.compile(r'<input type="hidden" name="_xsrf" value="(.*?)"/>')
login_token=re.search(re_data,html).group(1)
# print login_token

data = {'_xsrf': login_token, 'email': 'xxxxxxx', 'password': 'xxxxxxxx', 'remember_me': True}
session = requests.Session()
result = session.post('https://www.zhihu.com/login/email', headers=header, data=data) #这里的result是一个json格式的字符串,里面包含了登录结果

result_dict=json.loads(result.content)
print result_dict

#之后访问知乎的其他页面,只需要使用session.get('网址', headers=header)这种格式

front_page = session.get('https://www.zhihu.com', headers=header)
print(front_page.content.decode())

此篇博客仅供学习交流

2 thoughts on “Python用post方法登陆知乎”

Leave a Comment