python获取天气分析_Python爬取南京市往年天气预报,使用pyecharts进行分析
上一次分享了使用matplotlib對(duì)爬取的豆瓣書籍排行榜進(jìn)行分析,但是發(fā)現(xiàn)python本身自帶的這個(gè)繪圖分析庫(kù)還是有一些局限,繪圖不夠美觀等,在網(wǎng)上搜索了一波,發(fā)現(xiàn)現(xiàn)在有很多的支持python的繪圖庫(kù)可以使用,本次嘗試使用pyecharts對(duì)爬取的數(shù)據(jù)進(jìn)行分析,然后發(fā)現(xiàn)這個(gè)庫(kù)實(shí)在是太好用了,生成的庫(kù)也很好看,還能生成動(dòng)態(tài)圖,簡(jiǎn)直是進(jìn)行數(shù)據(jù)分析的一大神器!
pyecharts:pyecharts是一個(gè)封裝百度開源圖表庫(kù)echarts的包,使用pyecharts可以生成獨(dú)立的網(wǎng)頁,也可以在flask、django中集成使用。
本次爬取的首頁地址是:
http://www.tianqihoubao.com/lishi/nanjing.html
爬取步驟:
爬取主網(wǎng)頁,獲取進(jìn)入每個(gè)南京市具體年份月份的天氣數(shù)據(jù)的鏈接
爬取上方獲取的具體鏈接的數(shù)據(jù)
存儲(chǔ)數(shù)據(jù)
對(duì)數(shù)據(jù)進(jìn)行篩選后使用pyecharts進(jìn)行分析
話不多說,馬上開始吧!
步驟一
從上圖可知,我們需要先獲取進(jìn)入每個(gè)具體月份的鏈接,才能爬取想要的數(shù)據(jù),所以首先定義獲取具體鏈接的函數(shù),然后在爬取會(huì)方便很多;查看網(wǎng)頁源代碼查找目標(biāo)所在位置,本次我依然是使用lxml庫(kù)來進(jìn)行數(shù)據(jù)的爬取(PS:感覺習(xí)慣了lxml其他庫(kù)就不好用了),這里需要注意的是,我是將獲得的結(jié)果一個(gè)一個(gè)的存入列表,這種方法很笨,但作為菜鳥的我確實(shí)不知道其他方法了,還有就是發(fā)現(xiàn)爬取的部分鏈接缺了一點(diǎn),所以又定義了一個(gè)函數(shù)來補(bǔ)上。
具體代碼如下:?????????? 注:轉(zhuǎn)載代碼請(qǐng)標(biāo)明出處
1 def get_mainurl(url): #定義獲取月份天氣的詳細(xì)url 函數(shù)
2 res = requests.get(url, headers=headers)3 main_url =[]4 if res.status_code == 200: #判斷請(qǐng)求狀態(tài)
5 selector =etree.HTML(res.text)6 htmlurls = selector.xpath('//div[contains(@id,"content")]/div') #循環(huán)點(diǎn)
7 try:8 for htmlurl inhtmlurls:9 Jan = htmlurl.xpath('ul[1]/li[2]/a/@href')[0] #一月份天氣url
10 main_url.append(Jan) #將網(wǎng)址放入列表中,一個(gè)一個(gè)放是很蠢的方法,但我也確實(shí)不知道其他方法了,下同
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是不完整的,此函數(shù)使其完整
43 final_urls=[]44 list_urls =get_mainurl(url)45 for list_url inlist_urls:46 if len(list_url) < 30: #因?yàn)楂@取的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
步驟二
接下來是獲取所需的數(shù)據(jù),遍歷所在節(jié)點(diǎn)就行了,需要注意的是要跳過第一個(gè)節(jié)點(diǎn),因?yàn)槠鋬?nèi)部沒有內(nèi)容。
代碼如下:
def get_infos(detail_url): #爬取月份天氣詳細(xì)數(shù)據(jù)函數(shù)
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的作用是跳過第一次循環(huán),因?yàn)榈谝粋€(gè)是非天氣數(shù)據(jù)
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
步驟三
接下來執(zhí)行主程序存儲(chǔ)就行了,使用了多進(jìn)程來爬取加快速度,所以爬取的數(shù)據(jù)排列可能不按順序,使用wps或excel自行排序即可。
下方附上剩余代碼:
importrequestsfrom lxml importetreeimporttimeimportcsvfrom multiprocessing importPool#請(qǐng)求頭
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__': #執(zhí)行主程序
url = 'http://www.tianqihoubao.com/lishi/nanjing.html' #獲取月份天氣url的網(wǎng)址
get_mainurl(url)
details=link_url(url)
with open('Nanjing.csv', 'a+', newline='', encoding='utf-8')as ff: #寫入第一行作為表頭
writer =csv.writer(ff)
writer.writerow(('日期', '天氣狀況', '氣溫', '風(fēng)力風(fēng)向'))
pool= Pool(processes=4) #使用多進(jìn)程爬取
pool.map(get_infos, details) #需要注意爬取結(jié)果并不是按順序的,可以用excel進(jìn)行排序
部分?jǐn)?shù)據(jù)如下:
步驟四
進(jìn)行數(shù)據(jù)分析之前,先用pandas的read_csv()方法將數(shù)據(jù)讀出,然后將2011-2018年的溫度和天氣狀況提取出來進(jìn)行分析,這里溫度需要將數(shù)字提取出來,天氣狀況需要將 ‘/’去掉,還有因?yàn)橐惶斓奶鞖鈹?shù)據(jù)是多個(gè)的(例如一天氣溫有最高溫和最低溫),所以后面分析時(shí)發(fā)現(xiàn)數(shù)據(jù)量大于8年總天數(shù),這是正常的。
由于我也是第一次使用pyecharts,所以話不多說,直接上代碼:
1 importpandas as pd2 from pyecharts importLine, Pie, Page, Bar3
4
5 page = Page(page_title='南京氣溫分析') #page 使多個(gè)圖位于一個(gè)網(wǎng)頁,網(wǎng)頁名
6
7 pd.set_option('display.max_rows', None) #設(shè)置使dataframe 所有行都顯示
8 df = pd.read_csv('Nanjing.csv') #讀取天氣數(shù)據(jù)
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年一月氣溫?cái)?shù)據(jù)
23 attr = ['{}號(hào)'.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年一月氣溫變化') #賦予將折線圖對(duì)象, 命名
28 line.add('當(dāng)日最高氣溫', attr, Jan_Htemps, mark_point=['average', 'max', 'min'], #顯示平均、最大/小值
29 mark_point_symbol='diamond', #特殊點(diǎn)用鉆石形狀顯示
30 mark_point_textcolor='red', #標(biāo)注點(diǎn)顏色
31 is_smooth=True #圖像光滑
32 )33 line.add('當(dāng)日最低氣溫', 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() #調(diào)試輸出pyecharts的js配置信息
39 page.add_chart(line) #添加到page
40
41 #統(tǒng)計(jì)2011-2018年的每天最高溫的氣溫分布情況,分四個(gè)階梯
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 #統(tǒng)計(jì)2011-2018年的每天最高溫的氣溫分布情況分,分四個(gè)階層
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℃及以上'] #標(biāo)簽屬性
67 H_data = [Hzero_down, Hzup_fifdown, Hfifup_thrdown, Hthrity_up] #數(shù)據(jù)
68 pie = Pie('南京市2011年-2018年每日最高氣溫分布', title_pos='center', title_color='red') #繪制餅圖,標(biāo)題位于中間,標(biāo)題顏色
69 pie.add('',attr2, H_data, is_label_show=True, #展示標(biāo)簽
70 legend_pos='right', legend_orient='vertical', #標(biāo)簽位置,標(biāo)簽排列
71 label_text_color=True, legend_text_color=True, #標(biāo)簽顏色
72 )73 pie.show_config()74 page.add_chart(pie, name='餅圖')75
76 #繪制環(huán)形圖
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環(huán)形圖內(nèi)外圓半徑
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='環(huán)形圖')86
87
88 #繪制南京2011-2018年天氣狀況條形統(tǒng)計(jì)圖
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年天氣情況統(tǒng)計(jì)', '注意:一天有兩個(gè)天氣變化,部分日期天氣情況可能丟失', 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') #網(wǎng)頁地址
圖像結(jié)果如下:
是不是發(fā)現(xiàn)使用pyecharts得到的圖表更加好看,這里上傳的圖片是靜態(tài)的,在網(wǎng)頁打開的時(shí)查看其實(shí)是動(dòng)態(tài)的。
這里只爬取了南京市的歷史天氣,感興趣的朋友可以嘗試爬取更多城市的,甚至可以在此基礎(chǔ)上編寫一個(gè)小軟件,隨時(shí)隨地查看不同地區(qū)的歷史天氣,不過前提是該網(wǎng)站的源代碼不發(fā)生大變動(dòng)。
本次分享就到此為止,如果有錯(cuò)誤或者疑問或者是建議歡迎大家隨時(shí)指正,我也會(huì)積極回應(yīng)。
總結(jié)
以上是生活随笔為你收集整理的python获取天气分析_Python爬取南京市往年天气预报,使用pyecharts进行分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 隆鼻多少钱?
- 下一篇: pyqt5点击按钮后关联程序一直运行指导