技术标签: python
步骤一:
寻找想爬取数据的来源网站(即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]) or int(list[0]) > int(date[0]):
exit("输入的年份不在我的查询范围之内")
else:
if int(list[1]) < int(date[1]) or int(list[1]) > int(date[1])+1:
exit("你输入的月份不在我的查询范围之内")
else:
if int(list[2]) < int(date[2]):
exit("你输入的日期不在我的查询范围之内")
else:
if int(list[1]) < 10 and int(list[1][0]) != 0:
list[1] = '0' + list[1]
if int(list[2]) < 10 and int(list[2][0]) != 0:
list[2] = '0' + list[2]
return fw,tw,list[0] + '-' + list[1] + '-' + list[2]
message = get_message()
def run():
#获取站点信息
station_name = get_station()
g.msgbox(msg='request Static : request success.\n\n'
'数据表生成成功',title='运行提示',ok_button='打印数据表')
try:
#result_list = []
fromwhere = station_name[message[0]]
towhere = station_name[message[1]]
startime = message[2]
#get_tickets()获得车票信息列表
tickets = get_tickets(fromwhere,towhere,startime)
print('===============================================================================')
print('carNum'.center(8, '-'), end='')
print('{0:{1}^9}'.format('始发站', chr(12288)), end='')
print('{0:{1}^9}'.format('目的地', chr(12288)), end='')
print('{0:{1}^9}'.format('sTime', chr(12288)), end='')
print('{0:{1}^9}'.format('aTime', chr(12288)), end='')
print('{0:{1}^9}'.format('bTime', chr(12288)))
print('===============================================================================')
for item in tickets:
#利用decrypt()函数解码result(网络请求里的result),解码后生成列表,存储到result中
result = list(decrypt(item))
#遍历站点信息字典,存储到new_dict新字典里
new_dict = {
v: k for k, v in station_name.items()}
# ----------result_test-----------#
#结果:
#list列表:
#['G102', 'AOH', 'VNP', '06:26', '12:29', '06:03', '有', '有', '13']
#print(result)
#-----------new_dict_test----------#
#结果:
#dict字典:
#{'VAP': '北京北', 'BOP': '北京东'...}
#print(new_dict)
'''
将出发地、到达地的简称转换成中文
'''
#result列表准备就绪:
result[1] = new_dict[result[1]]
result[2] = new_dict[result[2]]
rightWidth = 8
print(result[0].center(rightWidth, '-'),end = '')
print('{0:{1}^9}'.format(result[1], chr(12288)),end = '')
print('{0:{1}^9}'.format(result[2], chr(12288)),end = '')
print('{0:{1}^9}'.format(result[3], chr(12288)),end = '')
print('{0:{1}^9}'.format(result[4], chr(12288)),end = '')
print('{0:{1}^9}'.format(result[5], chr(12288)))
print('-------------------------------------------------------------------------------')
except KeyError as k:
print("I can't find the city %s"%k)
if __name__ == '__main__':
run()
按照我的步骤一步一步,肯定是可以运行的,亲测有效
文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态
文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境
文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn
文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker
文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机
文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk
文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入
文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。 Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。
文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动
文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计
文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;gt;Jni-&amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图
文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法