Python爬虫之12306-买票器小白源码
研究不易
import requests
import re
import urllib.parse
import json
import datetime
from collections import OrderedDict
self=requests.session()
self.verify=False
self.headers={
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, br',
'Accept-Language':'zh-CN,zh;q=0.9',
'Connection':'keep-alive',
'Host':'kyfw.12306.cn',
'Cache-Control':'no-cache',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
}
def dow():
url='https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand'
requests.packages.urllib3.disable_warnings()
res=self.get(url)
print(res.status_code)
if res.status_code==200:
with open('login.jpg','wb') as f:
f.write(res.content)
else:
dow()
#验证
def yanzhengma():
#获取验证码
dow()
# 1 2 3 4 5 6 7 8
xylist=['35,35','105,35','175,35','245,35','35,105','105,105','175,105','245,105']
print('请依次输入验证码的位置并换行,0表示结束')
ilist=[]
while True:
i=input()
if i=='0':
break
ilist.append(xylist[int(i)-1])
xy=','.join(ilist)
print(xy) data={
'answer':xy,
'login_site':'E',
'rand':'sjrand'
}
url='https://kyfw.12306.cn/passport/captcha/captcha-check'
requests.packages.urllib3.disable_warnings()
res=self.post(url,data=data)
print(res.url)
print(res.text)
code=re.search('_code.*?(\d)',res.text,re.S).group(1) print(code) # 成功返回True,失败递归调用
if code=='4':
print('验证成功,请登陆') elif code=='5':
print('验证错误')
yanzhengma()
elif code=='7':
print('验证超时')
yanzhengma()
else:
print('验证失败')
yanzhengma()
def login():
yanzhengma()#验证码
data={
'username':'账号,
'password':'密码,
'appid':'otn'
}
url='https://kyfw.12306.cn/passport/web/login'
requests.packages.urllib3.disable_warnings()
res=self.post(url,data=data)
print(res.text)
code=re.search('_code.*?(\d)',res.text,re.S).group(1) # 成功返回True,失败递归调用
if code=='0':
yzdata={
'appid':'otn'
}
tk_url='https://kyfw.12306.cn/passport/web/auth/uamtk'
resp3=self.post(tk_url,data=yzdata)
print('-----------------第一次验证-----------------')
print(resp3.text)
login_message=resp3.json()['newapptk']
print('loginMessage=',login_message)
yz2data={
'tk':login_message
}
client_url='https://kyfw.12306.cn/otn/uamauthclient'
resp4=self.post(client_url,data=yz2data)
print('-----------------第二次验证-----------------')
print(resp4.text)
print('登陆成功,可以开始购票') elif code=='1':
print('密码输入错误。如果输错次数超过4次,用户将被锁定。')
login()
else: print('登录失败')
login()
def shoppiao(): data={
'leftTicketDTO.train_date':'2018-10-15',#时间
'leftTicketDTO.from_station':'BJQ',#出发站码
'leftTicketDTO.to_station':'CBN',#目的地码
'purpose_codes':'ADULT'#票类型ADULT成人,STUDENT学生
}
url='https://kyfw.12306.cn/otn/leftTicket/queryA?'
requests.packages.urllib3.disable_warnings()
res=self.get(url,params=data)
print(res.status_code)
print(res.text)
dictr=json.loads(res.text)
pklist=dictr.get('data').get('result')
for item in pklist:
sp_item = item.split('|')
for index, item in enumerate(sp_item,0): print('{}:\t{}'.format(index, item))
'''
通过分析
0:列车信息(订票时候需要) 1:信息 2:火车编号
3:列车号 4:始发站 5:终点站 6:起始站 7:目标站 8:出发时间 9:到达时间
10:行车时间
11:有3种状态:Y, N, IS_TIME_NOT_BUY 分别对应,可以预定,不可以预定,其他原因----对应的是第1项
12:参数leftTicket
13:日期
14:
15:参数train_location
21:高级动卧 22: 23:软卧 24:软座 25:特等座 26:无座 28:硬卧 29:硬座 30:二等座 31:一等座 32:商务座 33:动卧
'''
if sp_item[11]=='Y':#可以买票,开始订票
if sp_item[30]!='无':#买二等座
print(sp_item[30])
if vel_longin_2():#验证登陆
print('已经登陆可以开始下单')
self.headers['X-Requested-With']='XMLHttpRequest'
secretStr=urllib.parse.unquote(sp_item[0]) self.headers['Referer'] = 'https://kyfw.12306.cn/otn/leftTicket/init' submitOrderRequest(secretStr) data = OrderedDict()
data["_json_att"] =''
data["fromStationTelecode"] =sp_item[6]
data["leftTicket"] = sp_item[12]
data['purpose_codes']='00'
data['REPEAT_SUBMIT_TOKEN']=''
data["seatType"] = 'O'
data["stationTrainCode"] = sp_item[3]
data["toStationTelecode"] =sp_item[7]
data["train_date"] = str(datetime.datetime.strptime(sp_item[13], '%Y%m%d').strftime('%a %b %d %Y %H:%M:%S GMT+0800'))
data["train_location"] = sp_item[15]
data["train_no"] =sp_item[2] '''
data={
'train_date':str(datetime.datetime.strptime(sp_item[13], '%Y%m%d').strftime('%a %b %d %Y %H:%M:%S GMT+0800')),
'train_no':sp_item[2],#火车编号
'stationTrainCode':sp_item[3],#列车号
'seatType':'O',#座位类型 1是硬座(无座),2是软座,3是硬卧,4是软卧, O 大写字母 是高铁二等座,M是高铁一等座,商务座(9),特等座(P),高级软卧(6)
'fromStationTelecode':sp_item[6],#起始站编号
'toStationTelecode':sp_item[7],#目标站编号
'leftTicket':sp_item[12],
'train_location':sp_item[15],#15项Q6
}
'''
shopdin(data) else:
login()
shoppiao()
break def submitOrderRequest(secretStr):
data = OrderedDict()
data["secretStr"] = secretStr
data["train_date"] = '2018-09-20'
data["tour_flag"] = "dc"
data["purpose_codes"] = "ADULT"
data["query_from_station_name"] ='深圳'
data["query_to_station_name"] = '赤壁'
data["undefined"] = ''
url='https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest'
res=self.post(url,data=data)
print(res.text)
#开始下单
def shopdin(data1):
#获取1个参数
liop=initDc()
#改变Headers
self.headers['Referer'] = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
self.headers['Origin']='https://kyfw.12306.cn'
print(self.headers)
#请求并获取联系人参数
pasdir=PassengerDTOs(liop[0])
print(type(pasdir))
# 二等座 0 (车票类型:ticket_type_codes 成人票1) ,1,张三(passenger_name), 1(证件类型:passenger_id_type_code),320xxxxxx(passenger_id_no),151xxxx(mobile_no),N
passengerTicketStr=data1['seatType']+ ',0,'+pasdir['passenger_type']+','+pasdir['passenger_name']+','+pasdir['passenger_id_type_code']+','+pasdir['passenger_id_no']+','+pasdir['mobile_no']+',N'
#张三(passenger_name),1(证件类型:passenger_id_type_code),320xxxxxx(passenger_id_no),1(passenger_type)_
oldPassengerStr=pasdir['passenger_name']+','+pasdir['passenger_id_type_code']+','+pasdir['passenger_id_no']+','+pasdir['passenger_type']+'_'
data = OrderedDict()
data["_json_att"] =''
data["ed_level_order_num"] ='000000000000000000000000000000'
data["cancel_flag"] ='2'
data["oldPassengerStr"] = oldPassengerStr
data["passengerTicketStr"] = passengerTicketStr
data["randCode"] =''
data["tour_flag"] ='dc'
data["whatsSelect"] ='1'
'''
data={
'cancel_flag':'2',#固定
'ed_level_order_num':'000000000000000000000000000000',#固定
'passengerTicketStr':passengerTicketStr,#联系人
'oldPassengerStr':oldPassengerStr,#联系人
'tour_flag':'dc',#单程
'randCode':'',#空
'whatsSelect':'1',#是否选择了联系人,
}
'''
OrderInfo(data)
data1['REPEAT_SUBMIT_TOKEN']=liop[0]
#提交订单
getQueueCount(data1)
data2= OrderedDict()
data2["_json_att"] =''#空
data2["choose_seats"] =''#空
data2["dwAll"] ='N'#固定
data2["key_check_isChange"] =liop[1]#页面找
data2["leftTicketStr"] = data1['leftTicket']#列车
data2["oldPassengerStr"] =oldPassengerStr#联系人
data2["passengerTicketStr"] =passengerTicketStr#联系人
data2["purpose_codes"] ='00'#
data2["randCode"] =''#随机数 空
data2["REPEAT_SUBMIT_TOKEN"] =liop[0]
data2["roomType"] ='00'#固定
data2["seatDetailType"] ='000'#选铺 暂不支持 默认参数
data2["train_location"] = data1['train_location']#q6
data2["whatsSelect"] ='1'#固定
tijiao(data2)
def tijiao(data):
url='https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue'
res=self.post(url,data=data)
print(res.status_code)
print(res.text)
#获取联系人
def PassengerDTOs(REPEAT_SUBMIT_TOKEN):
data={
'_json_att':'',#空
'REPEAT_SUBMIT_TOKEN':REPEAT_SUBMIT_TOKEN#页面找
}
url='https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs'
res=self.post(url,data=data)
#print(res.text)
passen=res.json().get('data').get('normal_passengers')[1]
print(passen)
return passen #订单页面----获取参数
def initDc():
url='https://kyfw.12306.cn/otn/confirmPassenger/initDc'
res=self.post(url,data={'_json_att':''})
REPEAT_SUBMIT_TOKEN=re.search('globalRepeatSubmitToken = .(.*?).;',res.text,re.S).group(1)
ticketInfoForPassengerForm_name = re.compile(r'var ticketInfoForPassengerForm=(\{.+\})?')
order_request_params_name = re.compile(r'var orderRequestDTO=(\{.+\})?')
re_tfpf = re.findall(ticketInfoForPassengerForm_name, res.text)
re_orp = re.findall(order_request_params_name, res.text)
key_check_isChange=re.search('key_check_isChange.:.(.*?).,',res.text,re.S).group(1)
return [REPEAT_SUBMIT_TOKEN,key_check_isChange]
#选乘客票种提交
def OrderInfo(data):
url='https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo'
res=self.post(url,data=data)
print(res.status_code)
print(res.text)
#提交订单列车余票。
def getQueueCount(data):
url='https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount'
res=self.post(url,data=data)
print(res.status_code)
print(res.text)
def vel_longin_2():
url='https://kyfw.12306.cn/otn/login/checkUser'
requests.packages.urllib3.disable_warnings()
res=self.post(url,data={'_json_att':''})
login_vel=res.json().get('data')['flag'] return login_vel
if __name__ == '__main__':
#yanzhengma()
shoppiao()
vel_longin_2()
Python爬虫之12306-买票器小白源码的更多相关文章
- python爬虫之12306网站--火车票信息查询
python爬虫之12306网站--火车票信息查询 思路: 1.火车票信息查询是基于车站信息查询,先完成车站信息查询,然后根据车站信息查询生成的url地址去查询当前已知出发站和目的站的所有车次车票信息 ...
- Python 多线程、多进程 (一)之 源码执行流程、GIL
Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...
- 一个功能齐全的IOS音乐播放器应用源码
该源码是在ios教程网拿过来的,一个不错的IOS音乐播放器应用源码,这个是我当时进公司时 我用了一晚上写的 图片都是在别的地方扒的,主要是歌词同步,及上一曲,下一曲,功能齐全了 ,大家可以学习一下吧 ...
- rest_framework解析器组件源码流程
rest_framework解析器组件源码流程 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数 ...
- DRF-解析器组件源码解析
解析器组件源码解析 解析器组件源码解析 1 执行request.data 开始找重装的request中的data方法 2 在dispatch找到重装的request def dispatch(self ...
- python爬虫——爬取淘票票正在热映电影
今天正好学习了一下python的爬虫,觉得收获蛮大的,所以写一篇博客帮助想学习爬虫的伙伴们. 这里我就以一个简单地爬取淘票票正在热映电影为例,介绍一下一个爬虫的完整流程. 首先,话不多说,上干货——源 ...
- python爬虫之12306网站--车站信息查询
python爬虫查询车站信息 目录: 1.找到要查询的url 2.对信息进行分析 3.对信息进行处理 python爬虫查询全拼相同的车站 目录: 1.找到要查询的url 2.对信息进行分析 3.对信息 ...
- Python 实现的 12306抢票脚本
Python12306抢票脚本 本脚本使用一个类来实现所有代码,大体上分为以下几个模块及其步骤:- 初始化对象属性(在抢票前进行的属性初始化,包括初始化浏览器模拟对象,个人信息等).- 建立模拟浏览器 ...
- [收藏] 传说中的12306买票插件-chrome专用
12306.cn买票,难死了,登录登录登录... 现在不用了... js插件+chrome浏览器: /* * 12306 Auto Query => A javascript snippet t ...
随机推荐
- 014_zk路径过滤分析
一.线上zk访问延迟特别高需要统计一段时间内的zk写入路径top10,实现如下: #!/usr/bin/env python # -*- coding:utf-8 -*- import re,trac ...
- fullcalendar日历插件的使用并动态增删改查
我上个项目是做了一个关于教育方面的web端页面,其中的课程表就要用到fullcalendar日历插件,刚开始也是不会用,因为以前也没用过,后面也是看官方文档,问同事,最后完成了这个课程表,个人感觉fu ...
- JS Jquery 中 的遍历
$.each()和$().each(),以及forEach()的用法 1.forEach是js中遍历数组的方法,如下 var arr=[1,2,3,4];arr.forEach(functio ...
- 分布式存储ceph——(1)部署ceph
前言: 很多朋友想学ceph,但是开始ceph部署就让初学者举步为艰,ceph部署时由于国外源的问题(具体大家应该懂得),下载和安装软件便会卡住,停止不前.即使配置搭建了国内源后,执行ceph-dep ...
- JVN的理解
写的很不错,通俗易懂:http://www.cnblogs.com/leefreeman/p/7344460.html
- C#、WPF中如何自定义鼠标样式
需求:在C#中如何自定义鼠标样式?在这里可以分两种情况,一种是在winForm,另一种是在WPF中(注意使用的Cursor对象不一样) 解决办法如下: a.首先针对WinForm中,我们可以采用图标加 ...
- java.util.NoSuchElementException错误原因及解决方案
1.原因:没有控制语句导致的迭代器的越界,使得map中的数据无法传入reduce,从而无法把结果传入目标文件中. 在进行Mapreduce实例——WordCount实验时遇到的错误,开始以为是lib包 ...
- dell服务器raid设置
dell服务器raid设置 配置说明: 开机自检按ctrl+R键进入配置界面 如果服务器有raid卡,而不想做磁盘阵列时,需要做单盘RAID0,主要是为了让卡来识别一下硬盘 对raid进行操作很可能会 ...
- pytorch错误:Missing key(s) in state_dict、Unexpected key(s) in state_dict解决
版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 在模型训练时加上: model = nn.DataParallel(model)cudnn.bench ...
- 解决使用Spring Boot、Multipartfile实现上传提示无法找到文件的问题
前言 SpringBoot使用MultiPartFile接收来自表单的file文件,然后进行服务器的上传是一个项目最基本的需求,我以前的项目都是基于SpringMVC框架搭建的,所以在使用Spring ...