小白教程:Python爬取12306车票信息以及后期数据处理 您所在的位置:网站首页 爬虫官网 小白教程:Python爬取12306车票信息以及后期数据处理

小白教程:Python爬取12306车票信息以及后期数据处理

2024-03-05 01:51| 来源: 网络整理| 查看: 265

步骤一:

寻找想爬取数据的来源网站(即12306),直接进入官网就可以了https://kyfw.12306.cn

步骤二:

因为我们是爬取车票信息,所以直接点击单程车票查询就可了 F12启动chrome开发者模式,然后按照下面图片里的步骤操作

在这里插入图片描述

步骤三: 然后就会发现一个请求,接下来,我们点击这条请求,查看请求信息,可以发现包括Headers,Proview,Responsr,Cookies,Timing等信息,以及GET请求的url

在这里插入图片描述 下面是请求网络路径(url),经过多次,不同车站的搜索,我们可以发现,里面参数发生改变的只有,始发地、终点站、出发时间等(但是地名都是大写字母简称)

在这里插入图片描述

步骤四: 接下来,我们就部署链接,先把站点简称爬取到本都(我是爬取到本地,然后顺便转存到tomcat服务器,为后面检索关键词、制作词云图做准备)

''' 文件名:_get_station.py 如果先复制我的代码,请命名与我一致,因为后面文件里要引用这个模块 ''' #引用request模块 -- 网络请求模块 import requests #引用re模块 -- 正则表达式 import re #引用shutil模块,进行文件复制转存,直接存储在tomcat服务器中 import shutil #引用esayGui模块,制作弹窗 import easygui as ea #Function() -- 获取12306站点信息 def get_station(): ''' @url:12306站点信息存储文件地址(即网络服务器文件目录) :return: station ''' url = 'https://www.gn720.com/file/station_name.js' #爬取数据,并以txt问本形式返回 response = requests.get(url).text #用正则表达式匹配出name和referred(站点列表和简称列表) name = re.findall(r'.*?\|(.*?)\|.*?\|.*?\|.*?\|.*?',response) referred = re.findall(r'.*?\|.*?\|(.*?)\|.*?\|.*?\|.*?',response) #用zip打包信息,将信息打包成由元组构成的列表,在转成字典存储到本地文件里 ''' @zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 ''' station = dict(zip(name,referred)) ''' 1.以二进制形式打开新的文件,本地有文件就打开,没有就创建一个新的 2.向文件写入获取内容 3.关闭文件流 ''' file = open('station.txt','w',encoding='utf-8') file.write(str(station)) file.close() #将文件转存到tomcats服务器中 returnString = shutil.move('C:\\Desktop\\Desktop\\实训\\Demo\\_Python_12306\\station.txt','G:\\tomcat8\\apache-tomcat-8.5.38\\webapps\\_localhostServer_') #弹窗提示:站点信息爬取完成,并且已经存储在本地 ea.msgbox(msg='----------------12306站点信息已经爬取完成----------------\n\n' '---------------------成功上传tomcat---------------------\n\n' 'Path:http://127.0.0.1:9999/_localhostServer_/station.txt\n\n\n' '-----------------稍后可查看关键词、词云图----------------\n\n',title='运行提示!',ok_button='查看关键字检索') #@return: return station

这段代码可以直接复制运行,因为不涉及到其他模块、文件的引用,如果你只想存储到本地,或者没有tomcat,记得把转存到服务器部分的代码注释掉~

运行上面代码,在当前文件夹里面应该会出现一个文本文件station.txt,打开,里面是所有站点名称,以及简称构成的字典key为站点中文名称,value为简称,像这样子:

在这里插入图片描述

''' 这个station.txt文件的作用: 1.稍后,我们会用这个字典,匹配出我们输入的汉字站点,转成简称,作为请求参数; 2.拿到响应数据,由于站点信息是我们看不懂的英文简称,用其转成中文,再做回显; '''

步骤五:

下面我们就可以构造链接了,要一下这个请求的响应结果: 可以发现响应结果的形式是这样的:(如下)

在这里插入图片描述

步骤六:

构造链接,抓数据

''' 文件名:_get_tickets.py ''' #以用request模块 import requests #引用json模块 import json #取得编码模块 from urllib.parse import urlencode ''' @headers:request请求的请求头 请求信息: F12,启动开发者模式,在参数里就可以找到请求头信息 ''' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', 'Cookie': 'JSESSIONID=85ABACBDDEC5EF0D3F4390E49C235DCD; BIGipServerotn=569377290.24610.0000; BIGipServerpool_passport=183304714.50215.0000; RAIL_EXPIRATION=1584746738988; RAIL_DEVICEID=c_HPEh5qqB0-onW7FlqB5a2T-w9tiHZ95ePILEBaXLQ3Nj84j7a4PV1ezmRs7O57oEVHFp3JcbAEi_s3qJb_bqey5sGYiQ-RmKrzrZ0wzbndDLKGidKjF1l5UZ4FjwqSTdhbaSx8ds-5RgV-KxQrm0mINenavAb3; route=c5c62a339e7744272a54643b3be5bf64; _jc_save_fromStation=%u5317%u4EAC%2CBJP; _jc_save_fromDate=2020-03-17; _jc_save_toDate=2020-03-17; _jc_save_wfdc_flag=dc; _jc_save_toStation=%u5929%u6D25%2CTJP' } ''' @data_dict:key_value: 经过多次的请求测试,发现get参数改变的都是出发地,到达地,出发时间 所以确定字典有三个键值对 即:fromwhere,towhere,startime ''' def get_tickets(fromwhere,towhere,startime): #数据字典 data = { 'leftTicketDTO.train_date': startime, 'leftTicketDTO.from_station': fromwhere, 'leftTicketDTO.to_station': towhere, 'purpose_codes': 'ADULT', } #构造请求链接:地址 + 参数 (startime,fromwhere,wowhere) request_url = 'https://kyfw.12306.cn/otn/leftTicket/query?' + urlencode(data) #利用json.loads()将其他(这里是文本类型)类型的数据转化成Python类型(这里是转成字典) response = json.loads(requests.get(request_url,headers=headers).text) #构造结果字典 result = response['data']['result'] #创建新的字典,并且遍历字典,除去列车停运数据 new_list = [] for item in result: if not '列车停运' in item: new_list.append(item) else: pass #@return:dict{} return new_list

别慌!!! 有些小伙伴们看到代码是不是有点懵,我来说一下这里面乱七八糟的东西怎么来的,走着~!

解释1:headers :这个是网络请求的请求头,这里面大致包括'User-Agent'和'Cookie',这东西在这:

User-Agent: 在这里插入图片描述 Cookie: 在这里插入图片描述 解释2:urlencode()方法

接受参数形式为:[(key1, value1), (key2, value2),...] 和 {'key1': 'value1', 'key2': 'value2',...} 返回的是形如key2=value2&key1=value1字符串。

解释3:下面字典中键的名字怎么来的

data = { 'leftTicketDTO.train_date': startime, 'leftTicketDTO.from_station': fromwhere, 'leftTicketDTO.to_station': towhere, 'purpose_codes': 'ADULT', }

把鼠标悬停在这,你就看见了~ 在这里插入图片描述 步骤七:

这个_get_tickets.py写完,打印一下返回值:

在这里插入图片描述 乍一看有点懵,仔细看,在“预定”之后其实就是我们想要的东西 所以接下来,我们直接用正则表达式,把我们想要的东西搞下来

''' 文件名:Decrypt.py ''' #对数据进行解码 #引用re模块 -- 正则表达式 import re def decrypt(string): #指定匹配规则 reg = re.compile('.*?\|预订\|.*?\|(.*?)\|(.*?)\|(.*?)\|.*?\|.*?\|(.*?)\|(.*?)\|(.*?)\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|.*?\|.*?\|.*?\|.*') ''' 正则匹配 [0]:匹配所有数据 ''' result = re.findall(reg,string)[0] #返回匹配结果 return result

步骤八:

最后一步就是通过main方法,按照一定的逻辑,调用上面的三个函数,或者再加上一下回显修饰

这里其实可以有很多信息,如:各种座位的余票,可不可以预定等;但这里我解码出六项数据,做回显,【车次】,【始发地】,【终点站】,【出发时间】,【到达时间】,【历时】,如果你需要其他的,可以自己加上去。

这里代码简单,不解释啦,直接贴上~

''' 文件名:mian.py ''' from _get_station import get_station from _get_tickets import get_tickets from GUI import inputInfo from Decrypt import decrypt from texttable import Texttable import easygui as g import sys import datetime #获取信息函数 def get_message(): _inputInfo = inputInfo() fw = _inputInfo[0] tw = _inputInfo[1] st = _inputInfo[2] if st == '': #如果没有输入时间,则当前日期为默认时间 st = datetime.date.today() #锁定参数 return fw,tw,st else: today = datetime.date.today() date = str(today).split('-') list = st.split('-') if int(list[0]) int(date[0]): exit("输入的年份不在我的查询范围之内") else: if int(list[1]) int(date[1])+1: exit("你输入的月份不在我的查询范围之内") else: if int(list[2])


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有