seal66yx

一、选题的背景

  本次选题,我想从我的大学所在城市泉州入手,分析泉州公交分布,了解绿色出行对人们生活的意义和人们对绿色出行的重视。

  美丽泉州是人民群众的福祉。为贯彻落实《国务院关于实施健康中国行动的意见》,促进健康环境建设,为推进国家生态文明试点示范市建设,深化全国文明城市、卫生城市创建多作贡献。泉州市号召全市百姓积极践行绿色出行、低碳出行、文明出行。而城市公共交通是城市基础设施的重要组成部分,在我国经济发展、城市建设和社会生活中占有重要地位,它直接关系着城市的经济发展与居民生活,对城市经济具有全局性、先导性的影响。

 

二、主题式网络爬虫设计方案

1.主题式网络爬虫名称

基于高德开放平台|高德地图API爬取泉州公交有关数据并进行分析

2.主题式网络爬虫爬取的内容与数据特征分析

通过高德地图开放平台爬取有关的公交线路,并提取标签整理成数据集csv文件进行分析,分析主要通过公交线路,区间站点,全程长度,站点经纬度来对泉州公交普及分析。

3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)

1)实现思路

1.首先是获取数据集,具体是从高德地图API(https://lbs.amap.com/)获取key来获取,关于参数和标签头文件名获取,感谢高德开放平台下的开发指南提供了参数名

2.取数据后对数据进行清洗整理进csv文件。

3.对csv文件进行分析及数据可视 化。

(2)技术难点

1.对数据的切片和分布读取

2.对数据进行清洗和处理

3.对可用数据的可视化处理

4.对冗余数据的处理

 

三、主题页面的结构与特征分析

1.主题页面的结构与特征分析

 

 

2.节点(标签)查找方法与遍历方法 (必要时画出节点树结构)

由于高德地图开放平台下的开发指南已经给出,所以不需要再寻找。

 

2.节点(标签)查找方法与遍历方法 (必要时画出节点树结构)

由于高德地图开放平台下的开发指南已经给出,所以不需要再寻找。

 

四、网络爬虫程序设计(60 分) 爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后 面提供输出结果的截图。

(1)数据爬取与采集

1. 先对url进行测试,查看是否能够正常返回数据

 1 #爬取网页异常处理的通用框架
 2 import requests
 3 url = \'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=ad243f840dbda301f753ffd0436035b6&output=json&city={}&offset=1&keywords={}&platform=JS\'
 4 
 5 def requests_caputure():
 6     try:
 7         r=requests.get(url,timeout=30)#请求超时时间为30秒
 8         r.raise_for_status()#如果状态不是200,则引发异常
 9         r.encoding=r.apparent_encoding #配置编码
10         return r.text
11     except:
12         return "产生异常"
13 
14 if __name__ == \'__main__\':
15     response=requests_caputure()
16     print(response[:100])

运行结果

2.对url进行爬取泉州公交线路的始发站、终点站、行驶路径(行车轨迹)、站点名称和坐标、行驶距离等与公交车有关的基本信息,并将其保存到Execl表格中。

 1 #导入爬虫所需的库
 2 import requests
 3 import json
 4 import pandas as pd
 5 import time
 6 
 7 #用于记录爬取公交线路所需要的时间函数
 8 def record_time(flag):
 9     if flag==0:
10         global t0
11         t0=time.time()
12     else:
13         t1=time.time()
14         print("用时:%.2fs"%(t1-t0))  
15     print(time.strftime(\'%Y-%m-%d %H:%M:%S\',time.localtime(time.time())))
16 
17 #获取公交基本信息 
18 #具体参考:高德地图api 路径规划-API文档-开发指南 https://lbs.amap.com/api/webservice/guide/api/direction#bus_list
19 def get_station(cityname,line):
20     global bus_num
21     #获取当前公交线路数据 利用高德开放平台创建适用web端的key,爬取公交站点信息
22     url = \'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=ad243f840dbda301f753ffd0436035b6&output=json&city={}&offset=1&keywords={}&platform=JS\'.format(cityname,line)
23     r = requests.get(url).text  #请求文本内容
24     rt = json.loads(r) #将json格式数据转换为字典
25     try:
26         #读取当前公交线路主要信息
27         dt = {}  #先定义一个dt数据集
28         dt[\'公交线路\'] = rt[\'buslines\'][0][\'name\'] #公交线路名字
29         dt[\'始发站点\'] = rt[\'buslines\'][0][\'start_stop\'] #始发站
30         dt[\'终点站\'] = rt[\'buslines\'][0][\'end_stop\'] #终点站
31         dt[\'区间站点\'] = rt[\'buslines\'][0][\'bounds\'] #行车区间(非始发站,终点站坐标)
32         dt[\'全程长度\'] = rt[\'buslines\'][0][\'distance\'] #全程长度
33         
34         #获取沿途站点站名、对应坐标和“第几站”信息
35         station_name = []
36         station_coords = []
37         station_sequence = []
38         
39         for st in rt[\'buslines\'][0][\'busstops\']:
40             station_name.append(st[\'name\'])
41             station_coords.append(st[\'location\'])
42             station_sequence.append(st[\'sequence\'])
43         
44         dt[\'沿途站点名\'] = station_name #沿途站点名
45         dt[\'沿途站点坐标\'] = station_coords #沿途站点坐标
46         dt[\'沿途站点第几站\'] = station_sequence #沿途站点第几站
47         
48         bus_num+=1 #有效公交数+1
49         
50         return pd.DataFrame(dt)  #返回pd.DataFrame()类型
51          
52     except: #try语句部分出错进入此部分(一般为站点名错误)
53         print(\'没有{}公交\'.format(line)) #输出没有的公交线路名字
54         return pd.DataFrame([])  #返回空的pd.DataFrame类型
55 
56 #获取当前城市所有公交基本信息:线路名、行车区间、全程长度、沿途站点及坐标
57 def Bus_info(city,for_num):
58     all_bus=pd.DataFrame()
59     for i in range(1,for_num+1):  
60         all_bus=pd.concat([all_bus,get_station(city,str(i)+\'\')])  #不加这个\'路\'可能优先获取地铁
61     print("Bus_info函数遍历{}前{}路公交,有效公交线路数为:{}个".format(city,for_num,bus_num))
62     all_bus.to_csv("{}前{}路公交(有效线路数:{})基本信息.csv".format(city,for_num,bus_num),encoding=\'utf-8-sig\')
63 
64 
65 if __name__=="__main__":
66     record_time(0)#用于记录开始时间
67     
68     bus_num=0  #全局变量,计算有效遍历的公交数
69     city=\'泉州\' #需要查询公交信息的城市
70     for_num=1000 #遍历的线路数[1路,for_num路],通常公交线路数小于1000,具体可参考8684等网站
71     Bus_info(city,for_num)
72 
73     record_time(1)#用于记录结束时间并输出用时
74 
75  

运行结果

csv文件如下

 

 

(2)文本分析(可选):jieba 分词、wordcloud 的分词可视化

 1. #绘制词云,查看出现最多的站点

 1  # 绘制词云,查看出现最多的站点
 2 import jieba
 3 from pylab import *
 4 from wordcloud import WordCloud
 5 df = pd.read_csv(\'C:/Users/bb/python-jupyter noteboook/泉州前1000路公交(有效线路数:120)基本信息.csv\')
 6 text = \'\'  
 7 for line in df[\'沿途站点名\']:  
 8     text += line  
 9 # 使用jieba模块将字符串分割为单词列表
10 cut_text = \' \'.join(jieba.cut(text))
11 color_mask = imread(\'C:/Users/bb/python-jupyter noteboook/66.jpg\')  #设置背景图
12 cloud = WordCloud(
13     
14     background_color = \'white\',
15     # 对中文操作必须指明字体
16     font_path=\'C:\windows\Fonts\STZHONGS.TTF\',
17     mask = color_mask,
18     max_words = 50,
19     max_font_size = 200
20     ).generate(cut_text)
21  
22 # 保存词云图片
23 cloud.to_file(\'qzword1cloud.jpg\')
24 plt.imshow(cloud)
25 plt.axis(\'off\')
26 plt.show()

运行结果

 2.循环泉州市的1000路以内的公交,获取这些线路的:路线名、行车区间、路程长度、站点数、区间直线距离等数据,并计算出这些公交线路的平均长度、平均站点数、平均站距。

 1 import requests
 2 import json
 3 import pandas as pd
 4 import time
 5 from math import sin, asin, cos, radians, sqrt
 6 #获取公交信息:线路名、行车区间(坐标)、路程、行车区间直线距离等
 7 def Bus_inf(city,line):
 8     global bus_num  #全局变量,用于计算公交数目
 9     try:
10         #获取数据
11         url = \'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS\'.format(city,line)
12         r = requests.get(url).text
13         rt = json.loads(r)
14         #读取当前公交线路基本信息
15         dt = {}
16         dt[\'line_name\'] = rt[\'buslines\'][0][\'name\'] #公交线路名字
17         dt[\'bounds\'] = rt[\'buslines\'][0][\'bounds\'] #行车区间(不是始发站,终点站坐标!!!)
18         dt[\'distance\'] = float(rt[\'buslines\'][0][\'distance\']) #全程长度
19         dt[\'station\'] = int(rt[\'buslines\'][0][\'busstops\'][-1][\'sequence\']) #全程站点数(包括始发站和终点站)
20         dt[\'station_dis\'] = dt[\'distance\']/(dt[\'station\']-1) #该路线站距
21         #计算直线系数 和 非直线系数=1/直线系数
22         #以下为两套求直线的方法:(1)求行车区间 (2)求始发站到终点站距离
23         lng1,lat1 =rt[\'buslines\'][0][\'bounds\'].split(\';\')[0].split(\',\')  
24         lng2,lat2 =rt[\'buslines\'][0][\'bounds\'].split(\';\')[1].split(\',\')  
25         dt[\'straight\'] =  Geodistance(float(lng1),float(lat1),float(lng2),float(lat2)) #计算区间bounds的直线距离
26         lng1,lat1 = rt[\'buslines\'][0][\'busstops\'][0][\'location\'].split(\',\')  #始发站坐标
27         lng2,lat2 = rt[\'buslines\'][0][\'busstops\'][-1][\'location\'].split(\',\') #终点站坐标
28         dt[\'straight2\'] =  Geodistance(float(lng1),float(lat1),float(lng2),float(lat2)) #始发站到终点站的直线距离
29         #首尾距离小于1km即认为存在上下行(环形线路)
30         if  dt[\'straight2\']<1.0:
31             print(dt[\'line_name\'])
32             dt[\'straight\']=dt[\'straight\']*2 #环形线直线距离乘2
33             lng1,lat1 = rt[\'buslines\'][0][\'busstops\'][0][\'location\'].split(\',\')  #始发站坐标
34             lng2,lat2 = rt[\'buslines\'][0][\'busstops\'][int(dt[\'station\']/2)][\'location\'].split(\',\') #中间站坐标
35             dt[\'straight2\'] = Geodistance(float(lng1),float(lat1),float(lng2),float(lat2))*2 #始发站到中间站点距离且需要*2
36         
37         dt[\'straight_dis\'] = dt[\'straight\']/dt[\'distance\']      #直线系数1=直线长度/路程长度 (0,1]
38         dt[\'non_straight_dis\'] = dt[\'distance\']/dt[\'straight\']  #非直线系数1=路程长度/直线长度 [1,∞)
39         dt[\'straight_dis2\'] = dt[\'straight2\']/dt[\'distance\']      #直线系数2=直线长度/路程长度 (0,1]
40         dt[\'non_straight_dis2\'] = dt[\'distance\']/dt[\'straight2\']  #非直线系数2=路程长度/直线长度 [1,∞)
41 
42         bus_num+=1 #有效公交数+1
43         return pd.DataFrame(dt,index=[bus_num]) #下标index为“第几条公交线”
44     except:
45         #print(\'没有{}公交\'.format(line)) #正常情况下,这条语句不会执行
46         return pd.DataFrame()  #读取数据失败,返回空的
47 
48 def Bus_analysis(bus_info):
49     print(\'公交线路的平均长度:{:.6f} km\'.format(bus_info["distance"].mean())) 
50     print(\'公交线路的平均站点数:{:.6f} 个\'.format(bus_info[\'station\'].mean()))
51     print(\'公交线路的平均站距1为:{:.6f} km/站\'.format(bus_info["distance"].sum()/(bus_info[\'station\'].sum()-bus_num)))
52     print(\'公交线路的平均直线系数(区间距离):{:.6f}\'.format(bus_info[\'straight\'].sum()/bus_info["distance"].sum()))
53     print(\'公交线路的平均非直线系数(区间距离):{:.6f}\'.format(bus_info["distance"].sum()/bus_info[\'straight\'].sum()))
54     print(\'公交线路的平均直线系数(首位距离):{:.6f}\'.format(bus_info[\'straight2\'].sum()/bus_info["distance"].sum()))
55     print(\'公交线路的平均非直线系数(首位距离):{:.6f}\'.format(bus_info["distance"].sum()/bus_info[\'straight2\'].sum()))
56     
57 if __name__=="__main__":
58     t0=time.time()
59     
60     bus_num=0  #设置全局变量数值(通常默认就是0)
61     city=\'泉州\' #需要查询公交信息的城市
62     for_num=120 #遍历的线路数[1路,for_num路],通常公交线路数小于1000,具体可参考8684等网站
63     all_buslines=pd.DataFrame()     
64     for i in range(1,for_num+1):
65         all_buslines=pd.concat([all_buslines,Bus_inf(city,str(i)+\'\')])  #不加这个\'路\'可能优先获取地铁
66     
67     print("Bus_info函数遍历{}前{}路公交,有效公交线路数为:{}个的情况下:".format(city,for_num,bus_num))
68     Bus_analysis(all_buslines)
69     
70     all_buslines.to_csv("{}前{}路公交(有效线路数:{})基本信息.csv".format(city,for_num,bus_num),encoding=\'utf-8-sig\')
71     
72     t1=time.time()
73     print("用时:%.2fs"%(t1-t0))

运行结果

(3)数据分析与可视化(例如:数据柱形图、直方图、散点图、盒图、分布图)

1.基于经纬度做泉州公交站点分布散点图

 

 1 #导入库
 2 import numpy as np
 3 import scipy as sp
 4 import pandas as pd
 5 import matplotlib
 6 import matplotlib.pyplot as plt
 7 from scipy.optimize import leastsq
 8 import random
 9 import matplotlib as mpl
10 df = pd.read_csv(\'C:/Users/bb/python-jupyter noteboook/泉州前1000路公交(有效线路数:120)基本信息.csv\')   #导入泉州公交数据集
11 
12 df[[\'经度\',\'纬度\']] = df[\'沿途站点坐标\'].str.split(\',\', n=1, expand=True)    #因为爬取的经纬度在同一格,但是要分开,故采用切片。
13 df[\'经度\']=df[\'经度\'].astype(float)   #转换双精度类型
14 df[\'纬度\'] = df[\'纬度\'].astype(float)
15 
16 #设置x轴数据,有点冗余这一步,下一步也是
17 x_data =df[\'经度\']      
18 y_data = df[\'纬度\']
19 
20 #设置坐标点颜色
21 colors = [\'#FF0000\', \'#0000CD\', \'#00BFFF\', \'#008000\', \'#FF1493\', \'#FFD700\', \'#FF4500\', \'#00FA9A\', \'#191970\', \'#9932CC\'] 
22 #随机坐标颜色
23 colors = [random.choice(colors) for i in range(len(x_data))]
24 mpl.rcParams[\'font.family\'] = \'SimHei\'                        #用来正常显示中文标签
25 plt.style.use(\'ggplot\')                                       #利用matplotlib绘图设置背景,用plt.style.available查出可用样式列表
26 #plt.style.available
27 # 设置大小
28 plt.figure(figsize=(18, 10), dpi=200)
29 # 绘制散点图  经度  纬度  传进去   设置 颜色  点的大小
30 plt.scatter(x_data, y_data, marker="o", s=30., c=colors)
31  
32 # 添加描述信息 x轴 y轴 标题
33 plt.xlabel("经度")
34 plt.ylabel("纬度")
35 plt.title("泉州市公交站点分布情况")
36 plt.savefig(\'经纬度散点图.png\')
37 plt.show()

 

运行结果

 2.可视化查看泉州公交线路的全程长度对比

 1 #导入库
 2 import numpy as np
 3 import scipy as sp
 4 import pandas as pd
 5 import matplotlib
 6 import matplotlib.pyplot as plt
 7 from scipy.optimize import leastsq
 8 
 9 df = pd.read_csv(\'C:/Users/bb/python-jupyter noteboook/泉州前1000路公交(有效线路数:120)基本信息.csv\')
10 chinese=matplotlib.font_manager.FontProperties(fname=\'C:\Windows\Fonts\simsun.ttc\') #设置正常读取表格中中文名
11 
12 # 创建figure对象,设置画布大小
13 
14 plt.figure(figsize=(50,40))
15 
16 Xi=np.array(df[\'公交线路\'])
17 Yi=np.array(df[\'全程长度\'])
18 
19 from pylab import *   #从pylab中导入所有的非私有类,函数,全局变量等,* 代表所有,
20 mpl.rcParams[\'font.sans-serif\'] = [\'SimHei\']
21 mpl.rcParams[\'axes.unicode_minus\'] = False
22 
23 #绘制矩形图,x,y轴数据,表名,颜色
24 plt.barh(Xi, Yi, label="公交线路长度统计",color=[\'b\',\'orange\',\'g\',\'r\',\'purple\',\'#FF4500\', \'#00FA9A\',\'Pink\',\'#00BFFF\',\'y\',\'cyan\'])
25 
26 plt.title(\'泉州公交路线路长柱形图\')
27 plt.xlabel(\'总路程(km)\')
28 plt.ylabel(\'公交号\')   
29 plt.show()

运行结果

 3.将以上各部分的代码汇总,附上完整程序代码

  1 #爬取网页异常处理的通用框架
  2 import requests
  3 url = \'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=ad243f840dbda301f753ffd0436035b6&output=json&city={}&offset=1&keywords={}&platform=JS\'
  4 
  5 def requests_caputure():
  6     try:
  7         r=requests.get(url,timeout=30)#请求超时时间为30秒
  8         r.raise_for_status()#如果状态不是200,则引发异常
  9         r.encoding=r.apparent_encoding #配置编码
 10         return r.text
 11     except:
 12         return "产生异常"
 13 
 14 if __name__ == \'__main__\':
 15     response=requests_caputure()
 16     print(response[:100])
 17 
 18 
 19 #-------------------------------------------------------------------
 20 import requests
 21 import json
 22 import pandas as pd
 23 import time
 24 from math import sin, asin, cos, radians, sqrt
 25 #获取公交信息:线路名、行车区间(坐标)、路程、行车区间直线距离等
 26 def Bus_inf(city,line):
 27     global bus_num  #全局变量,用于计算公交数目
 28     try:
 29         #获取数据
 30         url = \'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS\'.format(city,line)
 31         r = requests.get(url).text
 32         rt = json.loads(r)
 33         #读取当前公交线路基本信息
 34         dt = {}
 35         dt[\'line_name\'] = rt[\'buslines\'][0][\'name\'] #公交线路名字
 36         dt[\'bounds\'] = rt[\'buslines\'][0][\'bounds\'] #行车区间(不是始发站,终点站坐标!!!)
 37         dt[\'distance\'] = float(rt[\'buslines\'][0][\'distance\']) #全程长度
 38         dt[\'station\'] = int(rt[\'buslines\'][0][\'busstops\'][-1][\'sequence\']) #全程站点数(包括始发站和终点站)
 39         dt[\'station_dis\'] = dt[\'distance\']/(dt[\'station\']-1) #该路线站距
 40         #计算直线系数 和 非直线系数=1/直线系数
 41         #以下为两套求直线的方法:(1)求行车区间 (2)求始发站到终点站距离
 42         lng1,lat1 =rt[\'buslines\'][0][\'bounds\'].split(\';\')[0].split(\',\')  
 43         lng2,lat2 =rt[\'buslines\'][0][\'bounds\'].split(\';\')[1].split(\',\')  
 44         dt[\'straight\'] =  Geodistance(float(lng1),float(lat1),float(lng2),float(lat2)) #计算区间bounds的直线距离
 45         lng1,lat1 = rt[\'buslines\'][0][\'busstops\'][0][\'location\'].split(\',\')  #始发站坐标
 46         lng2,lat2 = rt[\'buslines\'][0][\'busstops\'][-1][\'location\'].split(\',\') #终点站坐标
 47         dt[\'straight2\'] =  Geodistance(float(lng1),float(lat1),float(lng2),float(lat2)) #始发站到终点站的直线距离
 48         #首尾距离小于1km即认为存在上下行(环形线路)
 49         if  dt[\'straight2\']<1.0:
 50             print(dt[\'line_name\'])
 51             dt[\'straight\']=dt[\'straight\']*2 #环形线直线距离乘2
 52             lng1,lat1 = rt[\'buslines\'][0][\'busstops\'][0][\'location\'].split(\',\')  #始发站坐标
 53             lng2,lat2 = rt[\'buslines\'][0][\'busstops\'][int(dt[\'station\']/2)][\'location\'].split(\',\') #中间站坐标
 54             dt[\'straight2\'] = Geodistance(float(lng1),float(lat1),float(lng2),float(lat2))*2 #始发站到中间站点距离且需要*2
 55         
 56         dt[\'straight_dis\'] = dt[\'straight\']/dt[\'distance\']      #直线系数1=直线长度/路程长度 (0,1]
 57         dt[\'non_straight_dis\'] = dt[\'distance\']/dt[\'straight\']  #非直线系数1=路程长度/直线长度 [1,∞)
 58         dt[\'straight_dis2\'] = dt[\'straight2\']/dt[\'distance\']      #直线系数2=直线长度/路程长度 (0,1]
 59         dt[\'non_straight_dis2\'] = dt[\'distance\']/dt[\'straight2\']  #非直线系数2=路程长度/直线长度 [1,∞)
 60 
 61         bus_num+=1 #有效公交数+1
 62         return pd.DataFrame(dt,index=[bus_num]) #下标index为“第几条公交线”
 63     except:
 64         #print(\'没有{}公交\'.format(line)) #正常情况下,这条语句不会执行
 65         return pd.DataFrame()  #读取数据失败,返回空的
 66 
 67 def Bus_analysis(bus_info):
 68     print(\'公交线路的平均长度:{:.6f} km\'.format(bus_info["distance"].mean())) 
 69     print(\'公交线路的平均站点数:{:.6f} 个\'.format(bus_info[\'station\'].mean()))
 70     print(\'公交线路的平均站距1为:{:.6f} km/站\'.format(bus_info["distance"].sum()/(bus_info[\'station\'].sum()-bus_num)))
 71     print(\'公交线路的平均直线系数(区间距离):{:.6f}\'.format(bus_info[\'straight\'].sum()/bus_info["distance"].sum()))
 72     print(\'公交线路的平均非直线系数(区间距离):{:.6f}\'.format(bus_info["distance"].sum()/bus_info[\'straight\'].sum()))
 73     print(\'公交线路的平均直线系数(首位距离):{:.6f}\'.format(bus_info[\'straight2\'].sum()/bus_info["distance"].sum()))
 74     print(\'公交线路的平均非直线系数(首位距离):{:.6f}\'.format(bus_info["distance"].sum()/bus_info[\'straight2\'].sum()))
 75     
 76 if __name__=="__main__":
 77     t0=time.time()
 78     
 79     bus_num=0  #设置全局变量数值(通常默认就是0)
 80     city=\'泉州\' #需要查询公交信息的城市
 81     for_num=120 #遍历的线路数[1路,for_num路],通常公交线路数小于1000,具体可参考8684等网站
 82     all_buslines=pd.DataFrame()     
 83     for i in range(1,for_num+1):
 84         all_buslines=pd.concat([all_buslines,Bus_inf(city,str(i)+\'\')])  #不加这个\'路\'可能优先获取地铁
 85     
 86     print("Bus_info函数遍历{}前{}路公交,有效公交线路数为:{}个的情况下:".format(city,for_num,bus_num))
 87     Bus_analysis(all_buslines)
 88     
 89     all_buslines.to_csv("{}前{}路公交(有效线路数:{})基本信息.csv".format(city,for_num,bus_num),encoding=\'utf-8-sig\')
 90     
 91     t1=time.time()
 92     print("用时:%.2fs"%(t1-t0))
 93 
 94  #----------------------------------------------------------------------
 95  
 96  # 绘制词云,查看出现最多的站点
 97 import jieba
 98 from pylab import *
 99 from wordcloud import WordCloud
100 df = pd.read_csv(\'C:/Users/bb/python-jupyter noteboook/泉州前1000路公交(有效线路数:120)基本信息.csv\')
101 text = \'\'  
102 for line in df[\'沿途站点名\']:  
103     text += line  
104 # 使用jieba模块将字符串分割为单词列表
105 cut_text = \' \'.join(jieba.cut(text))
106 color_mask = imread(\'C:/Users/bb/python-jupyter noteboook/66.jpg\')  #设置背景图
107 cloud = WordCloud(
108     
109     background_color = \'white\',
110     # 对中文操作必须指明字体
111     font_path=\'C:\windows\Fonts\STZHONGS.TTF\',
112     mask = color_mask,
113     max_words = 50,
114     max_font_size = 200
115     ).generate(cut_text)
116  
117 # 保存词云图片
118 cloud.to_file(\'qzword1cloud.jpg\')
119 plt.imshow(cloud)
120 plt.axis(\'off\')
121 plt.show()
122 
123 
124  #----------------------------------------------------------------------
125 #导入爬虫所需的库
126 import requests
127 import json
128 import pandas as pd
129 import time
130 
131 #用于记录爬取公交线路所需要的时间函数
132 def record_time(flag):
133     if flag==0:
134         global t0
135         t0=time.time()
136     else:
137         t1=time.time()
138         print("用时:%.2fs"%(t1-t0))  
139     print(time.strftime(\'%Y-%m-%d %H:%M:%S\',time.localtime(time.time())))
140 
141 #获取公交基本信息 具体参考:高德地图api 路径规划-API文档-开发指南 https://lbs.amap.com/api/webservice/guide/api/direction#bus_list
142 def get_station(cityname,line):
143     global bus_num
144     #获取当前公交线路数据 利用高德开放平台创建适用web端的key,爬取公交站点信息
145     url = \'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=ad243f840dbda301f753ffd0436035b6&output=json&city={}&offset=1&keywords={}&platform=JS\'.format(cityname,line)
146     r = requests.get(url).text  #请求文本内容
147     rt = json.loads(r) #将json格式数据转换为字典
148     try:
149         #读取当前公交线路主要信息
150         dt = {}  #先定义一个dt数据集
151         dt[\'公交线路\'] = rt[\'buslines\'][0][\'name\'] #公交线路名字
152         dt[\'始发站点\'] = rt[\'buslines\'][0][\'start_stop\'] #始发站
153         dt[\'终点站\'] = rt[\'buslines\'][0][\'end_stop\'] #终点站
154         dt[\'区间站点\'] = rt[\'buslines\'][0][\'bounds\'] #行车区间(非始发站,终点站坐标)
155         dt[\'全程长度\'] = rt[\'buslines\'][0][\'distance\'] #全程长度
156         
157         #获取沿途站点站名、对应坐标和“第几站”信息
158         station_name = []
159         station_coords = []
160         station_sequence = []
161         
162         for st in rt[\'buslines\'][0][\'busstops\']:
163             station_name.append(st[\'name\'])
164             station_coords.append(st[\'location\'])
165             station_sequence.append(st[\'sequence\'])
166         
167         dt[\'沿途站点名\'] = station_name #沿途站点名
168         dt[\'沿途站点坐标\'] = station_coords #沿途站点坐标
169         dt[\'沿途站点第几站\'] = station_sequence #沿途站点第几站
170         
171         bus_num+=1 #有效公交数+1
172         
173         return pd.DataFrame(dt)  #返回pd.DataFrame()类型
174          
175     except: #try语句部分出错进入此部分(一般为站点名错误)
176         print(\'没有{}公交\'.format(line)) #输出没有的公交线路名字
177         return pd.DataFrame([])  #返回空的pd.DataFrame类型
178 
179 #获取当前城市所有公交基本信息:线路名、行车区间、全程长度、沿途站点及坐标
180 def Bus_info(city,for_num):
181     all_bus=pd.DataFrame()
182     for i in range(1,for_num+1):  
183         all_bus=pd.concat([all_bus,get_station(city,str(i)+\'\')])  #不加这个\'路\'可能优先获取地铁
184     print("Bus_info函数遍历{}前{}路公交,有效公交线路数为:{}个".format(city,for_num,bus_num))
185     all_bus.to_csv("{}前{}路公交(有效线路数:{})基本信息.csv".format(city,for_num,bus_num),encoding=\'utf-8-sig\')
186 
187 
188 if __name__=="__main__":
189     record_time(0)#用于记录开始时间
190     
191     bus_num=0  #全局变量,计算有效遍历的公交数
192     city=\'泉州\' #需要查询公交信息的城市
193     for_num=1000 #遍历的线路数[1路,for_num路],通常公交线路数小于1000,具体可参考8684等网站
194     Bus_info(city,for_num)
195 
196     record_time(1)#用于记录结束时间并输出用时
197 
198  
199 #----------------------------------------------------------------
200 #导入库
201 import numpy as np
202 import scipy as sp
203 import pandas as pd
204 import matplotlib
205 import matplotlib.pyplot as plt
206 from scipy.optimize import leastsq
207 import random
208 import matplotlib as mpl
209 
210 df = pd.read_csv(\'C:/Users/bb/python-jupyter noteboook/泉州前1000路公交(有效线路数:120)基本信息.csv\')   #导入泉州公交数据集
211 #df.head()
212 
213 df[[\'经度\',\'纬度\']] = df[\'沿途站点坐标\'].str.split(\',\', n=1, expand=True)    #因为爬取的经纬度在同一格,但是要分开,故采用切片。
214 df[\'经度\']=df[\'经度\'].astype(float)   #转换双精度类型
215 df[\'纬度\'] = df[\'纬度\'].astype(float)
216 
217 #设置x轴数据,有点冗余这一步,下一步也是
218 x_data =df[\'经度\']      
219 y_data = df[\'纬度\']
220 
221 #设置坐标点颜色
222 colors = [\'#FF0000\', \'#0000CD\', \'#00BFFF\', \'#008000\', \'#FF1493\', \'#FFD700\', \'#FF4500\', \'#00FA9A\', \'#191970\', \'#9932CC\'] 
223 #随机坐标颜色
224 colors = [random.choice(colors) for i in range(len(x_data))]
225 mpl.rcParams[\'font.family\'] = \'SimHei\'                  #用来正常显示中文标签
226 plt.style.use(\'ggplot\')                                 #利用matplotlib绘图设置背景,用plt.style.available查出可用样式列表
227 #plt.style.available
228 # 设置大小
229 plt.figure(figsize=(18, 10), dpi=200)
230 # 绘制散点图  经度  纬度  传进去   设置 颜色  点的大小
231 plt.scatter(x_data, y_data, marker="o", s=30., c=colors)
232  
233 # 添加描述信息 x轴 y轴 标题
234 plt.xlabel("经度")
235 plt.ylabel("纬度")
236 plt.title("泉州市公交站点分布情况")
237 plt.savefig(\'经纬度散点图.png\')
238 plt.show()
239 
240 
241 #----------------------------------------------------------------
242 #导入库
243 import numpy as np
244 import scipy as sp
245 import pandas as pd
246 import matplotlib
247 import matplotlib.pyplot as plt
248 from scipy.optimize import leastsq
249 
250 df = pd.read_csv(\'C:/Users/bb/python-jupyter noteboook/泉州前1000路公交(有效线路数:120)基本信息.csv\')
251 chinese=matplotlib.font_manager.FontProperties(fname=\'C:\Windows\Fonts\simsun.ttc\') #设置正常读取表格中中文名
252 
253 # 创建figure对象,设置画布大小
254 
255 plt.figure(figsize=(50,40))
256 
257 Xi=np.array(df[\'公交线路\'])
258 Yi=np.array(df[\'全程长度\'])
259 
260 from pylab import *   #从pylab中导入所有的非私有类,函数,全局变量等,* 代表所有,
261 mpl.rcParams[\'font.sans-serif\'] = [\'SimHei\']
262 mpl.rcParams[\'axes.unicode_minus\'] = False
263 
264 #绘制矩形图,x,y轴数据,表名,颜色
265 plt.barh(Xi, Yi, label="公交线路长度统计",color=[\'b\',\'orange\',\'g\',\'r\',\'purple\',\'#FF4500\', \'#00FA9A\',\'Pink\',\'#00BFFF\',\'y\',\'cyan\'])
266 
267 plt.title(\'泉州公交路线路长柱形图\')
268 plt.xlabel(\'总路程(km)\')
269 plt.ylabel(\'公交号\')   
270 plt.show()

 

 

五、总结(10 分)

(1)经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?

 结论:

  1.泉州的公交系统十分发达

  2.k207路是泉州行进路程最长一路

  3.泉州交通资源利用率较高

  

2.在完成此设计过程中,得到哪些收获?以及要改进的建议?

收获:

  1.通过上面的数据获取、分析与统计,我们不难看出公共交通作为城市经济和民生中最为重要的基础性设施,重视政府在城市公共交通中的重要地位和作用,提高对公共交通的政策扶持力度,进一步规范公共市场行为,提高公共交通企业市场竞争力.

  2.从整个数据爬取项目中我学习了许多新的知识内容,对之前学习的内容进行了巩固。

建议:

  需要改进的建议在于爬取的数据可分析的方向太少,下次可以尝试向公交的其他方面拓展。

 

分类:

技术点:

相关文章:

  • 2021-10-21
  • 2021-05-16
  • 2021-12-19
  • 2022-01-11
  • 2021-10-29
  • 2021-09-02
  • 2021-05-24
  • 2021-12-18
猜你喜欢
  • 2021-12-06
  • 2022-12-23
  • 2021-08-31
  • 2021-12-24
  • 2021-12-28
  • 2021-08-17
  • 2021-04-01
相关资源
相似解决方案