使用python多进程爬取全国航班数据与可视化【附代码与excel数据(包含经纬度坐标)】

周末去天津浪了一圈,首先当然是去海边,海风吹着,可带劲了,和面筋歌的心情是一样的。

可带劲了
然后基本是在天津的海滨新区逛逛,参观了大沽口炮台遗址,内心是沉重的。
大沽口炮台遗址

此行本来看航母的,后来由于原因,没能登上航母,甚是遗憾呀,好在看到国产航母舾装完毕,即将进入海试,很激动呀。

废话中的废话不多说,进入正题。

–=============================================–

提示:没用到爬虫架构,请放心食用。
此次爬取的数据源是“哪儿哪儿都不想去网站”(https://link.zhihu.com/?target=http%3A//flight.qunar.com/schedule/alphlet_order.jsp)
,开始时尝试了一下,该网站居然没有采取反爬虫措施,那就so easy了,多进程搞起!

在写爬虫前,我们要熟悉抓取的页面以及url结构规律,然后才能更有效率

例如北京到大同的航班查询url为
http://flight.qunar.com/schedule/fsearch_list.jsp?departure=北京&arrival=大同

那么我们就可以通过这个页面的城市来拼凑出所有的url地址
https://link.zhihu.com/?target=http%3A//flight.qunar.com/schedule/alphlet_order.jsp
大沽口炮台遗址
由于要使用多进程,我这里预先将查询到的所有有航班url写入到txt中,

python环境是python2版本,按照惯例导入需要使用的模块,

1
2
3
4
from bs4 import BeautifulSoup
import re
from multiprocessing import Pool
import sys

然后利用multiprocessing模块进行多进程分任务抓取页面信息,并使用美丽的鲜汤(BeautifulSoup)解析需要的内容存进txt中,信息如下
“出发城市 出发城市y 出发城市x 到达城市 到达城市y 到达城市x 里程(公里) 航班班次 航空公司 机型 起飞时间 降落时间 起飞机场 起飞机场y 起飞机场x 降落机场 降落机场y 降落机场x 准点率 平均误点世间 周一班期 周二班期 周三班期 周四班期 周五班期 周六班期 周日班期 航班有效期开始 航班有效期结束”
该过程我主要写了三个函数来实现业务逻辑:任务分配、包装请求和网页内容获取、页面有效信息提取。
业务逻辑函数
然后基于百度的地理编码API获取出发城市、达到城市、出发机场、到达机场的经纬度坐标。

然后我就获得了全国15074条航班数据。
航班数据

该过程所有代码附后,代码拙劣,见笑见笑。

通过分析获取的数据,我们看到:

目前全国有185个城市或地区有航班
开通航班城市
一共有214个机场用于民用航线的起降
机场
我们都知道,一般飞机场都建在城市郊区或者更远的地方,各城市与当地机场的距离最远的排名Top30如下,PS:生活在这些城市的小伙伴们有木有切身的体会呢?
城市到机场距离Top30
另外,在一万五千次航班中,机型最多的是波音737(中),其次是空客A320(中),国产的新舟60(小)接近150架次
机型
其他的信息,大家可以自行探索了,就不一一赘述了。

然后我们可以使用ArcMap中的xy to line工具生成全国的航班换线图
航线图
由于爬取的数据比较完整,完全可以动态展示。后期有时间会再写一篇教程。

最后附上源码和数据

PS:以上展示或者数据计算可能有误,欢迎指出并交流。

excel数据(包含经纬度坐标)
链接:https://pan.baidu.com/s/149x089ZdxMQXZbymentYwQ 密码:p1rn

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import requests
from bs4 import BeautifulSoup
import re
from multiprocessing import Pool

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
def geturl(url):
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
hbpage = requests.get(url, headers=headers).text
print hbpage
return hbpage
def flyin(city_citys,numm):
print '>>>>>进程%d开始>>>>>'%(numm+1)
# time.sleep(5)
pageinfo = []
for city_city in city_citys:
hbpage=geturl(city_city)
# print hbpage
bg=str(city_city.split('=')[-2]).replace('&arrival','')#始发
dg=city_city.split('=')[-1]#飞往
ft=(bg+dg)
print ft
if BeautifulSoup(hbpage, 'lxml').select('p[class="msg2"]'):
print '此线路无航班'
else:
hblc = BeautifulSoup(hbpage, 'lxml').select('em')[0].get_text()
print hblc
#航班班次 第一列
hbtitle=BeautifulSoup(hbpage,'lxml').select('span[class="title"]')
hbbc1=[]
hkgs1=[]
jixing1=[]
for ht in hbtitle:
hbbc=re.findall(r'\w.?\d*',ht.get_text())[0]#航班班次
hkgs=ht.get_text().split(hbbc)[0]#航空公司
jixing=ht.get_text().split(hbbc)[1]#机型
hbbc1.append(hbbc)
hkgs1.append(hkgs)
jixing1.append(jixing)
#起降时间 第二列
hbtime=BeautifulSoup(hbpage,'lxml').select('span[class="c2"]')[1:]
qfsj1=[]
jlsj1=[]
for qj in hbtime:
qfsj=qj.get_text()[:5]#起飞时间
jlsj=qj.get_text()[5:]#降落时间
qfsj1.append(qfsj)
jlsj1.append(jlsj)

#机场 第三列
hbjc=BeautifulSoup(hbpage,'lxml').select('span[class="c3"]')[1:]
qfjc1=[]
jljc1=[]
for jc in hbjc:
qfjc=jc.get_text().split('机场'.decode('utf-8'))[0]+'机场'.decode('utf-8')#起飞机场
jljc=jc.get_text().split('机场'.decode('utf-8'))[1]+'机场'.decode('utf-8')#降落机场
qfjc1.append(qfjc)
jljc1.append(jljc)

#准点率 第四列
zdl=BeautifulSoup(hbpage,'lxml').select('span[class="c4"]')[1:]
zdl1=[]
wdsj1=[]
for zd in zdl:
zdlv=zd.get_text().split('%')[0]+'%'
wdsj=zd.get_text().split('%')[1]
zdl1.append(zdlv)
wdsj1.append(wdsj)


#班期 第五列
bq=BeautifulSoup(hbpage,'lxml').select('span[class="c5"]')[1:]
# xx=[]
duty1 = []
for xq in bq:
week=re.split('\">\d</span>',str(xq))[:-1]
week1=[]
ii=1
for day in week:
if ii==1:
dd='周一'
elif ii==2:
dd = '周二'
elif ii==3:
dd = '周三'
elif ii==4:
dd = '周四'
elif ii==5:
dd = '周五'
elif ii==6:
dd = '周六'
elif ii==7:
dd = '周日'
if day[-4:]=='blue':
duty='%s有班期'%dd
else:
duty='%s没有班期'%dd
ii+=1
week1.append(duty)
duty1.append(week1)

#班期有效期 第七列
bqyxq = BeautifulSoup(hbpage, 'lxml').select('span[class="c7"]')[1:]
qs1=[]
js1=[]
for yxq in bqyxq:

yxs=yxq.get_text()[:10]#起始
yxe=yxq.get_text()[:10]#结束
qs1.append(yxs)
js1.append(yxe)

print hbbc1
for li in range(len(hbbc1)):
print '标记'
pageinfo.append(bg + ',' + dg + ',' + hblc + ',' + hbbc1[li] + ',' + hkgs1[li] + ',' + jixing1[li] + ',' + qfsj1[li] + ',' + jlsj1[li] + ',' + qfjc1[li] + ',' + jljc1[li] + ',' + zdl1[li] + ',' + wdsj1[li] + ',' + duty1[li][0] + ',' + duty1[li][1] + ',' + duty1[li][2] + ',' +duty1[li][3] + ',' + duty1[li][4] + ',' + duty1[li][5] + ',' + duty1[li][6] + ',' + qs1[li] + ',' + js1[li] + '\n')
print bg + ',' + dg + ',' + hblc + ',' + hbbc1[li] + ',' + hkgs1[li] + ',' + jixing1[li] + ',' + qfsj1[li] + ',' + jlsj1[li] + ',' + qfjc1[li] + ',' + jljc1[li] + ',' + zdl1[li] + ',' + wdsj1[li] + ',' + duty1[li][0] + ',' + duty1[li][1] + ',' + duty1[li][2] + ',' +duty1[li][3] + ',' + duty1[li][4] + ',' + duty1[li][5] + ',' + duty1[li][6] + ',' + qs1[li] + ',' + js1[li] + '\n'
print pageinfo
return pageinfo

def urlsplit(urls,jiange):
urli=[]
for newj in range(0,len(urls),jiange):
urli.append(urls[newj:newj+jiange])
return urli
if __name__=='__main__':
finalre=[]
files = open(r'C:\Users\username\Desktop\url.txt', 'r')
urls=[]
for url in files.read().split():
urls.append(url)
urlss=urls[:6]
urlll=urlsplit(urlss,2)
p = Pool(2)
result=[]
for i in range(len(urlll)):
result.append(p.apply_async(flyin,args=(urlll[i],i)))
p.close()
p.join()
print result
for result_i in range(len(result)):
print result[result_i]
fin_info_result_list = result[result_i].get().decode('utf-8')
finalre.extend(fin_info_result_list)
filers=open(r'C:\Users\username\Desktop\url55.txt','a+')
for fll in finalre:
filers.write(str(fll).encode('utf-8'))