python 实现自动登陆

当提到「登录」时,就不得不提 Cookie 技术,而说起 Cookie 技术时,还得从 HTTP 协议说起。HTTP 是一种无状态的协议, 协议本身不保留之前的一切请求信息和响应信息,也就是说,对于一个刚刚发送了HTTP 请求的客户端再次发起请求时,服务端并不知道之前访问过。这样设计的理由是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计如此简单。

但是,无状态导致业务处理就变得棘手了,一个简单的例子就是网上购物的时候,当我在一个页面把商品加入购物车的时候,正当我要跳转到支付页面时,如果没有一种机制来保持我的登录状态,那么之前选的商品全部丢失了。

因此,为了在无状态的 HTTP 协议之上维护会话状态,使服务器可以知道当前是和哪个客户端打交道,于是Cookie 技术应运而生 ,Cookie 通俗的理解就是服务端分配给客户端的一个标识。

Cookie原理其实也非常简单,总共4个步骤维护HTTP会话。

  

1. 浏览器第一次发起 HTTP 请求时,没有携带任何 Cookie 信息,服务器收到请求并返回给浏览器的HTTP响应,同时HTTP 响应包括了一个响应头 Set-Cookie 字段,它的值是要设置的 Cookie。

2. 浏览器收到来自服务器的 HTTP 响应,响应头中发现有 Set-Cookie 字段,就会将该字段的值保存在内存或者硬盘中。

3. 浏览器下次给该服务器发送 HTTP 请求时, 会将 Cookie 信息附加在 HTTP 请求的头字段 Cookie 中。

4. 服务器收到这个HTTP请求,发现请求头中有Cookie字段, 便知道之前就和这个用户打过交道了。

理解了 Cookie 的基本原理之后,我们就可以尝试用 Python 来实现模拟知乎登录。

用过知乎的都知道,只要提供用户名和密码以及验证码之后即可登录。当然,这只是我们眼中看到的,而背后隐藏的技术细节还需要借助浏览器来发觉。现在我们就用 Chrome 来查看当我们填完表单后,点击登录的时候究竟发生了什么?

首先进入知乎的登录页面 https://www.zhihu.com/#signin ,打开 Chrome 的开发者工具条(按 F12)先尝试输入一个错误的验证码观察浏览器是如何发送请求的。

进入开发这界面后,选择上面的NetWork, 左侧就会出现Name(不知道这里的name什么意思),右侧出现Headers

Name中选择email: 

General: 请求的URL和方法post

Request URL:
https://www.zhihu.com/login/email
Request Method:
POST

Request Headers:
headers = {
  "Host":"www.zhihu.com",
  "Referer":"https://www.zhihu.com/",
  'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87'
  }
Form Data:
  1. _xsrf:
    aeab808f9debd3187a084800b96082b3
  2. password:
    66666
  3. captcha_type:
    cn
  4. email:
    13301171201@163.com
所谓的模拟登陆就是:把上面的数据 post到 web server作者:liuzhijun
微信: lzjun567
公众号:Python之禅(id:VTtalk)
"""
import time
from http import cookiejar
import requests
from bs4 import BeautifulSoup

headers = {
    "Host": "www.zhihu.com",
    "Referer": "https://www.zhihu.com/",
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87'
}
# 使用登录cookie信息
session = requests.session()
session.cookies = cookiejar.LWPCookieJar(filename='cookies.txt')
try:
    print(session.cookies)
    session.cookies.load(ignore_discard=True)
except:
    print("还没有cookie信息")
def get_xsrf():
    response = session.get("https://www.zhihu.com", headers=headers)
    soup = BeautifulSoup(response.content, "html.parser")
    xsrf = soup.find('input', attrs={"name": "_xsrf"}).get("value")
    return xsrf
def get_captcha():
    """
    把验证码图片保存到当前目录,手动识别验证码
    :return:
    """
    t = str(int(time.time() * 1000))
    captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
    r = session.get(captcha_url, headers=headers)
    with open('captcha.jpg', 'wb') as f:
        f.write(r.content)
    captcha = input("验证码:")
    return captcha
def login(email, password):
    login_url = 'https://www.zhihu.com/login/email'
    data = {
        'email': email,
        'password': password,
        '_xsrf': get_xsrf(),
        "captcha": get_captcha(),
        'remember_me': 'true'}
    response = session.post(login_url, data=data, headers=headers)
    login_code = response.json()
    print(login_code['msg'])
    for i in session.cookies:
        print(i)
    session.cookies.save()
if __name__ == '__main__':
    email = "xxxx"
    password = "xxxxx"
    login(email, password)


使用chrome的调试功能(F12进入,firefox也是F12)没有找到firefox 使用的data Temp, 刚试了下 Firefox也可以:都是Network: name
看上面描述的信息。
调试工具也可以看清楚哪里出错了,如访问的url 是否不对等。

这里要返回session, 后面的web操作使用这个初始化的session,否则后面,访问又要出错了:没有登陆
Beautiful 的功能是格式化网页元素,
    def login(self):
        session = requests.session()
        rsp = session.get(self.LOGIN_URL)
        soup = BeautifulSoup(rsp.text, 'lxml')


        ls = ''
        execution = ''
        eventId = ''
        try:
            lt = soup.find('input', {'name':'lt'}).get('value')
            execution = soup.find('input', {'name':'execution'}).get('value')
            eventId = soup.find('input', {'name':'_eventId'}).get('value')
        except:
            pass


        form_data = {'username':self.user_name, 'password':self.password, 'lt':lt, 'execution':execution, '_eventId':eventId}
        print form_data
        print self.LOGIN_URL
        session.post(self.LOGIN_URL, data=form_data, headers=self.COOKIE_HEADER)
        return session

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值