使用Python实现青岛航空登录(一)

使用Python实现青岛航空登录(一)

​ 事情的起因是朋友在美利坚的学业结束了,回国的机票一票难求,无奈之下问我能不能用Python写一个脚本,实现对青岛航空从首尔到青岛的机票信息的监控。

(一)页面分析

​ 页面地址https://www.qdairlines.com/,用Google浏览器打开,主页大概是这个样子的。

青岛航空主页

​ 需要提交的数据有账号、密码和验证码,验证码是图形验证码,应该可以使用pillow和pytesseract两个库对验证码进行识别验证。
登录页面

​ F12打开开发者工具,输入账号密码和验证码点击登录,经过分析,找到账号密码和验证码的提交方式。

开发者工具

​ 请求提交的URL是https://www.qdairlines.com/api/auth/auth/form?username=619749686@qq.com&password=*******************ddc597ca780d

​ 很明显可以看出,账号和密码是通过URL来提交的,而验证码在请求头中的imageCode。

(二)获取图形验证码

​ 需要提交验证码,首先就要获取验证码,一般只要请求登录页面返回的响应就可以得到图形验证的图片,但是在测试过程中,我构造了如下请求头

	headers = {
		'Host' : 'www.qdairlines.com',
		'Origin' : 'https://www.qdairlines.com',
		'Referer' : 'https://www.qdairlines.com/',
		'codeType' : 'imageCode',
		'operType' : 'login',
		'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
	}

​ 虽然返回的响应状态码是200,但是返回的响应体为空。

在这里插入图片描述

​ 在第二次分析请求头的时候,发现一个被忽略的参数。

在这里插入图片描述

​ 这个名为deviceId的参数应该是一个时间戳,于是构造如下请求头。

time1 = time.time()
timestamp = str(int(time1*1000))
print(timestamp)
headers = {
		'Host' : 'www.qdairlines.com',
		'Origin' : 'https://www.qdairlines.com',
		'Referer' : 'https://www.qdairlines.com/',
		'codeType' : 'imageCode',
		'operType' : 'login',
		'deviceId' : timestamp,
		'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
	}

​ 在构造了新的请求头之后,再测试得到如下的响应体。
在这里插入图片描述
​ 请求体中的“result”应该就是图形验证码,此时我们已经正确得到图形验证码,接下来就是将编码保存为图片格式。

​ 再回到登录页面,在审查元素时,发现图形验证的 src为“data:image/jpeg;base64,/9j/…",分析结果为图片格式是jpeg,并通过base64方式加密,知道了加密方式之后,只需要解码并保存图片,即可获得图形验证码。

​ 首先通过正则获得图片的编码,然后通过Python的base64库解码,最后保存为jpeg格式,即可获得图形验证码的图片。

import requests
import base64
import re
code_url = r'https://www.qdairlines.com/api/auth/auth/imageCode/login'
time1 = time.time()
timestamp = str(int(time1*1000))
headers = {
		'Host' : 'www.qdairlines.com',
		'Origin' : 'https://www.qdairlines.com',
		'Referer' : 'https://www.qdairlines.com/',
		'codeType' : 'imageCode',
		'operType' : 'login',
		'deviceId' : timestamp,
		'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
	}
print(headers)
reponse = requests.post(code_url,headers=headers)
print(reponse)
print(reponse.content)
fcode = re.findall(r'"result":"(.*?)"',reponse.text)
# print(fcode)
code = r'{}'.format(fcode[0])
imagedate = base64.b64decode(code)	
file = open('code.jpeg','wb')
file.write(imagedate)
file.close()

(三)登录

​ 在得到图形验证码之后,我们就可以通过requests来实现登录了,先构造登录的请求头,将deviceId和imageCode参数设置为变量,分别接收时间戳和图形验证码。(由于是测试,我并没有使用PIL和pytesseract自动识别验证码,而是通过手填的方式)

login_headers = {
		'Accept' : 'application/json, text/plain, */*',
		'Accept-Encoding' : 'gzip, deflate, br',
		'Accept-Language' : 'zh-CN,zh;q=0.9',
		'Authorization' : 'Basic bWFya2V0LWZyYW1lLXp1dWw6cWRhaXJsaW5lcw==',
		'Cache-Control':' no-cache',
		'codeType' : 'imageCode',
		'Connection' : 'keep-alive',
		'Content-Length' : '2',
		'Content-Type' : 'application/x-www-form-urlencoded',
		'deviceId' : timestamp,
		'Host' : 'www.qdairlines.com',
		'imageCode' : imagecode,
		'operType' : 'login',
		'Origin' : 'https://www.qdairlines.com',
		'Pragma' : 'no-cache',
		'Referer' : 'https://www.qdairlines.com/',
		'Sec-Fetch-Dest' : 'empty',
		'Sec-Fetch-Mode' : 'cors',
		'Sec-Fetch-Site' : 'same-origin',
		'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
	}

​ 再发送请求之后得到响应,响应状态码200,响应体也标识请求成功,至此登录应该是成功了。
在这里插入图片描述

​ 贴出完整代码

import requests
import time
import re
import base64

if __name__ == '__main__':
    login_url = r'https://www.qdairlines.com/api/auth/auth/form?username=619749686@qq.com&password=46707b08ae5f05ea41fbddc597ca780d'
    code_url = r'https://www.qdairlines.com/api/auth/auth/imageCode/login'
    time1 = time.time()
    timestamp = str(int(time1*1000))
    headers = {
        'Host' : 'www.qdairlines.com',
        'Origin' : 'https://www.qdairlines.com',
        'Referer' : 'https://www.qdairlines.com/',
        'codeType' : 'imageCode',
        'operType' : 'login',
        'deviceId' : timestamp,
        'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
        }
    print(headers)
    reponse = requests.post(code_url,headers=headers)
    print(reponse)
    print(reponse.content)
    fcode = re.findall(r'"result":"(.*?)"',reponse.text)
    # print(fcode)
    code = r'{}'.format(fcode[0])
    imagedate = base64.b64decode(code)	
    file = open('code.jpeg','wb')
    file.write(imagedate)
    file.close()
    imagecode = input('请输入验证码:')
    login_headers = {
        'Accept' : 'application/json, text/plain, */*',
        'Accept-Encoding' : 'gzip, deflate, br',
        'Accept-Language' : 'zh-CN,zh;q=0.9',
        'Authorization' : 'Basic bWFya2V0LWZyYW1lLXp1dWw6cWRhaXJsaW5lcw==',
        'Cache-Control':' no-cache',
        'codeType' : 'imageCode',
        'Connection' : 'keep-alive',
        'Content-Length' : '2',
        'Content-Type' : 'application/x-www-form-urlencoded',
        'deviceId' : timestamp,
        'Host' : 'www.qdairlines.com',
        'imageCode' : imagecode,
        'operType' : 'login',
        'Origin' : 'https://www.qdairlines.com',
        'Pragma' : 'no-cache',
        'Referer' : 'https://www.qdairlines.com/',
        'Sec-Fetch-Dest' : 'empty',
        'Sec-Fetch-Mode' : 'cors',
        'Sec-Fetch-Site' : 'same-origin',
        'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
        }
    re = requests.post(login_url,headers=login_headers)
    print(re)
    print(re.text)

(四)写在最后

​ 实现登陆之后,便是带身份保持登录状态查询机票信息,由于本人也是初学者,在查询过程中还有一部分问题尚未解决,等后续成功之后会继续更新。如果有幸被大佬看到,欢迎提出改进意见,在此先谢过。

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页