requests+re 模拟登陆去哪儿网

分析登陆页面
1. 使用 Chrome 无痕模式访问去哪儿网登陆网页
https://user.qunar.com/passport/login.jsp

直接使用 Chrome 开发者工具分析,发现cookie 返回 QN1


requests+re 模拟登陆去哪儿网_第1张图片
image.png
2. 访问去哪儿网发现登陆需要验证码,所以分析下验证码接口

,发现验证码的URL是固定的

https://user.qunar.com/captcha/api/image?k={en7mni(z&p=ucenter_login&c=ef7d278eca6d25aa6aec7272d57f0a9a
image.png

而且发现访问验证码后,返回的 cookie 有所改变。返回QN1、QN25


requests+re 模拟登陆去哪儿网_第2张图片
image.png
3. 尝试错误登陆,分析登陆接口

发现请求的网址为

https://user.qunar.com/passport/loginx.jsp

查看请求页面的 from data 数据,以及传入的 cookie 数据 QN1、QN25、QN271、_i、_vi、_fid


requests+re 模拟登陆去哪儿网_第3张图片
image.png

requests+re 模拟登陆去哪儿网_第4张图片
image.png

直接使用验证码返回的 cookie 去访问请求页面,发现不能登录成功,可能有:

  • cookie 不完整;
  • 除了 cookie 还有其他 request headers 校验;

尝试分析剩下的 cookie数据 QN271、_i、_vi、_fid的来源

查找QN271
直接在Chrome 开发者工具 全局搜索 Ctrl+Shift+F,搜索 QN271 的值

requests+re 模拟登陆去哪儿网_第5张图片
image.png

发现QN271是在JS里面的,而且第三条搜索结果的URL很干净

https://rmcsdf.qunar.com/js/df.js?org_id=ucenter.login&js_type=0

可以看下里面的构造(数据太长,未截取关键部位)

requests+re 模拟登陆去哪儿网_第6张图片
image.png

点左下角的Pretty print 格式化js文件,发现 QN271存在里面,可以直接使用 正则 获取其值

# secScript.setAttribute("src", "https://rmcsdf.qunar.com/js/device.js?orgId=ucenter.login&sessionId=a7a856be-c704-4aa4-89e6-76f14da844a5&auto=false");
sessionId = re.findall(r'sessionId=(.*?)&',response.text)[0]

查找_i 和 _vi
用上面同样的方法进行查找,并未能找到 _i 的值
一般来说 _i 这个值是服务器返回是,那么可以尝试搜索 set-cookie-name:_i(一般来说应先尝试搜索这个)

requests+re 模拟登陆去哪儿网_第7张图片
image.png

发现有返回 _i 和 _vi 的过程
而URL是:

https://user.qunar.com/passport/addICK.jsp?ssl

查找 fid
set-cookie-name:的方法尝试查找 fid 的值

requests+re 模拟登陆去哪儿网_第8张图片
image.png

很幸运能找到该cookie 值
但是URL却是:

https://rmcsdf.qunar.com/api/device/challenge.json?callback=callback_1531563394135&sessionId=a7a856be-c704-4aa4-89e6-76f14da844a5&domain=qunar.com&orgId=ucenter.login

callback: callback_1531563394135
sessionId: a7a856be-c704-4aa4-89e6-76f14da844a5
domain: qunar.com
orgId: ucenter.login

需要分析该URL的组成
callback 一般是固定值,请求返回后调用哪个js
sessionId 是非固定值,重新刷新页面,其值会改变
domain 跟 orgId 是固定值
所以难点是找出 sessionId 的规律
但难得可贵的是,这个sessionId值是跟上面 查找QN271 中的 sessionId 是一致的

所以 cookie 添加思路为:

  1. 访问登录页面,获得QN1
    https://user.qunar.com/passport/login.jsp
  2. 访问验证码页面,获得QN1,QN25
    https://user.qunar.com/captcha/api/image?k={en7mni(z&p=ucenter_login&c=ef7d278eca6d25aa6aec7272d57f0a9a
  3. 访问 addICK 页面,获得_i,_vi
    https://user.qunar.com/passport/addICK.jsp?ssl
  4. 访问 df.js 页面,获得 sessionId,即获得 QN271(并非直接存储在 session)
    https://rmcsdf.qunar.com/js/df.js?org_id=ucenter.login&js_type=0
  5. 访问由 sessionId 组成的 URL,获得fid,并往 session 会话中添加 QN271 {'QN271':cookie_QN271}
    'https://rmcsdf.qunar.com/api/device/challenge.json?callback=callback_1511693290383&'
    'sessionId={}&domain=qunar.com&orgId=ucenter.login'.format(cookie_QN271)

技巧:cookie 添加完成后可以尝试再次登录,访问过程中可以 设置断点debug查看 cookie 是否添加完整


requests+re 模拟登陆去哪儿网_第9张图片
image.png

代码实现:

import requests
import re
"""

此代码共分为4部分:初始化模块,获取添加cookies模块,验证码模块,登录模块

"""


def start_get_session():
    session_ = requests.session()   # 得到一个session
    return session_


def get_base_cookies(session_):
    session_.get('https://user.qunar.com/passport/login.jsp')  # 获得cookie参数,原始的QN1
    get_image(session_)   # 通过调用get_image函数,得到验证码图片,同时获得cookie参数QN1,QN25
    session_.get('https://user.qunar.com/passport/addICK.jsp?ssl')  # 获得cookie参数_i,_vi

    """
    由于获取fid参数的url需要cookie参数SESSIONID得到,所以没办法直接得到fid,需要先得到SESSIONID这个参数,再得到fid参数

    """
    # 经过查找发现SESSIONID在这个js文件中,所以先得到它
    response = session_.get('https://rmcsdf.qunar.com/js/df.js?org_id=ucenter.login&js_type=0')
    # 查找SESSIONID
    cookie_SE = re.findall(r'&sessionId=(.*?)&', response.text)[0]  # 通过正则得到SESSIONID

    # 获取fid
    session_.get('https://rmcsdf.qunar.com/api/device/challenge.json?callback=callback_1511693290383&'
                 'sessionId={}&domain=qunar.com&orgId=ucenter.login'.format(cookie_SE))

    session_.cookies.update({'QN271': cookie_SE})  # 通过比对发现参数QN271和SESSIONID相同,所以直接加入cookies中


def get_image(session_):
    response = session_.get(
        'https://user.qunar.com/captcha/api/image?k={en7mni(z&'
        'p=ucenter_login&c=ef7d278eca6d25aa6aec7272d57f0a9a')   # 获得二维码的response

    with open('./img/code.png', 'wb') as f:
        f.write(response.content)   # 把二维码存进同级img文件夹下命名为code


def login(session_, username, password, vcode):
    data ={
        'loginType': 0,
        'username': username,
        'password': password,
        'remember': 1,
        'vcode': vcode,
    }

    url = 'https://user.qunar.com/passport/loginx.jsp'
    response = session_.post(url , data)   # 通过post请求方式,模拟登录
    print(response.text)


if __name__ == '__main__':   # 主程序,程序入口
    session = start_get_session()   # 实例化一个session
    get_base_cookies(session)   # 调用函数,在session中添加cookie
    username = input('请输入账号:')
    password = input('请输入密码:')
    vcode = input('请输入验证码:')
    login(session, username, password, vcode)  # 调用登录函数

改进:
账户密码可以添加到环境变量中,从环境变量中获取,或者放到.env文件,然后读取;
验证码可以考虑OCR识别或者打码

你可能感兴趣的:(requests+re 模拟登陆去哪儿网)