一、選題背景
交通對於一個城市而言是不可忽視的事情,在科技日益發達的當今世界,也隨着智慧交通的普及,交通的數據清晰,我們的生活也趨於更加便利的環境,但其上面的數據並不是很直觀。因此,我做了一個對於智慧交通網站上,數據爬取並進行數據分析及可視化,來讓數據更加直觀明了。
二、主題式網絡爬蟲設計方案
1.網絡爬蟲名稱
爬取百度地圖智慧交通的泉州擁堵指數內容
2.網頁網址
http://jiaotong.baidu.com/top/report/?citycode=134
3.主題頁面的結構特征分析
數據源代碼

發現 在body標簽里沒有div的內容,只有script標簽內容。但是用鼠標右鍵,檢查元素(F12)中是可以看到內容的,我想到了用Python中selenium的解析庫來做。
並且發現頁面中有些數據不是文字格式,而是通過數據可視化形成的繪圖對象,如圖:

在網上查閱了大量資料后且求助了老師,得知在網頁源碼里體現不到的數據,一般是通過json文件發送的。
右鍵檢查元素(F12)找到Network,左側的Name欄是頁面發送的相關請求,右側有Headers、Preview、Response等屬性,我們單擊Preview會出現一些json數據,經過對比我發現正是我在源碼里獲取不到的繪圖對象的數據。
點擊對應請求的Headers,我們可以看到頁面請求的地址Request URL,進行爬取數據
這個Request URL就是我們要爬取的目標鏈接,這個地址里的json數據對應的是“實時擁堵指數”的數據,對於其他的數據,我們一一尋找即可。
三、數據爬取程序設計
1.導入要使用的庫
源碼:
1 #導入要使用的庫 2 import requests 3 import re 4 import json
2.獲取頁面
源碼:
1 def get_page(url): 2 try: 3 response = requests.get(url) 4 if response.content: # 返回成功 5 return response 6 except requests.ConnectionError as e: 7 print('url出錯', e.args)
嘗試運行一下程序,將get_page(url)的返回值轉為文本格式,輸出get_page(url)的返回值和返回值類型。
源碼:
1 #將get_page(url)的返回值轉為文本格式 2 url = 'https://jiaotong.baidu.com/trafficindex/city/details?cityCode=134&callback=jsonp_1570959868686_520859' 3 print(type(get_page(url))) 4 print(get_page(url).text)
運行結果

3.解析頁面
獲取到文本格式的頁面信息后,我們要對頁面進行解析,和解析網頁源碼類似,我們要找一下,獲取到的頁面信息有哪些是我們需要的。
源碼:
1 #將get_page(url)的返回值轉為文本格式 2 url = 'https://jiaotong.baidu.com/trafficindex/city/details?cityCode=134&callback=jsonp_1570959868686_520859' 3 print(type(get_page(url))) 4 print(get_page(url).text)
在數據中發現,json格式的數據類似與Python中的字典:{key : value},顯然返回的頁面文本有一些其他數據,我們要對這些數據進行一下篩選,找出我們需要的那一部分。
源碼:
1 # 獲取實時擁堵指數內容 2 def get_detail(page): 3 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 4 detail = transformData['data']['detail'] 5 print('實時擁堵指數數據:') 6 for i in detail: 7 print(str(i)+':'+str(detail[i]))
這樣即可獲取頁面返回文本中括號里的內容,這里用到了re.findall()函數,re.findall(pattern,string)可以將傳入的字符串以列表的形式返回,因此,這里取re.findall(pattern, page.text)[0](返回只有一串json文本,只取列表中的第一個即可)。用json.loads()讀取處理過的數據,加載成Python中的字典格式。
運行襯程序結果展示

頁面中獲取不到的實時交通指數數據,已經被我們成功獲取到了,再將獲取到的數據寫入txt文件中即可。
設計一個txt的生成程序,儲存數據
源碼:
1 import requests 2 import re 3 import json 4 5 def get_page(url): 6 try: 7 response = requests.get(url) 8 if response.content: # 返回成功 9 return response 10 except requests.ConnectionError as e: 11 print('url出錯', e.args) 12 13 def write_to_file(content): 14 with open('泉州市交通情況數據爬取.txt', 'a', encoding='utf-8') as f: 15 f.write(json.dumps(content, ensure_ascii=False)+'\n') 16 # f.close()
4.在此基礎上,用同樣的方法我還爬取了實時擁堵指數變化內容、實時道路擁堵指數、實時擁堵里程、昨日早晚高峰內容、全部道路擁堵情況
(1)實時擁堵指數變化情況
源碼:
1 # 獲取實時擁堵指數變化內容 2 def get_curve(page): 3 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 4 curve_detail = transformData['data']['list'] 5 k = 0 6 for roadrank_list in curve_detail: 7 print('---------------分割線---------------') 8 print(k) 9 write_to_file(str(k)+str(roadrank_list)) 10 k += 1 11 print(roadrank_list) 12 url_curve = 'https://jiaotong.baidu.com/trafficindex/city/curve?cityCode=134&type=minute&callback=jsonp_1571018819971_8078256' 13 # 獲取實時擁堵指數變化內容 14 print('獲取實時擁堵指數變化內容') 15 write_to_file('獲取實時擁堵指數變化內容') 16 get_curve(get_page(url_curve))
運行程序結果展示

(2)獲取實時道路擁堵數據內容
源碼:
1 # 獲取實時道路擁堵指數內容 2 def get_road(page): 3 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 4 detail = transformData['data']['detail'] 5 for i in detail: 6 write_to_file(str(i)+':'+str(detail[i])) 7 print(str(i)+':'+str(detail[i])) 8 url_road = 'https://jiaotong.baidu.com/trafficindex/city/road?cityCode=134&callback=jsonp_1571014746541_9598712' 9 # 獲取實時道路擁堵指數內容 10 print('獲取實時道路擁堵指數內容') 11 write_to_file('獲取實時道路擁堵指數內容') 12 get_road(get_page(url_road))
程序運行結果展示

(3)獲取實時擁堵里程內容
源碼:
1 # 獲取實時擁堵里程內容 2 def get_congestmile(page): 3 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 4 congest = transformData['data']['congest'] 5 for i in congest: 6 write_to_file(str(i)+':'+str(congest[i])) 7 print(str(i)+':'+str(congest[i])) 8 9 url_congestmile = 'https://jiaotong.baidu.com/trafficindex/city/congestmile?cityCode=134&callback=jsonp_1571014746542_5952586' 10 11 # 獲取實時擁堵里程內容 12 print('獲取實時擁堵里程內容') 13 write_to_file('獲取實時擁堵里程內容') 14 get_congestmile(get_page(url_congestmile))
程序運行結果展示

(4)獲取早晚峰內容
源碼:
1 # 獲取昨日早晚高峰內容 2 def get_peakCongest(page): 3 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 4 peak_detail = transformData['data']['peak_detail'] 5 for i in peak_detail: 6 write_to_file(str(i)+':'+str(peak_detail[i])) 7 print(str(i)+':'+str(peak_detail[i])) 8 url_peakCongest = 'https://jiaotong.baidu.com/trafficindex/city/peakCongest?cityCode=134&callback=jsonp_1571014746543_3489265' 9 # 獲取昨日早晚高峰內容 10 print('獲取昨日早晚高峰內容') 11 write_to_file('獲取昨日早晚高峰內容') 12 get_peakCongest(get_page(url_peakCongest))
程序運行結果展示

(5)獲取全道路擁堵情況
源碼:
1 # 獲取全部道路擁堵情況 2 def get_roadrank(page): 3 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 4 roadrank_detail = transformData['data']['list'] 5 for roadrank_list in roadrank_detail: 6 write_to_file('---------------分割線---------------') 7 print('---------------分割線---------------') 8 for element in roadrank_list: 9 if str(element) != 'links' and str(element) != 'nameadd': 10 write_to_file(str(element)+':'+str(roadrank_list[element])) 11 print(str(element)+':'+str(roadrank_list[element])) 12 url_roadrank = 'https://jiaotong.baidu.com/trafficindex/city/roadrank?cityCode=134&roadtype=0&callback=jsonp_1571016737139_1914397' 13 # 獲取全部道路擁堵情況 14 print('獲取全部道路擁堵情況') 15 write_to_file('獲取全部道路擁堵情況') 16 get_roadrank(get_page(url_roadrank))
程序運行結果展示

四、數據分析及可視化
在爬取完數據之后,選取了實時擁堵指數數據為主體展開分析
1.首先將有用實時擁堵指數數據進行整合,提取有用數據
源碼:
1 #將實時擁堵指數變化內容里的有用數據導出 2 from bs4 import BeautifulSoup 3 import urllib.request 4 import re 5 6 html_doc = "https://jiaotong.baidu.com/trafficindex/city/curve?cityCode=134&type=minute&callback=jsonp_1571018819971_8078256" 7 req = urllib.request.Request(html_doc) 8 webpage = urllib.request.urlopen(req) 9 html = webpage.read() 10 html=html.decode('utf-8') 11 transformData = json.loads(re.findall(r'[(](.*?)[)]',html)[0]) 12 curve_detail = transformData['data']['list'] 13 print(curve_detail)
將index、speed、time,三樣數據導出

2.將三樣數據導成csv文件,方便之后數據可視化和數據分析中使用
源碼:
1 #將實時擁堵指數變化內容的有用數據轉化為csv文件 2 import pandas as pd 3 4 # 下面這行代碼運行報錯 5 # list.to_csv('e:/testcsv.csv',encoding='utf-8') 6 name=['index','speed','time'] 7 test=pd.DataFrame(columns=name,data=curve_detail)#數據有三列,列名分別為one,two,three 8 print(test) 9 test.to_csv('泉州實時擁堵指數變化內容.csv',encoding='gbk') 10 #試運行導出前五行數據 11 df = pd.read_csv('泉州實時擁堵指數變化內容.csv',encoding='gbk') 12 df.head()
生成csv文件

3.數據分析,將csv文件中的index列的數據進行讀取,並轉換格式,截取前30個數據進行分析
源碼:
1 #導入csv模塊 2 import csv 3 4 #指定文件名,然后使用 with open() as 打開 5 filename = '泉州實時擁堵指數變化內容.csv' 6 #導出頭文件 7 with open(filename) as f: 8 #創建一個閱讀器:將f傳給csv.reader 9 reader = csv.reader(f) 10 11 #使用csv的next函數,將reader傳給next,將返回文件的下一行 12 header_row = next(reader) 13 14 for index, column_header in enumerate(header_row): 15 print(index, column_header) 16 #讀取擁堵指數 17 #創建最高擁堵指數的列表 18 indexs =[] 19 #遍歷reader的余下的所有行(next讀取了第一行,reader每次讀取后將返回下一行) 20 for row in reader: 21 indexs.append(row[1]) 22 #f分析前30個擁堵指數 23 indexs = indexs[:30] 24 print(indexs) 25 index = float(row[1]) 26 indexs.append(index) 27
程序運行結果展示

4.采取相同的方法,將time列的數據取出,截取前30個數據,並將time和index兩者繪制折線圖,分析數據之間的關系
源碼:
1 import csv 2 import matplotlib.pyplot as plt 3 from datetime import datetime 4 5 filename = '泉州實時擁堵指數變化內容.csv' 6 with open(filename,'r') as f: 7 reader = csv.reader(f) # 生成閱讀器,f對象傳入 8 header_row = next(reader) # 查看文件第一行,reader是可迭代對象 9 10 dates,indexs = [],[] 11 for row in reader: 12 #current_date = datetime.strptime(row[3]) 13 dates.append(row[3]) 14 #high = int(row[1]) 15 indexs.append(row[1]) 16 print(dates) 17 indexs = indexs[:30] 18 index = float(row[1]) 19 indexs.append(index) 20 dates=dates[:30] 21 date=row[3] 22 dates.append(date) 23 24 # 設置圖片大小 25 fig = plt.figure(dpi=128,figsize=(10,6)) 26 plt.plot(dates,indexs, c='red',linewidth=1) # linewidth決定繪制線條的粗細 27 28 # 設置圖片格式 29 plt.title('實時擁堵指數折線圖', fontsize=13) # 標題 30 plt.xlabel('時間', fontsize=14) 31 fig.autofmt_xdate() # 日期標簽轉為斜體 32 plt.ylabel('擁堵指數', fontsize=14) 33 plt.tick_params(axis='both',which='major') 34 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 35 plt.show() # 輸出圖像
折線圖

從圖像可以看出,擁堵指數大致是增長的趨勢,但指數的變化都在分毫之間,也有存在着下降的趨勢,說明在夜深的時候,整體變化趨勢不大,但是在時間段上還是有區別的。
5.繼續分析index和time之間的關系,繪制散點圖
源碼:
1 import csv 2 import matplotlib.pyplot as plt 3 from datetime import datetime 4 5 filename = '泉州實時擁堵指數變化內容.csv' 6 with open(filename,'r') as f: 7 reader = csv.reader(f) # 生成閱讀器,f對象傳入 8 header_row = next(reader) # 查看文件第一行,reader是可迭代對象 9 10 indexs = [] 11 for row in reader: 12 indexs.append(row[1]) 13 indexs = indexs[:30] 14 index = str(row[1]) 15 indexs.append(index) 16 17 18 import matplotlib.pyplot as plt 19 # 設置圓點大小 20 size = 5 21 # 繪制散點圖 22 23 fig = plt.figure(dpi=128,figsize=(10,6)) 24 plt.scatter(dates,indexs, size, color="r") 25 plt.xlabel("時間") 26 fig.autofmt_xdate() # 日期標簽轉為斜體 27 plt.ylabel("擁堵指數") 28 plt.title("實時擁堵指數散點圖") 29 plt.show()
散點圖

通過散點圖和折線圖可知,指數在1.095居多,且在2點上,指數比其他時間段的都來得小可以得知,在這段時間交通是順暢的
6.以同樣的方法,提取出speed,繪制出speed和time之間的關系圖像,執行分析。
源碼:
1 #導出speed數據 2 import csv 3 import matplotlib.pyplot as plt 4 from datetime import datetime 5 6 filename = '泉州實時擁堵指數變化內容.csv' 7 with open(filename,'r') as f: 8 reader = csv.reader(f) # 生成閱讀器,f對象傳入 9 header_row = next(reader) # 查看文件第一行,reader是可迭代對象 10 11 speed = [] 12 for row in reader: 13 speed.append(row[2]) 14 speeds=speed[:30] 15 speed=str(row[2]) 16 speeds.append(speed) 17 print(speeds) 18 19 import matplotlib.pyplot as plt 20 # 設置圓點大小 21 size = 5 22 # 繪制散點圖 23 24 fig = plt.figure(dpi=128,figsize=(10,6)) 25 plt.scatter(dates,speeds, size, color="r") 26 plt.xlabel("時間") 27 fig.autofmt_xdate() # 日期標簽轉為斜體 28 plt.ylabel("平均速度") 29 plt.title("實時擁堵平均速度散點圖") 30 plt.show() 31 32 # 設置圖片大小 33 fig = plt.figure(dpi=128,figsize=(10,6)) 34 plt.plot(dates,speeds, c='red',linewidth=1) # linewidth決定繪制線條的粗細 35 # 設置圖片格式 36 plt.title('實時擁堵平均折線圖', fontsize=13) # 標題 37 plt.xlabel('時間', fontsize=14) 38 fig.autofmt_xdate() # 日期標簽轉為斜體 39 plt.ylabel('平均速度', fontsize=14) 40 plt.tick_params(axis='both',which='major') 41 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 42 plt.show() # 輸出圖像
折線圖

散點圖

根據這兩個圖像可知,在時間上,時間客觀的決定了擁堵的程度,同時牽引着擁堵指數,擁堵指數影響着平均速度,在高峰期的時候更為突出。
7.繪制平均速度和擁堵指數的散點圖與折線圖,進一步的分析兩者之間的關系
源碼:
1 import matplotlib.pyplot as plt 2 # 設置圓點大小 3 size = 5 4 # 繪制散點圖 5 6 fig = plt.figure(dpi=128,figsize=(10,6)) 7 plt.scatter(indexs,speeds, size, color="r") 8 plt.xlabel("擁堵指數") 9 fig.autofmt_xdate() # 日期標簽轉為斜體 10 plt.ylabel("平均速度") 11 plt.title("實時擁堵平均速度與擁堵指數散點圖") 12 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 13 plt.show() 14 # 設置圖片大小 15 fig = plt.figure(dpi=128,figsize=(10,6)) 16 plt.plot(dates,speeds, c='red',linewidth=1) # linewidth決定繪制線條的粗細 17 # 設置圖片格式 18 plt.title('實時擁堵平均與擁堵指數之間折線圖', fontsize=13) # 標題 19 plt.xlabel('擁堵指數', fontsize=14) 20 fig.autofmt_xdate() # 日期標簽轉為斜體 21 plt.ylabel('平均速度', fontsize=14) 22 plt.tick_params(axis='both',which='major') 23 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 24 plt.show() # 輸出圖像
散點圖

折線圖

如圖所示平均速度與擁堵指數,相互影響,一方改變就會牽動着另一方的變化,再結合前面的數據分析,得出在不同的時間節點上,擁堵指數和平均速度都在變化,且也會受着不可控因素的影響
8.數據持久化
在數據提取直接采用,csv存儲到默認位置,方便打開,並且方便數據更新,並且,方便我們的數據分析,也使得數據能夠在任何場地、任何人的電腦都能夠運行。
9、以上就是我的課程設計,完整代碼如下
1 #導入要使用的庫 2 import requests 3 import re 4 import json 5 6 #獲取頁面 7 def get_page(url): 8 try: 9 response = requests.get(url) 10 if response.content: # 返回成功 11 return response 12 except requests.ConnectionError as e: 13 print('url出錯', e.args) 14 15 #輸出get_page(url)的返回值和返回值類型。 16 url = 'https://jiaotong.baidu.com/trafficindex/city/details?cityCode=134&callback=jsonp_1570959868686_520859' 17 print(type(get_page(url))) 18 print(get_page(url)) 19 20 #將get_page(url)的返回值轉為文本格式 21 url = 'https://jiaotong.baidu.com/trafficindex/city/details?cityCode=134&callback=jsonp_1570959868686_520859' 22 print(type(get_page(url))) 23 print(get_page(url).text) 24 25 # 獲取實時擁堵指數內容 26 def get_detail(page): 27 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 28 detail = transformData['data']['detail'] 29 print('實時擁堵指數數據:') 30 for i in detail: 31 print(str(i)+':'+str(detail[i])) 32 print('獲取實時擁堵指數內容') 33 write_to_file('獲取實時擁堵指數內容') 34 get_detail(get_page(url_detail)) 35 36 37 # 獲取實時擁堵指數內容 38 39 def get_detail(page): 40 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 41 detail = transformData['data']['detail'] 42 print('實時擁堵指數數據:') 43 for i in detail: 44 print(str(i)+':'+str(detail[i])) 45 46 import requests 47 import re 48 import json 49 50 def get_page(url): 51 try: 52 response = requests.get(url) 53 if response.content: # 返回成功 54 return response 55 except requests.ConnectionError as e: 56 print('url出錯', e.args) 57 58 def write_to_file(content): 59 with open('泉州市交通情況數據爬取.txt', 'a', encoding='utf-8') as f: 60 f.write(json.dumps(content, ensure_ascii=False)+'\n') 61 # f.close() 62 63 # 獲取實時擁堵指數內容 64 def get_detail(page): 65 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 66 detail = transformData['data']['detail'] 67 for i in detail: 68 write_to_file(str(i)+':'+str(detail[i])) 69 print(str(i)+':'+str(detail[i])) 70 71 # 獲取實時擁堵指數變化內容 72 def get_curve(page): 73 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 74 curve_detail = transformData['data']['list'] 75 k = 0 76 for roadrank_list in curve_detail: 77 print('---------------分割線---------------') 78 print(k) 79 write_to_file(str(k)+str(roadrank_list)) 80 k += 1 81 print(roadrank_list) 82 83 # 獲取實時道路擁堵指數內容 84 def get_road(page): 85 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 86 detail = transformData['data']['detail'] 87 for i in detail: 88 write_to_file(str(i)+':'+str(detail[i])) 89 print(str(i)+':'+str(detail[i])) 90 91 # 獲取實時擁堵里程內容 92 def get_congestmile(page): 93 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 94 congest = transformData['data']['congest'] 95 for i in congest: 96 write_to_file(str(i)+':'+str(congest[i])) 97 print(str(i)+':'+str(congest[i])) 98 99 100 # 獲取昨日早晚高峰內容 101 def get_peakCongest(page): 102 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 103 peak_detail = transformData['data']['peak_detail'] 104 for i in peak_detail: 105 write_to_file(str(i)+':'+str(peak_detail[i])) 106 print(str(i)+':'+str(peak_detail[i])) 107 108 109 # 獲取全部道路擁堵情況 110 def get_roadrank(page): 111 transformData = json.loads(re.findall(r'[(](.*?)[)]', page.text)[0]) 112 roadrank_detail = transformData['data']['list'] 113 for roadrank_list in roadrank_detail: 114 write_to_file('---------------分割線---------------') 115 print('---------------分割線---------------') 116 for element in roadrank_list: 117 if str(element) != 'links' and str(element) != 'nameadd': 118 write_to_file(str(element)+':'+str(roadrank_list[element])) 119 print(str(element)+':'+str(roadrank_list[element])) 120 121 if __name__ == '__main__': 122 123 url_detail = 'https://jiaotong.baidu.com/trafficindex/city/details?cityCode=134&callback=jsonp_1570959868686_520859' 124 125 url_curve = 'https://jiaotong.baidu.com/trafficindex/city/curve?cityCode=134&type=minute&callback=jsonp_1571018819971_8078256' 126 127 url_road = 'https://jiaotong.baidu.com/trafficindex/city/road?cityCode=134&callback=jsonp_1571014746541_9598712' 128 129 url_congestmile = 'https://jiaotong.baidu.com/trafficindex/city/congestmile?cityCode=134&callback=jsonp_1571014746542_5952586' 130 131 url_peakCongest = 'https://jiaotong.baidu.com/trafficindex/city/peakCongest?cityCode=134&callback=jsonp_1571014746543_3489265' 132 133 url_roadrank = 'https://jiaotong.baidu.com/trafficindex/city/roadrank?cityCode=134&roadtype=0&callback=jsonp_1571016737139_1914397' 134 135 url_highroadrank = 'https://jiaotong.baidu.com/trafficindex/city/roadrank?cityCode=134&roadtype=1&callback=jsonp_1571018628002_9539211' 136 137 # 獲取實時擁堵指數內容 138 print('獲取實時擁堵指數內容') 139 write_to_file('獲取實時擁堵指數內容') 140 get_detail(get_page(url_detail)) 141 142 # 獲取實時擁堵指數變化內容 143 print('獲取實時擁堵指數變化內容') 144 write_to_file('獲取實時擁堵指數變化內容') 145 get_curve(get_page(url_curve)) 146 147 # 獲取實時道路擁堵指數內容 148 print('獲取實時道路擁堵指數內容') 149 write_to_file('獲取實時道路擁堵指數內容') 150 get_road(get_page(url_road)) 151 152 # 獲取實時擁堵里程內容 153 print('獲取實時擁堵里程內容') 154 write_to_file('獲取實時擁堵里程內容') 155 get_congestmile(get_page(url_congestmile)) 156 157 # 獲取昨日早晚高峰內容 158 print('獲取昨日早晚高峰內容') 159 write_to_file('獲取昨日早晚高峰內容') 160 get_peakCongest(get_page(url_peakCongest)) 161 162 # 獲取全部道路擁堵情況 163 print('獲取全部道路擁堵情況') 164 write_to_file('獲取全部道路擁堵情況') 165 get_roadrank(get_page(url_roadrank)) 166 167 # 獲取高速/快速路擁堵情況 168 print('獲取高速/快速路擁堵情況') 169 write_to_file('獲取高速/快速路擁堵情況') 170 get_roadrank(get_page(url_highroadrank)) 171 172 #將實時擁堵指數變化內容里的有用數據導出 173 from bs4 import BeautifulSoup 174 import urllib.request 175 import re 176 177 html_doc = "https://jiaotong.baidu.com/trafficindex/city/curve?cityCode=134&type=minute&callback=jsonp_1571018819971_8078256" 178 req = urllib.request.Request(html_doc) 179 webpage = urllib.request.urlopen(req) 180 html = webpage.read() 181 html=html.decode('utf-8') 182 transformData = json.loads(re.findall(r'[(](.*?)[)]',html)[0]) 183 curve_detail = transformData['data']['list'] 184 print(curve_detail) 185 186 #將實時擁堵指數變化內容的有用數據轉化為csv文件 187 import pandas as pd 188 189 # 下面這行代碼運行報錯 190 # list.to_csv('e:/testcsv.csv',encoding='utf-8') 191 name=['index','speed','time'] 192 test=pd.DataFrame(columns=name,data=curve_detail)#數據有三列,列名分別為one,two,three 193 print(test) 194 test.to_csv('泉州實時擁堵指數變化內容.csv',encoding='gbk') 195 #試運行導出前五行數據 196 df = pd.read_csv('泉州實時擁堵指數變化內容.csv',encoding='gbk') 197 df.head() 198 199 #導入csv模塊 200 import csv 201 202 #指定文件名,然后使用 with open() as 打開 203 filename = '泉州實時擁堵指數變化內容.csv' 204 #導出頭文件 205 with open(filename) as f: 206 #創建一個閱讀器:將f傳給csv.reader 207 reader = csv.reader(f) 208 209 #使用csv的next函數,將reader傳給next,將返回文件的下一行 210 header_row = next(reader) 211 212 for index, column_header in enumerate(header_row): 213 print(index, column_header) 214 #讀取擁堵指數 215 #創建最高擁堵指數的列表 216 indexs =[] 217 #遍歷reader的余下的所有行(next讀取了第一行,reader每次讀取后將返回下一行) 218 for row in reader: 219 indexs.append(row[1]) 220 #f分析前30個擁堵指數 221 indexs = indexs[:30] 222 print(indexs) 223 index = float(row[1]) 224 indexs.append(index) 225 226 import csv 227 import matplotlib.pyplot as plt 228 from datetime import datetime 229 230 filename = '泉州實時擁堵指數變化內容.csv' 231 with open(filename,'r') as f: 232 reader = csv.reader(f) # 生成閱讀器,f對象傳入 233 header_row = next(reader) # 查看文件第一行,reader是可迭代對象 234 235 dates,indexs = [],[] 236 for row in reader: 237 #current_date = datetime.strptime(row[3]) 238 dates.append(row[3]) 239 #high = int(row[1]) 240 indexs.append(row[1]) 241 print(dates) 242 indexs = indexs[:30] 243 index = float(row[1]) 244 indexs.append(index) 245 dates=dates[:30] 246 date=row[3] 247 dates.append(date) 248 249 # 設置圖片大小 250 fig = plt.figure(dpi=128,figsize=(10,6)) 251 plt.plot(dates,indexs, c='red',linewidth=1) # linewidth決定繪制線條的粗細 252 253 # 設置圖片格式 254 plt.title('實時擁堵指數折線圖', fontsize=13) # 標題 255 plt.xlabel('時間', fontsize=14) 256 fig.autofmt_xdate() # 日期標簽轉為斜體 257 plt.ylabel('擁堵指數', fontsize=14) 258 plt.tick_params(axis='both',which='major') 259 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 260 plt.show() # 輸出圖像 261 262 import csv 263 import matplotlib.pyplot as plt 264 from datetime import datetime 265 266 filename = '泉州實時擁堵指數變化內容.csv' 267 with open(filename,'r') as f: 268 reader = csv.reader(f) # 生成閱讀器,f對象傳入 269 header_row = next(reader) # 查看文件第一行,reader是可迭代對象 270 271 indexs = [] 272 for row in reader: 273 indexs.append(row[1]) 274 indexs = indexs[:30] 275 index = str(row[1]) 276 indexs.append(index) 277 278 279 import matplotlib.pyplot as plt 280 # 設置圓點大小 281 size = 5 282 # 繪制散點圖 283 284 fig = plt.figure(dpi=128,figsize=(10,6)) 285 plt.scatter(dates,indexs, size, color="r") 286 plt.xlabel("時間") 287 fig.autofmt_xdate() # 日期標簽轉為斜體 288 plt.ylabel("擁堵指數") 289 plt.title("實時擁堵指數散點圖") 290 plt.show() 291 292 #導出speed數據 293 import csv 294 import matplotlib.pyplot as plt 295 from datetime import datetime 296 297 filename = '泉州實時擁堵指數變化內容.csv' 298 with open(filename,'r') as f: 299 reader = csv.reader(f) # 生成閱讀器,f對象傳入 300 header_row = next(reader) # 查看文件第一行,reader是可迭代對象 301 302 speed = [] 303 for row in reader: 304 speed.append(row[2]) 305 speeds=speed[:30] 306 speed=str(row[2]) 307 speeds.append(speed) 308 print(speeds) 309 310 #實時擁堵平均速度散點圖和折線圖 311 import matplotlib.pyplot as plt 312 # 設置圓點大小 313 size = 5 314 # 繪制散點圖 315 316 fig = plt.figure(dpi=128,figsize=(10,6)) 317 plt.scatter(dates,speeds, size, color="r") 318 plt.xlabel("時間") 319 fig.autofmt_xdate() # 日期標簽轉為斜體 320 plt.ylabel("平均速度") 321 plt.title("實時擁堵平均速度散點圖") 322 plt.show() 323 324 # 設置圖片大小 325 fig = plt.figure(dpi=128,figsize=(10,6)) 326 plt.plot(dates,speeds, c='red',linewidth=1) # linewidth決定繪制線條的粗細 327 # 設置圖片格式 328 plt.title('實時擁堵平均折線圖', fontsize=13) # 標題 329 plt.xlabel('時間', fontsize=14) 330 fig.autofmt_xdate() # 日期標簽轉為斜體 331 plt.ylabel('平均速度', fontsize=14) 332 plt.tick_params(axis='both',which='major') 333 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 334 plt.show() # 輸出圖像 335 336 337 #繪制平均速度和擁堵指數的散點圖和折線圖 338 import matplotlib.pyplot as plt 339 # 設置圓點大小 340 size = 5 341 # 繪制散點圖 342 343 fig = plt.figure(dpi=128,figsize=(10,6)) 344 plt.scatter(indexs,speeds, size, color="r") 345 plt.xlabel("擁堵指數") 346 fig.autofmt_xdate() # 日期標簽轉為斜體 347 plt.ylabel("平均速度") 348 plt.title("實時擁堵平均速度與擁堵指數散點圖") 349 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 350 plt.show() 351 # 設置圖片大小 352 fig = plt.figure(dpi=128,figsize=(10,6)) 353 plt.plot(dates,speeds, c='red',linewidth=1) # linewidth決定繪制線條的粗細 354 # 設置圖片格式 355 plt.title('實時擁堵平均與擁堵指數之間折線圖', fontsize=13) # 標題 356 plt.xlabel('擁堵指數', fontsize=14) 357 fig.autofmt_xdate() # 日期標簽轉為斜體 358 plt.ylabel('平均速度', fontsize=14) 359 plt.tick_params(axis='both',which='major') 360 plt.rcParams['font.sans-serif']=['Microsoft YaHei']#顯示中文 361 plt.show() # 輸出圖像
五、總結
1.預期與結果:
(1)根據數據網絡爬蟲,數據整合及轉換,還有最后的數據分析來說,本次課程設計已經達到了我所預期的,能夠將數據爬取出來,也能夠將數據進行可視化和數據分析,讓百度地圖上不能夠很直觀的數據,能夠直觀的展現出來;同時分析了三種數據之間的關系,以圖表的形式,是預期想做的,能夠使他們之間的關系更加明了。
(2)這次的課程設計比較妙的地方在於,將數據進行了csv文件的生成,讓數據可以隨時可用,也可以隨時可以更新,符合了我所想要達到的實驗目的,讓實時數據可以隨時導出,隨時利用。
2.不足之處:
(1)在前期的數據爬取上,仍存在着很多不懂的地方,在網絡爬取數據方面需要進一步的加強;
(2)在后面的csv文件的導出上,還是不夠熟練,花費時間過長
(3)在數據可視化分析上,有些語句仍不夠熟練,不能很好的利用,進行數據可視化,導致在圖像方面上,並沒有達到預期的想法。
