python获取天气分析_Python爬取南京市往年天气预报,使用pyecharts进行分析
上一次分享了使用matplotlib對爬取的豆瓣書籍排行榜進行分析,但是發現python本身自帶的這個繪圖分析庫還是有一些局限,繪圖不夠美觀等,在網上搜索了一波,發現現在有很多的支持python的繪圖庫可以使用,本次嘗試使用pyecharts對爬取的數據進行分析,然后發現這個庫實在是太好用了,生成的庫也很好看,還能生成動態圖,簡直是進行數據分析的一大神器!
pyecharts:pyecharts是一個封裝百度開源圖表庫echarts的包,使用pyecharts可以生成獨立的網頁,也可以在flask、django中集成使用。
本次爬取的首頁地址是:
http://www.tianqihoubao.com/lishi/nanjing.html
爬取步驟:
爬取主網頁,獲取進入每個南京市具體年份月份的天氣數據的鏈接
爬取上方獲取的具體鏈接的數據
存儲數據
對數據進行篩選后使用pyecharts進行分析
話不多說,馬上開始吧!
步驟一
從上圖可知,我們需要先獲取進入每個具體月份的鏈接,才能爬取想要的數據,所以首先定義獲取具體鏈接的函數,然后在爬取會方便很多;查看網頁源代碼查找目標所在位置,本次我依然是使用lxml庫來進行數據的爬取(PS:感覺習慣了lxml其他庫就不好用了),這里需要注意的是,我是將獲得的結果一個一個的存入列表,這種方法很笨,但作為菜鳥的我確實不知道其他方法了,還有就是發現爬取的部分鏈接缺了一點,所以又定義了一個函數來補上。
具體代碼如下:?????????? 注:轉載代碼請標明出處
1 def get_mainurl(url): #定義獲取月份天氣的詳細url 函數
2 res = requests.get(url, headers=headers)3 main_url =[]4 if res.status_code == 200: #判斷請求狀態
5 selector =etree.HTML(res.text)6 htmlurls = selector.xpath('//div[contains(@id,"content")]/div') #循環點
7 try:8 for htmlurl inhtmlurls:9 Jan = htmlurl.xpath('ul[1]/li[2]/a/@href')[0] #一月份天氣url
10 main_url.append(Jan) #將網址放入列表中,一個一個放是很蠢的方法,但我也確實不知道其他方法了,下同
11 Feb = htmlurl.xpath('ul[1]/li[3]/a/@href')[0] #二月份天氣url
12 main_url.append(Feb)13 Mar = htmlurl.xpath('ul[1]/li[4]/a/@href')[0] #同上,下類推
14 main_url.append(Mar)15 Apr = htmlurl.xpath('ul[2]/li[2]/a/@href')[0]16 main_url.append(Apr)17 May = htmlurl.xpath('ul[2]/li[3]/a/@href')[0]18 main_url.append(May)19 June = htmlurl.xpath('ul[2]/li[4]/a/@href')[0]20 main_url.append(June)21 July = htmlurl.xpath('ul[3]/li[2]/a/@href')[0]22 main_url.append(July)23 Aug = htmlurl.xpath('ul[3]/li[3]/a/@href')[0]24 main_url.append(Aug)25 Sep = htmlurl.xpath('ul[3]/li[4]/a/@href')[0]26 main_url.append(Sep)27 Oct = htmlurl.xpath('ul[4]/li[2]/a/@href')[0]28 main_url.append(Oct)29 Nov = htmlurl.xpath('ul[4]/li[3]/a/@href')[0]30 main_url.append(Nov)31 Dec = htmlurl.xpath('ul[4]/li[4]/a/@href')[0]32 main_url.append(Dec)33
34 time.sleep(0.5) #休眠0.5s
35 exceptIndexError:36 pass
37 return main_url #將存了所有url的列表返回
38 else:39 pass
40
41
42 def link_url(url): #上面獲取的url是不完整的,此函數使其完整
43 final_urls=[]44 list_urls =get_mainurl(url)45 for list_url inlist_urls:46 if len(list_url) < 30: #因為獲取的url有一些少了‘/lishi/’,所以需要判斷一下
47 list_url = 'http://www.tianqihoubao.com/lishi/' +list_url48 final_urls.append(list_url)49 else:50 list_url = 'http://www.tianqihoubao.com' +list_url51 final_urls.append(list_url)52 return final_urls
步驟二
接下來是獲取所需的數據,遍歷所在節點就行了,需要注意的是要跳過第一個節點,因為其內部沒有內容。
代碼如下:
def get_infos(detail_url): #爬取月份天氣詳細數據函數
main_res = requests.get(detail_url, headers=headers)
main_sele=etree.HTML(main_res.text)
main_infos= main_sele.xpath('//div[@class="hd"]/div[1]/table/tr')
i=Truetry:for info inmain_infos:if i: #此處i的作用是跳過第一次循環,因為第一個是非天氣數據
i =Falsecontinue
else:
date= info.xpath('td[1]/a/text()')[0].replace("\r\n", '').replace(' ', '') #去掉換行符、空格等,下同
weather = info.xpath('td[2]/text()')[0].replace("\r\n", '').replace(' ', '')
temps= info.xpath('td[3]/text()')[0].replace('\r\n', '').replace(' ', '')
clouds= info.xpath('td[4]/text()')[0].replace("\r\n", '').replace(' ', '')
with open('Nanjing.csv', 'a+', newline='', encoding='utf-8')as fp: #存入csv文件
writer =csv.writer(fp)
writer.writerow((date, weather, temps, clouds))exceptIndexError:pass
步驟三
接下來執行主程序存儲就行了,使用了多進程來爬取加快速度,所以爬取的數據排列可能不按順序,使用wps或excel自行排序即可。
下方附上剩余代碼:
importrequestsfrom lxml importetreeimporttimeimportcsvfrom multiprocessing importPool#請求頭
headers ={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'}if __name__ == '__main__': #執行主程序
url = 'http://www.tianqihoubao.com/lishi/nanjing.html' #獲取月份天氣url的網址
get_mainurl(url)
details=link_url(url)
with open('Nanjing.csv', 'a+', newline='', encoding='utf-8')as ff: #寫入第一行作為表頭
writer =csv.writer(ff)
writer.writerow(('日期', '天氣狀況', '氣溫', '風力風向'))
pool= Pool(processes=4) #使用多進程爬取
pool.map(get_infos, details) #需要注意爬取結果并不是按順序的,可以用excel進行排序
部分數據如下:
步驟四
進行數據分析之前,先用pandas的read_csv()方法將數據讀出,然后將2011-2018年的溫度和天氣狀況提取出來進行分析,這里溫度需要將數字提取出來,天氣狀況需要將 ‘/’去掉,還有因為一天的天氣數據是多個的(例如一天氣溫有最高溫和最低溫),所以后面分析時發現數據量大于8年總天數,這是正常的。
由于我也是第一次使用pyecharts,所以話不多說,直接上代碼:
1 importpandas as pd2 from pyecharts importLine, Pie, Page, Bar3
4
5 page = Page(page_title='南京氣溫分析') #page 使多個圖位于一個網頁,網頁名
6
7 pd.set_option('display.max_rows', None) #設置使dataframe 所有行都顯示
8 df = pd.read_csv('Nanjing.csv') #讀取天氣數據
9
10 #獲取最高氣溫
11 Max_temps =[]12 for max_data in df['氣溫']:13 Max_temps.append(int(max_data[0:2].replace('℃','')))14 Max_temps = Max_temps[:-109]15
16 #獲取最低氣溫
17 Low_temps =[]18 for low_data in df['氣溫']:19 Low_temps.append(int(low_data[-3:-1].replace('/', '')))20 Low_temps = Low_temps[:-109]21
22 #獲取2011年一月氣溫數據
23 attr = ['{}號'.format(str(i))for i in range(1,32)]24 Jan_Htemps = Max_temps[:31]25 Jan_Ltemps = Low_temps[:31]26 #繪制氣溫折線圖
27 line = Line('南京市2011年一月氣溫變化') #賦予將折線圖對象, 命名
28 line.add('當日最高氣溫', attr, Jan_Htemps, mark_point=['average', 'max', 'min'], #顯示平均、最大/小值
29 mark_point_symbol='diamond', #特殊點用鉆石形狀顯示
30 mark_point_textcolor='red', #標注點顏色
31 is_smooth=True #圖像光滑
32 )33 line.add('當日最低氣溫', attr, Jan_Ltemps, mark_point=['average', 'max', 'min'],34 mark_point_symbol='arrow',35 mark_point_textcolor='blue'
36 )37 line.use_theme('dark') #背景顏色
38 line.show_config() #調試輸出pyecharts的js配置信息
39 page.add_chart(line) #添加到page
40
41 #統計2011-2018年的每天最高溫的氣溫分布情況,分四個階梯
42 Hzero_down = Hthrity_up = Hzup_fifdown = Hfifup_thrdown =043 for i inMax_temps:44 if i <=0:45 Hzero_down += 1
46 elif i<=15:47 Hzup_fifdown += 1
48 elif i<=30:49 Hfifup_thrdown += 1
50 else:51 Hthrity_up +=1
52
53 #統計2011-2018年的每天最高溫的氣溫分布情況分,分四個階層
54 Lfiv_down = L25_up = Lfiv_tendown = Ltenup_25down =055 for i inLow_temps:56 if i <= -5:57 Lfiv_down += 1
58 elif i<=10:59 Lfiv_tendown += 1
60 elif i<=25:61 Ltenup_25down += 1
62 else:63 L25_up +=1
64
65 #繪圖
66 attr2 = ['0℃及以下', '0-15℃', '15-30℃', '30℃及以上'] #標簽屬性
67 H_data = [Hzero_down, Hzup_fifdown, Hfifup_thrdown, Hthrity_up] #數據
68 pie = Pie('南京市2011年-2018年每日最高氣溫分布', title_pos='center', title_color='red') #繪制餅圖,標題位于中間,標題顏色
69 pie.add('',attr2, H_data, is_label_show=True, #展示標簽
70 legend_pos='right', legend_orient='vertical', #標簽位置,標簽排列
71 label_text_color=True, legend_text_color=True, #標簽顏色
72 )73 pie.show_config()74 page.add_chart(pie, name='餅圖')75
76 #繪制環形圖
77 attr3 = ['-5℃及以下', '-5-10℃', '10-25℃', '25℃及以上']78 L_data =[Lfiv_down, Lfiv_tendown, Ltenup_25down, L25_up]79 pie2 = Pie('南京市2011年-2018年每日最低氣溫分布', title_pos='center')80 pie2.add('',attr3, L_data, radius=[30, 70], is_label_show=True, #radius環形圖內外圓半徑
81 label_text_color=None, legend_orient='vertical',82 legend_pos='left', legend_text_color=None83 )84 pie2.show_config()85 page.add_chart(pie2, name='環形圖')86
87
88 #繪制南京2011-2018年天氣狀況條形統計圖
89 Weather_NJ =[]90 for Weathers in df['天氣狀況']:91 Weather_s = Weathers.split('/')92 Weather_NJ.append(Weather_s[0])93 Weather_NJ.append(Weather_s[1])94 Weather_NJ = Weather_NJ[:-218]95
96 sunny = rainy = yin_cloudy = lightening = duo_cloudy = snowy =097 for t inWeather_NJ:98 if t == '晴':99 sunny += 1
100 elif t == '陰':101 yin_cloudy += 1
102 elif t == '多云':103 duo_cloudy += 1
104 elif t == '雷陣雨':105 lightening += 1
106 elif '雨' in t and t != '雨夾雪':107 rainy += 1
108 elif '雪' int:109 snowy += 1
110 else:111 pass
112 Weather_attr = ['晴', '雨天', '多云', '陰天', '雷陣雨', '雪天']113 Weather_datas =[sunny, rainy, duo_cloudy, yin_cloudy, lightening, snowy]114 bar = Bar('南京市2011-2018年天氣情況統計', '注意:一天有兩個天氣變化,部分日期天氣情況可能丟失', title_pos='center')115 bar.add('天氣狀況', Weather_attr, Weather_datas, is_more_utils=True,116 mark_point=['max', 'min'], legend_pos='right'
117 )118 bar.show_config()119 page.add_chart(bar)120
121 page.render('all_analysis.html') #網頁地址
圖像結果如下:
是不是發現使用pyecharts得到的圖表更加好看,這里上傳的圖片是靜態的,在網頁打開的時查看其實是動態的。
這里只爬取了南京市的歷史天氣,感興趣的朋友可以嘗試爬取更多城市的,甚至可以在此基礎上編寫一個小軟件,隨時隨地查看不同地區的歷史天氣,不過前提是該網站的源代碼不發生大變動。
本次分享就到此為止,如果有錯誤或者疑問或者是建議歡迎大家隨時指正,我也會積極回應。
總結
以上是生活随笔為你收集整理的python获取天气分析_Python爬取南京市往年天气预报,使用pyecharts进行分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 隆鼻多少钱?
- 下一篇: pyqt5点击按钮后关联程序一直运行指导