12306 抢票

一、写在前面

正值国庆之际,我还在为抢不到火车票,只能坐大巴回家而烦恼~你呢?
好消息来了,从学完这篇推文后,你就再也不用每天求这个朋友圈,求那个qq空间了。
第一篇,我们先登录12306,读完本篇,你将学会:如何模拟登录,基本图片验证方法,一波三折,过程很有意思,参考了网上一些资料。

二、一顿骚操作

流程(字有点丑,马马虎虎看吧 ):
登录流程

1.登录图片验证破解

(1)获取登录页面,session 保存 cookies值。

访问页面:https://kyfw.12306.cn/otn/login/init,F12页面分析,如下:

Headers中
Request URL: https://kyfw.12306.cn/otn/login/init
Request Method: GET

登录页面分析

  • 代码:
import requests
import os
from fake_useragent import UserAgent

# 1.获取登录
# 请求头,反爬伪装
headers = {
“User-Agent”: UserAgent(verify_ssl=False).random,
“Host”:“kyfw.12306.cn”,
“Referer”:“https://kyfw.12306.cn/otn/passport?redirect=/otn/”
}

login_url = ‘https://kyfw.12306.cn/otn/login/init’
# 1.1 cookie保持
session = requests.Session()
# 1.2 get请求
login_response = session.get(login_url,headers = headers)
login_html = login_response.text
# print(login_html)

(2)获取验证图片,破解验证操作
  • 破解思路:
    从页面上下载验证图片到本地,然后按要求选择正确图片位置,传递正确图片坐标,模拟页面点击,发送请求,模拟验证操作。
  • 验证图片页面分析:

验证图片所在处分析

Headers中
Request URL: https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.8854830207575652
Request Method: GET

  • 检查验证分析:
    这个必须在页面上进行账户密码输入,验证选择后才能加载出来,所以我就输入账号和错误密码,图片验证,加载出下面结果:

captcha-check :用于检查验证图片是否选择正确(验证正确)
login : 用户登录账号、密码判断
都是POST请求

检查验证

Headers中
Request URL: https://kyfw.12306.cn/passport/captcha/captcha-check
Request Method: POST
data = {
“answer”: positions,
“login_site”: “E”,
“rand”: “sjrand”
}

  • 代码:
# 2.获取并破解验证操作
# 2.1 下载验证图片
captcha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.8854830207575652'
captcha_response = session.get(captcha_url,headers = headers)
# 文件保存路径
image_path = os.path.abspath('image') + '/captcha_image.jpg'
# 以二进制写入文件
with open(image_path,'wb') as image_file:
	image_file.write(captcha_response.content)
# 2.2 验证
check_url = 'https://kyfw.12306.cn/passport/captcha/captcha-check'
# 输入数据格式为:x1,y1,x2,y2,...,xn,yn
positions = input("请输入验证码: ")   # 正确图片坐标
# 发送验证码
data = {
	"answer": positions,
	"login_site": "E",
	"rand": "sjrand"
}
check_response = session.post(check_url,data = data,headers = headers)
check_result = check_response.json()
# 测试发现,result_code = 4 时,表示验证成功
if not check_result['result_code'] == 4:
	exit("验证失败")
print(check_result )


 
   
   
   
   
  • 运行结果:

验证图片
验证结果

2.登录

(1)登录 login 分析
  • F12分析

login传入参数

Request URL: https://kyfw.12306.cn/passport/web/login
Request Method: POST
data = {
‘username’: Account_number, # 用户账号
‘password’: Password, # 用户密码
‘appid’: ‘otn’
}

  • 代码:
# 3.开始登录操作
login_check_url = 'https://kyfw.12306.cn/passport/web/login'
login_check_data = {
'username': Account_number,
'password': Password,
'appid': 'otn'
}
login_check_response = session.post(login_check_url,data=login_check_data,headers = headers)
print(login_check_response.json())


  
    
    
    
    
  • 运行结果:
    登录运行结果
    然而并没有正真的登录成功。
(1)登录 权限获取
  • 基本分析
    成功登录12306后页面为图示:
    成功登录

可以查找我们爬取的页面源码中包不包含我的名字来判断:我们是否是真的登录成功了,12306的内部权限验证比较麻烦,从最开始的图解可以看出来,掩饰过验证,密码账号输入之外,还有权限设置,还是两层,代码如下,不理解就加我微信:zs820553471吧。

  • 代码
# 4. 获取权限 authority
# 4.1 获取权限密钥:newapptk
uamtk_data = {
	"appid":"otn"
}
uamtk_url = "https://kyfw.12306.cn/passport/web/auth/uamtk"
uamtk_response = session.post(uamtk_url, headers=headers, data=uamtk_data)
uamtk_dict = uamtk_response.json()
newapptk = uamtk_dict['newapptk']
# print(uamtk_dict['newapptk'])

# 4.2 传递密钥,获取权限
uamauthclient_data = {
“tk” : newapptk
}
uamauthclient_url = “https://kyfw.12306.cn/otn/uamauthclient”
uamauthclient_response = session.post(uamauthclient_url, headers=headers, data=uamauthclient_data)

# 5 正真的登录
initMy_url = “https://kyfw.12306.cn/otn/index/initMy12306”
initMy_response = session.get(initMy_url, headers=headers)
my_name = initMy_response.text.find(“张建华”)
if not my_name == -1:
print(“用户已经登录成功”)

  • 运行结果

登录成功

三、随便说说

刚开始写这篇推文的时候本来是想一篇写完12306登录,车次信息获取,抢票,购票操作的,可写着写着,发现事情不是这么简单,心有余而力不足,昨天在GitHub上开了个账户,12306系列也会在GitHub上更新(之前代码一直放在码云上,中文的方便),欢迎大家加入,一起完成,不再为买票而烦恼。

你可能感兴趣的:(面试,java,servlet,服务器)