Python天气查询系统(连接数据库版)
?作為一名大三的準(zhǔn)程序員,這學(xué)期學(xué)了一門叫做腳本程序設(shè)計(jì)的課程,剛好很感興趣,于是做了一個(gè)相關(guān)的爬蟲系統(tǒng),目前只能算是半成品,因?yàn)檫€想到了很多可以跟進(jìn)的地方,但奈何知識(shí)儲(chǔ)備不夠,所以先發(fā)布一下目前的版本。
我爬取的是中國氣象網(wǎng)的天氣預(yù)報(bào)
成都天氣預(yù)報(bào),成都7天天氣預(yù)報(bào),成都15天天氣預(yù)報(bào),成都天氣查詢
下面我一 一講解一下我寫的代碼
目錄
觀察連接
判斷城市是否存在?
獲取url
請求獲取網(wǎng)頁內(nèi)容
處理信息
保存csv
創(chuàng)建數(shù)據(jù)庫表單
存儲(chǔ)數(shù)據(jù)到數(shù)據(jù)庫
繪制當(dāng)天溫度曲線
繪制15天溫度曲線
相對濕度曲線繪制
空氣質(zhì)量曲線繪制
風(fēng)向雷達(dá)圖繪制
繪制天氣餅圖
main主函數(shù)
全部代碼展示
觀察連接
首先,我們要先觀察這個(gè)連接,他有什么獨(dú)特之處。成都天氣預(yù)報(bào),成都7天天氣預(yù)報(bào),成都15天天氣預(yù)報(bào),成都天氣查詢
通過觀察,我們發(fā)現(xiàn)了兩個(gè)獨(dú)特之處。
首先,就是weather1d,我在這里給大家解釋一下,其中的‘1d’代表當(dāng)天的天氣情況,之后還會(huì)用到‘15d’,它代表的便是未來14天的天氣情況
然后就是101270101這串?dāng)?shù)字編碼,這其實(shí)是成都的城市編碼,我當(dāng)時(shí)看了一下中國氣象網(wǎng)的源文件,并沒有找到所以城市的編碼,無奈只好問問度娘,下面我把城市編碼放上來
北京:101010100都江堰:101270111朝陽:101010300順義:101010400懷柔:101010500通州:101010600昌平:101010700延慶:101010800豐臺(tái):101010900石景山:101011000大興:101011100房山:101011200密云:101011300門頭溝:101011400平谷:101011500八達(dá)嶺:101011600佛爺頂:101011700湯河口:101011800密云上甸子:101011900齋堂:101012000霞云嶺:101012100北京城區(qū):101012200海淀:101010200天津:101030100寶坻:101030300東麗:101030400西青:101030500北辰:101030600薊縣:101031400漢沽:101030800靜海:101030900津南:101031000塘沽:101031100大港:101031200武清:101030200寧河:101030700上海:101020100寶山:101020300嘉定:101020500南匯:101020600浦東:101021300青浦:101020800松江:101020900奉賢:101021000崇明:101021100徐家匯:101021200閔行:101020200金山:101020700石家莊:101090101張家口:101090301承德:101090402唐山:101090501秦皇島:101091101滄州:101090701衡水:101090801邢臺(tái):101090901邯鄲:101091001保定:101090201廊坊:101090601鄭州:101180101新鄉(xiāng):101180301許昌:101180401平頂山:101180501信陽:101180601南陽:101180701開封:101180801洛陽:101180901商丘:101181001焦作:101181101鶴壁:101181201濮陽:101181301周口:101181401漯河:101181501駐馬店:101181601三門峽:101181701濟(jì)源:101181801安陽:101180201合肥:101220101蕪湖:101220301淮南:101220401馬鞍山:101220501安慶:101220601宿州:101220701阜陽:101220801亳州:101220901黃山:101221001滁州:101221101淮北:101221201銅陵:101221301宣城:101221401六安:101221501巢湖:101221601池州:101221701蚌埠:101220201杭州:101210101舟山:101211101湖州:101210201嘉興:101210301金華:101210901紹興:101210501臺(tái)州:101210601溫州:101210701麗水:101210801衢州:101211001寧波:101210401重慶:101040100合川:101040300南川:101040400江津:101040500萬盛:101040600渝北:101040700北碚:101040800巴南:101040900長壽:101041000黔江:101041100萬州天城:101041200萬州龍寶:101041300涪陵:101041400開縣:101041500城口:101041600云陽:101041700巫溪:101041800奉節(jié):101041900巫山:101042000潼南:101042100墊江:101042200梁平:101042300忠縣:101042400石柱:101042500大足:101042600榮昌:101042700銅梁:101042800璧山:101042900豐都:101043000武隆:101043100彭水:101043200綦江:101043300酉陽:101043400秀山:101043600沙坪壩:101043700永川:101040200福州:101230101泉州:101230501漳州:101230601龍巖:101230701晉江:101230509南平:101230901廈門:101230201寧德:101230301莆田:101230401三明:101230801蘭州:101160101平?jīng)?101160301慶陽:101160401武威:101160501金昌:101160601嘉峪關(guān):101161401酒泉:101160801天水:101160901武都:101161001臨夏:101161101合作:101161201白銀:101161301定西:101160201張掖:101160701廣州:101280101惠州:101280301梅州:101280401汕頭:101280501深圳:101280601珠海:101280701佛山:101280800肇慶:101280901湛江:101281001江門:101281101河源:101281201清遠(yuǎn):101281301云浮:101281401潮州:101281501東莞:101281601中山:101281701陽江:101281801揭陽:101281901茂名:101282001汕尾:101282101韶關(guān):101280201南寧:101300101柳州:101300301來賓:101300401桂林:101300501梧州:101300601防城港:101301401貴港:101300801玉林:101300901百色:101301001欽州:101301101河池:101301201北海:101301301崇左:101300201賀州:101300701貴陽:101260101安順:101260301都勻:101260401興義:101260906銅仁:101260601畢節(jié):101260701六盤水:101260801遵義:101260201凱里:101260501昆明:101290101紅河:101290301文山:101290601玉溪:101290701楚雄:101290801普洱:101290901昭通:101291001臨滄:101291101怒江:101291201香格里拉:101291301麗江:101291401德宏:101291501景洪:101291601大理:101290201曲靖:101290401保山:101290501呼和浩特:101080101烏海:101080301集寧:101080401通遼:101080501阿拉善左旗:101081201鄂爾多斯:101080701臨河:101080801錫林浩特:101080901呼倫貝爾:101081000烏蘭浩特:101081101包頭:101080201赤峰:101080601南昌:101240101上饒:101240301撫州:101240401宜春:101240501鷹潭:101241101贛州:101240701景德鎮(zhèn):101240801萍鄉(xiāng):101240901新余:101241001九江:101240201吉安:101240601武漢:101200101黃岡:101200501荊州:101200801宜昌:101200901恩施:101201001十堰:101201101神農(nóng)架:101201201隨州:101201301荊門:101201401天門:101201501仙桃:101201601潛江:101201701襄樊:101200201鄂州:101200301孝感:101200401黃石:101200601咸寧:101200701成都:101270101自貢:101270301綿陽:101270401南充:101270501達(dá)州:101270601遂寧:101270701廣安:101270801巴中:101270901瀘州:101271001宜賓:101271101內(nèi)江:101271201資陽:101271301樂山:101271401眉山:101271501涼山:101271601雅安:101271701甘孜:101271801阿壩:101271901德陽:101272001廣元:101272101攀枝花:101270201銀川:101170101中衛(wèi):101170501固原:101170401石嘴山:101170201吳忠:101170301西寧:101150101黃南:101150301海北:101150801果洛:101150501玉樹:101150601海西:101150701海東:101150201海南:101150401濟(jì)南:101120101濰坊:101120601臨沂:101120901菏澤:101121001濱州:101121101東營:101121201威海:101121301棗莊:101121401日照:101121501萊蕪:101121601聊城:101121701青島:101120201淄博:101120301德州:101120401煙臺(tái):101120501濟(jì)寧:101120701泰安:101120801西安:101110101延安:101110300榆林:101110401銅川:101111001商洛:101110601安康:101110701漢中:101110801寶雞:101110901咸陽:101110200渭南:101110501太原:101100101臨汾:101100701運(yùn)城:101100801朔州:101100901忻州:101101001長治:101100501大同:101100201陽泉:101100301晉中:101100401晉城:101100601呂梁:101101100烏魯木齊:101130101石河子:101130301昌吉:101130401吐魯番:101130501庫爾勒:101130601阿拉爾:101130701阿克蘇:101130801喀什:101130901伊寧:101131001塔城:101131101哈密:101131201和田:101131301阿勒泰:101131401阿圖什:101131501博樂:101131601克拉瑪依:101130201拉薩:101140101山南:101140301阿里:101140701昌都:101140501那曲:101140601日喀則:101140201林芝:101140401臺(tái)北縣:101340101高雄:101340201臺(tái)中:101340401海口:101310101三亞:101310201東方:101310202臨高:101310203澄邁:101310204儋州:101310205昌江:101310206白沙:101310207瓊中:101310208定安:101310209屯昌:101310210瓊海:101310211文昌:101310212保亭:101310214萬寧:101310215陵水:101310216西沙:101310217南沙島:101310220樂東:101310221五指山:101310222瓊山:101310102長沙:101250101株洲:101250301衡陽:101250401郴州:101250501常德:101250601益陽:101250700婁底:101250801邵陽:101250901岳陽:101251001張家界:101251101懷化:101251201黔陽:101251301永州:101251401吉首:101251501湘潭:101250201南京:101190101鎮(zhèn)江:101190301蘇州:101190401南通:101190501揚(yáng)州:101190601宿遷:101191301徐州:101190801淮安:101190901連云港:101191001常州:101191101泰州:101191201無錫:101190201鹽城:101190701哈爾濱:101050101牡丹江:101050301佳木斯:101050401綏化:101050501黑河:101050601雙鴨山:101051301伊春:101050801大慶:101050901七臺(tái)河:101051002雞西:101051101鶴崗:101051201齊齊哈爾:101050201大興安嶺:101050701長春:101060101延吉:101060301四平:101060401白山:101060901白城:101060601遼源:101060701松原:101060801吉林:101060201通化:101060501沈陽:101070101鞍山:101070301撫順:101070401本溪:101070501丹東:101070601葫蘆島:101071401營口:101070801阜新:101070901遼陽:101071001鐵嶺:101071101朝陽:101071201盤錦:101071301大連:101070201錦州:101070701判斷城市是否存在?
既然我們需要按城市查詢天氣預(yù)報(bào),那么我們就需要判斷一下該城市是否存在,函數(shù)如下
"""判斷城市是否存在""" def Judge(city_name):city = re.compile(r'(?<={}:)\d*'.format(city_name))str1 = open('城市代碼.txt', 'r')new_str = str1.readlines()try:city_coding = city.search(str(new_str)).group(0)city_coding = city_namereturn city_nameexcept:return "你這兒是那個(gè)山卡卡"# print(city_coding)??這里用了正則,如果不熟悉正則的小伙伴,可以先在菜鳥教程在線正則編譯器進(jìn)行正則的審核工作,這里也推薦一本關(guān)于正則的書《正則表達(dá)式必知必會(huì)》,這本書消化了的話,正則簡直就是信手拈來。
獲取url
接下來便是通過我們所需要查詢的城市,獲取相應(yīng)的url,相應(yīng)函數(shù)如下:
"""獲取url""" def getURL(city_name):base_url = 'http://www.weather.com.cn/weather/{}.shtml'city = re.compile(r'(?<={}:)\d*'.format(city_name))str1 = open('城市代碼.txt', 'r')# print(str.readlines())new_str = str1.readlines()# print(new_str)# print(city.search(str).group(0))city_coding = city.search(str(new_str)).group(0)# print(city_coding)#new_url = base_url.format(city_coding)# print(new_url)return new_urldef getURL2(city_name):base_url = 'http://www.weather.com.cn/weather15d/{}.shtml'city = re.compile(r'(?<={}:)\d*'.format(city_name))str1 = open('城市代碼.txt', 'r')# print(str.readlines())new_str = str1.readlines()# print(new_str)# print(city.search(str).group(0))city_coding = city.search(str(new_str)).group(0)# print(city_coding)#new_url = base_url.format(city_coding)# print(new_url)return new_url這里說一句,以前看著大家用format不以為意,結(jié)果自己寫了這個(gè)才知道format才是yyds。
這里面的open('城市代碼.txt', 'r'),中的'城市代碼.txt',需要大家自行創(chuàng)建一個(gè)txt文檔,然后把本文開頭發(fā)的城市代碼全部復(fù)制進(jìn)去才可運(yùn)行
請求獲取網(wǎng)頁內(nèi)容
我們獲取了url之后,就該通過相應(yīng)的url請求網(wǎng)頁內(nèi)容了,
相關(guān)函數(shù)如下
"""請求獲得網(wǎng)頁內(nèi)容""" def getHTMLtext(url,city_name):"""請求獲得網(wǎng)頁內(nèi)容"""try:headers = {"User-Agent": UserAgent().random,}r = requests.get(url, timeout=30, headers=headers)r.raise_for_status()r.encoding = r.apparent_encodingprint("中國氣象網(wǎng){}24小時(shí)天氣訪問成功".format(city_name))return r.textexcept:print("中國氣象網(wǎng){}24小時(shí)天氣訪問失敗".format(city_name))return " "def getHTMLtext2(url,city_name):"""請求獲得網(wǎng)頁內(nèi)容"""try:headers = {"User-Agent": UserAgent().random,}r = requests.get(url, timeout=30, headers=headers)r.raise_for_status()r.encoding = r.apparent_encodingprint("中國氣象網(wǎng){}15天天氣訪問成功".format(city_name))return r.textexcept:print("中國氣象網(wǎng){}15天天氣訪問失敗".format(city_name))return " "這里用了一組try/except,本人不是太喜歡看到紅色報(bào)錯(cuò),所以如果訪問失敗,會(huì)直接返回print中的內(nèi)容?,前文也有一組,同樣的道理。
處理信息
處理有用的數(shù)據(jù),并暫時(shí)保存起來,
相關(guān)代碼如下
"""處理得到有用信息保存數(shù)據(jù)文件""" def get_content(html):final = [] # 初始化一個(gè)列表保存數(shù)據(jù)bs = BeautifulSoup(html, "html.parser") # 創(chuàng)建BeautifulSoup對象body = bs.bodydata = body.find('div', {'id': '7d'}) # 找到div標(biāo)簽且id = 7d# 下面爬取當(dāng)天的數(shù)據(jù)data2 = body.find_all('div', {'class': 'left-div'})text = data2[2].find('script').stringtext = text[text.index('=') + 1:-2] # 移除改var data=將其變?yōu)閖son數(shù)據(jù)jd = json.loads(text)dayone = jd['od']['od2'] # 找到當(dāng)天的數(shù)據(jù)final_day = [] # 存放當(dāng)天的數(shù)據(jù)count = 0for i in dayone:temp = []if count <= 23:temp.append(i['od21']) # 添加時(shí)間temp.append(i['od22']) # 添加當(dāng)前時(shí)刻溫度temp.append(i['od24']) # 添加當(dāng)前時(shí)刻風(fēng)力方向temp.append(i['od25']) # 添加當(dāng)前時(shí)刻風(fēng)級(jí)temp.append(i['od26']) # 添加當(dāng)前時(shí)刻降水量temp.append(i['od27']) # 添加當(dāng)前時(shí)刻相對濕度temp.append(i['od28']) # 添加當(dāng)前時(shí)刻控制質(zhì)量# print(temp)final_day.append(temp)count = count + 1return final_daydef get_content1_7(html):# 下面爬取7天的數(shù)據(jù)final = [] # 初始化一個(gè)列表保存數(shù)據(jù)bs = BeautifulSoup(html, "html.parser") # 創(chuàng)建BeautifulSoup對象body = bs.bodydata = body.find('div', {'id': '7d'}) # 找到div標(biāo)簽且id = 7dul = data.find('ul') # 找到所有的ul標(biāo)簽li = ul.find_all('li') # 找到左右的li標(biāo)簽i = 0 # 控制爬取的天數(shù)for day in li: # 遍歷找到的每一個(gè)liif 7 > i > 0:temp = [] # 臨時(shí)存放每天的數(shù)據(jù)date = day.find('h1').string # 得到日期date = date[0:date.index('日')] # 取出日期號(hào)temp.append(date)inf = day.find_all('p') # 找出li下面的p標(biāo)簽,提取第一個(gè)p標(biāo)簽的值,即天氣temp.append(inf[0].string)tem_low = inf[1].find('i').string # 找到最低氣溫if inf[1].find('span') is None: # 天氣預(yù)報(bào)可能沒有最高氣溫tem_high = Noneelse:tem_high = inf[1].find('span').string # 找到最高氣溫temp.append(tem_low[:-1])if tem_high[-1] == '℃':temp.append(tem_high[:-1])else:temp.append(tem_high)wind = inf[2].find_all('span') # 找到風(fēng)向for j in wind:temp.append(j['title'])wind_scale = inf[2].find('i').string # 找到風(fēng)級(jí)index1 = wind_scale.index('級(jí)')temp.append(int(wind_scale[index1 - 1:index1]))final.append(temp)i = i + 1return finaldef get_content8_14(html):"""處理得到有用信息保存數(shù)據(jù)文件"""final = [] # 初始化一個(gè)列表保存數(shù)據(jù)bs = BeautifulSoup(html, "html.parser") # 創(chuàng)建BeautifulSoup對象body = bs.bodydata = body.find('div', {'id': '15d'}) # 找到div標(biāo)簽且id = 15dul = data.find('ul') # 找到所有的ul標(biāo)簽li = ul.find_all('li') # 找到左右的li標(biāo)簽# final = []i = 0 # 控制爬取的天數(shù)for day in li: # 遍歷找到的每一個(gè)liif i < 8:temp = [] # 臨時(shí)存放每天的數(shù)據(jù)date = day.find('span', {'class': 'time'}).string # 得到日期date = date[date.index('(') + 1:-2] # 取出日期號(hào)temp.append(date)weather = day.find('span', {'class': 'wea'}).string # 找到天氣temp.append(weather)tem = day.find('span', {'class': 'tem'}).text # 找到溫度temp.append(tem[tem.index('/') + 1:-1]) # 找到最低氣溫temp.append(tem[:tem.index('/') - 1]) # 找到最高氣溫wind = day.find('span', {'class': 'wind'}).string # 找到風(fēng)向if '轉(zhuǎn)' in wind: # 如果有風(fēng)向變化temp.append(wind[:wind.index('轉(zhuǎn)')])temp.append(wind[wind.index('轉(zhuǎn)') + 1:])else: # 如果沒有風(fēng)向變化,前后風(fēng)向一致temp.append(wind)temp.append(wind)wind_scale = day.find('span', {'class': 'wind1'}).string # 找到風(fēng)級(jí)index1 = wind_scale.index('級(jí)')temp.append(int(wind_scale[index1 - 1:index1]))final.append(temp)return final一開始我用的是XPath,但是這個(gè)中國氣象網(wǎng)中網(wǎng)頁源代碼,和網(wǎng)頁代碼不一樣,要用tbody,這個(gè)問題當(dāng)時(shí)卡了我好幾天。?最后實(shí)在不想被惡心下去,又學(xué)了一下beautifusoup,用beautifulsoup解決了這里的問題。
保存csv
保存數(shù)據(jù)到csv文件,
、相關(guān)代碼如下
"""保存為csv文件""" def write_to_csv(file_name, data, day=14):"""保存為csv文件"""with open(file_name, 'w', errors='ignore', newline='') as f:if day == 14:header = ['日期', '天氣', '最低氣溫', '最高氣溫', '風(fēng)向1', '風(fēng)向2', '風(fēng)級(jí)']else:header = ['小時(shí)', '溫度', '風(fēng)力方向', '風(fēng)級(jí)', '降水量', '相對濕度', '空氣質(zhì)量']f_csv = csv.writer(f)f_csv.writerow(header)f_csv.writerows(data)由于我們訪問了兩個(gè)網(wǎng)頁,訪問所暫存的數(shù)據(jù)也不一樣,所以我們需要判斷一下是24小時(shí)的數(shù)據(jù)還是14天的數(shù)據(jù)?
創(chuàng)建數(shù)據(jù)庫表單
"""創(chuàng)建表""" def Creat_Table(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()cursor.execute('DROP TABLE IF EXISTS {}weather'.format(city_name))sql_set = 'CREATE TABLE IF NOT EXISTS {}weather(Time INT,Temperature INT ,' \'wind_direction VARCHAR(255), wind INT, rainfall INT, Humidity INT)'.format(city_name)try:cursor.execute(sql_set)con.commit()print('創(chuàng)建{}24小時(shí)天氣情況數(shù)據(jù)表成功'.format(city_name))except:con.rollback()print("創(chuàng)建{}24小時(shí)天氣情況數(shù)據(jù)表失敗".format(city_name))con.close()def Creat_Table14(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()cursor.execute('DROP TABLE IF EXISTS {}weather14d'.format(city_name))sql_set = 'CREATE TABLE IF NOT EXISTS {}weather14d(Date INT,Weather VARCHAR(255) ,' \'Min_temperature INT, Max_temperature INT, wind_direction_1 VARCHAR(255), wind_direction_2 VARCHAR(255), wind_level INT)'.format(city_name)try:cursor.execute(sql_set)con.commit()print('創(chuàng)建{}15天天氣情況數(shù)據(jù)表成功'.format(city_name))except:con.rollback()print('創(chuàng)建{}15天天氣情況數(shù)據(jù)表失敗'.format(city_name))con.close()如果大家需要copy的話,記得改這兒的數(shù)據(jù)庫相應(yīng)的值噢?
存儲(chǔ)數(shù)據(jù)到數(shù)據(jù)庫
??相關(guān)代碼如下
"""在表中插入數(shù)據(jù)""" def insert_data1(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()data1 = pd.read_csv('天氣預(yù)報(bào)-{}24小時(shí)天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')for i in range(data1.shape[0]):Time = list(data1['小時(shí)'])[i]Temperature = list(data1['溫度'])[i]wind_direction = list(data1['風(fēng)力方向'])[i]wind = list(data1['風(fēng)級(jí)'])[i]rainfall = list(data1['降水量'])[i]Humidity = list(data1['相對濕度'])[i]# Time = list(data1['空氣質(zhì)量'])[1]data = (Time, Temperature, wind_direction, wind, rainfall, Humidity)sql = "INSERT INTO {}weather(Time, Temperature, wind_direction, wind, rainfall, Humidity) values ".format(city_name) + str(data) + ";"try:cursor.execute(sql) #執(zhí)行sql語句con.commit() #連接提交except:con.rollback()print("插入{}24小時(shí)天氣情況數(shù)據(jù)失敗".format(city_name))print('插入{}24小時(shí)天氣情況數(shù)據(jù)成功'.format(city_name))cursor.close()con.close()# sql = "INSERT INTO weather(Time, Temperature, wind_direction, wind, rainfall, Humidity) values('1', '1', 's', '1', '1', '1');"# try:# cursor.execute(sql)# cursor.execute(sql)# con.commit()# print('插入數(shù)據(jù)成功')# except:# con.rollback()# print("插入數(shù)據(jù)失敗")# con.close()def insert_data14(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()data1 = pd.read_csv('天氣預(yù)報(bào)-{}15天天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')for i in range(data1.shape[0]):Date = list(data1['日期'])[i]Weather = list(data1['天氣'])[i]Min_temperature = list(data1['最低氣溫'])[i]Max_temperature = list(data1['最高氣溫'])[i]wind_direction_1 = list(data1['風(fēng)向1'])[i]wind_direction_2 = list(data1['風(fēng)向2'])[i]wind_level = list(data1['風(fēng)級(jí)'])[i]# Time = list(data1['空氣質(zhì)量'])[1]data = (Date, Weather, Min_temperature, Max_temperature, wind_direction_1, wind_direction_2,wind_level)sql = "INSERT INTO {}weather14d(Date, Weather, Min_temperature, Max_temperature, wind_direction_1, wind_direction_2,wind_level) values ".format(city_name) + str(data) + ";"try:cursor.execute(sql) #執(zhí)行sql語句con.commit() #連接提交except:con.rollback()print("插入{}半個(gè)月天氣情況數(shù)據(jù)失敗")print('插入{}15天天氣情況數(shù)據(jù)成功'.format(city_name))cursor.close()con.close()?這個(gè)地方也給我卡了小半天,結(jié)果你們猜哪兒出問題了,最后檢查出來是保存14天數(shù)據(jù)的時(shí)候,寫sql語句時(shí)表單名字寫錯(cuò)了。。。。。真的程序員的bug八成都是拼寫錯(cuò)誤
數(shù)據(jù)爬取和數(shù)據(jù)存儲(chǔ)的事情我們都已經(jīng)完成了,接下來就需要數(shù)據(jù)可視化了,我用的是matplotlib,首先爬取天氣預(yù)報(bào)肯定要把每天的天氣溫度放首位,那么接下來我們繼續(xù)
繪制當(dāng)天溫度曲線
def tem_curve(data,city_name ):"""溫度曲線繪制"""# plt.style.use('seaborn')hour = list(data['小時(shí)'])# print(hour)tem = list(data['溫度'])for i in range(0, 24):if math.isnan(tem[i]):tem[i] = tem[i - 1]tem_ave = sum(tem) / 24 # 求平均溫度tem_max = max(tem)tem_max_hour = hour[tem.index(tem_max)] # 求最高溫度tem_min = min(tem)tem_min_hour = hour[tem.index(tem_min)] # 求最低溫度x = []y = []for i in range(0, 24):x.append(i)y.append(tem[hour.index(i)])plt.style.use('seaborn')matplotlib.rcParams['font.sans-serif'] = ['SimHei']matplotlib.rcParams['axes.unicode_minus'] = Falseplt.figure(1)plt.plot(x, y, color='red', label='溫度',marker = '^') # 畫出溫度曲線plt.scatter(x, y, color='red') # 點(diǎn)出每個(gè)時(shí)刻的溫度點(diǎn)plt.plot([0, 24], [tem_ave, tem_ave], c='blue', linestyle='--', label='平均溫度') # 畫出平均溫度虛線plt.text(tem_max_hour + 0.15, tem_max + 0.15, str(tem_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高溫度plt.text(tem_min_hour + 0.15, tem_min + 0.15, str(tem_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低溫度plt.xticks(x)plt.legend()plt.title('一天溫度變化曲線圖')plt.xlabel('時(shí)間/h')plt.ylabel('攝氏度/℃')plt.savefig('image/{}24小時(shí)溫度曲線.png'.format(city_name), bbox_inches='tight')plt.show()?這段到后面的知識(shí)都是用了有關(guān)爬蟲可視化的知識(shí),這里包括但不限于matplotlib,當(dāng)時(shí)我學(xué)這個(gè)是在《Python從入門到實(shí)踐》這本書的可視化部分學(xué)的,這是圖靈出版的書,真的推薦大家去看看,特別適合新手入門
繪制15天溫度曲線
"""15天溫度曲線繪制""" def tem_curve14(data,city_name):date = list(data['日期'])tem_low = list(data['最低氣溫'])tem_high = list(data['最高氣溫'])for i in range(0, 14):if math.isnan(tem_low[i]):tem_low[i] = tem_low[i - 1]if math.isnan(tem_high[i]):tem_high[i] = tem_high[i - 1]tem_high_ave = sum(tem_high) / 14 # 求平均高溫tem_low_ave = sum(tem_low) / 14 # 求平均低溫tem_max = max(tem_high)tem_max_date = tem_high.index(tem_max) # 求最高溫度tem_min = min(tem_low)tem_min_date = tem_low.index(tem_min) # 求最低溫度x = range(1, 15)plt.figure(1)plt.plot(x, tem_high, color='red', label='高溫',marker = '^') # 畫出高溫度曲線plt.scatter(x, tem_high, color='red') # 點(diǎn)出每個(gè)時(shí)刻的溫度點(diǎn)plt.plot(x, tem_low, color='blue', label='低溫',marker = '^') # 畫出低溫度曲線plt.scatter(x, tem_low, color='blue') # 點(diǎn)出每個(gè)時(shí)刻的溫度點(diǎn)plt.plot([1, 15], [tem_high_ave, tem_high_ave], c='black', linestyle='--') # 畫出平均溫度虛線plt.plot([1, 15], [tem_low_ave, tem_low_ave], c='black', linestyle='--') # 畫出平均溫度虛線plt.legend()plt.text(tem_max_date + 0.15, tem_max + 0.15, str(tem_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高溫度plt.text(tem_min_date + 0.15, tem_min + 0.15, str(tem_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低溫度plt.xticks(x)plt.title('未來14天高溫低溫變化曲線圖')plt.xlabel('未來天數(shù)/天')plt.ylabel('攝氏度/℃')plt.savefig('image/{}15天溫度曲線.png'.format(city_name), bbox_inches='tight')plt.show()相對濕度曲線繪制
"""相對濕度曲線繪制""" def hum_curve(data,city_name):"""相對濕度曲線繪制"""hour = list(data['小時(shí)'])hum = list(data['相對濕度'])for i in range(0, 24):if math.isnan(hum[i]) == True:hum[i] = hum[i - 1]hum_ave = sum(hum) / 24 # 求平均相對濕度hum_max = max(hum)hum_max_hour = hour[hum.index(hum_max)] # 求最高相對濕度hum_min = min(hum)hum_min_hour = hour[hum.index(hum_min)] # 求最低相對濕度x = []y = []for i in range(0, 24):x.append(i)y.append(hum[hour.index(i)])plt.figure(2)plt.plot(x, y, color='blue', label='相對濕度',marker = '^') # 畫出相對濕度曲線plt.scatter(x, y, color='blue') # 點(diǎn)出每個(gè)時(shí)刻的相對濕度plt.plot([0, 24], [hum_ave, hum_ave], c='red', linestyle='--', label='平均相對濕度',marker = '*') # 畫出平均相對濕度虛線plt.text(hum_max_hour + 0.15, hum_max + 0.15, str(hum_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高相對濕度plt.text(hum_min_hour + 0.15, hum_min + 0.15, str(hum_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低相對濕度plt.xticks(x)plt.legend()plt.title('一天相對濕度變化曲線圖')plt.xlabel('時(shí)間/h')plt.ylabel('百分比/%')plt.savefig('image/{}相對濕度曲線.png'.format(city_name), bbox_inches='tight')plt.show()空氣質(zhì)量曲線繪制
"""空氣質(zhì)量曲線繪制""" def air_curve(data,city_name):"""空氣質(zhì)量曲線繪制"""hour = list(data['小時(shí)'])air = list(data['空氣質(zhì)量'])# print(type(air[0]))for i in range(0, 24):if math.isnan(air[i]) == True:air[i] = air[i - 1]air_ave = sum(air) / 24 # 求平均空氣質(zhì)量air_max = max(air)air_max_hour = hour[air.index(air_max)] # 求最高空氣質(zhì)量air_min = min(air)air_min_hour = hour[air.index(air_min)] # 求最低空氣質(zhì)量x = []y = []for i in range(0, 24):x.append(i)y.append(air[hour.index(i)])plt.figure(3)for i in range(0, 24):if y[i] <= 50:plt.bar(x[i], y[i], color='lightgreen', width=0.7) # 1等級(jí)elif y[i] <= 100:plt.bar(x[i], y[i], color='wheat', width=0.7) # 2等級(jí)elif y[i] <= 150:plt.bar(x[i], y[i], color='orange', width=0.7) # 3等級(jí)elif y[i] <= 200:plt.bar(x[i], y[i], color='orangered', width=0.7) # 4等級(jí)elif y[i] <= 300:plt.bar(x[i], y[i], color='darkviolet', width=0.7) # 5等級(jí)elif y[i] > 300:plt.bar(x[i], y[i], color='maroon', width=0.7) # 6等級(jí)plt.plot([0, 24], [air_ave, air_ave], c='black', linestyle='--') # 畫出平均空氣質(zhì)量虛線plt.text(air_max_hour + 0.15, air_max + 0.15, str(air_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高空氣質(zhì)量plt.text(air_min_hour + 0.15, air_min + 0.15, str(air_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低空氣質(zhì)量plt.xticks(x)plt.title('一天空氣質(zhì)量變化曲線圖')plt.xlabel('時(shí)間/h')plt.ylabel('空氣質(zhì)量指數(shù)AQI')plt.savefig('image/{}空氣質(zhì)量曲線.png'.format(city_name), bbox_inches='tight')plt.show()風(fēng)向雷達(dá)圖繪制
"""改變風(fēng)向""" def change_wind(wind):for i in range(0, 14):if wind[i] == "北風(fēng)":wind[i] = 90elif wind[i] == "南風(fēng)":wind[i] = 270elif wind[i] == "西風(fēng)":wind[i] = 180elif wind[i] == "東風(fēng)":wind[i] = 360elif wind[i] == "東北風(fēng)":wind[i] = 45elif wind[i] == "西北風(fēng)":wind[i] = 135elif wind[i] == "西南風(fēng)":wind[i] = 225elif wind[i] == "東南風(fēng)":wind[i] = 315return wind"""風(fēng)向雷達(dá)圖""" def wind_radar(data,city_name):wind1 = list(data['風(fēng)向1'])wind2 = list(data['風(fēng)向2'])wind_speed = list(data['風(fēng)級(jí)'])wind1 = change_wind(wind1)wind2 = change_wind(wind2)degs = np.arange(45, 361, 45)temp = []for deg in degs:speed = []# 獲取 wind_deg 在指定范圍的風(fēng)速平均值數(shù)據(jù)for i in range(0, 14):if wind1[i] == deg:speed.append(wind_speed[i])if wind2[i] == deg:speed.append(wind_speed[i])if len(speed) == 0:temp.append(0)else:temp.append(sum(speed) / len(speed))# print(temp)N = 8theta = np.arange(0. + np.pi / 8, 2 * np.pi + np.pi / 8, 2 * np.pi / 8)# 數(shù)據(jù)極徑radii = np.array(temp)# 繪制極區(qū)圖坐標(biāo)系plt.axes(polar=True)# 定義每個(gè)扇區(qū)的RGB值(R,G,B),x越大,對應(yīng)的顏色越接近藍(lán)色colors = [(1 - x / max(temp), 1 - x / max(temp), 0.6) for x in radii]plt.bar(theta, radii, width=(2 * np.pi / N), bottom=0.0, color=colors)plt.title('未來14天風(fēng)級(jí)圖', x=0.2, fontsize=20)plt.savefig('image/{}風(fēng)向曲線.png'.format(city_name), bbox_inches='tight')plt.show()繪制天氣餅圖
"""繪制天氣餅圖""" def weather_pie(data,city_name):weather = list(data['天氣'])dic_wea = {}for i in range(0, 14):if weather[i] in dic_wea.keys():dic_wea[weather[i]] += 1else:dic_wea[weather[i]] = 1# print(dic_wea)explode = [0.01] * len(dic_wea.keys())color = ['lightskyblue', 'silver', 'yellow', 'salmon', 'grey', 'lime', 'gold', 'red', 'green', 'pink']plt.pie(dic_wea.values(), explode=explode, labels=dic_wea.keys(), autopct='%1.1f%%', colors=color)plt.title('未來14天氣候分布餅圖')plt.savefig('image/{}天氣餅圖.png'.format(city_name), bbox_inches='tight')plt.show()main主函數(shù)
def main():"""主函數(shù)"""city_name = input("請輸入要查詢的城市:")judge = Judge(city_name)while judge == "你這兒是那個(gè)山卡卡":print("你勒兒是那個(gè)山卡卡,我查不到,你換個(gè)塔塔誒")city_name = input("請輸入要查詢的城市:")judge = Judge(city_name)print(judge)if judge == city_name:url_1 = getURL(city_name) # 7天天氣中國天氣網(wǎng)# print(url_1)url_2 = getURL2(city_name)html1 = getHTMLtext(url_1,city_name)data1 = get_content(html1) # 獲得1-7天和當(dāng)天的數(shù)據(jù)data1_7 = get_content1_7(html1)html2 = getHTMLtext2(url_2,city_name)data8_14 = get_content8_14(html2)data14 = data1_7 + data8_14write_to_csv('天氣預(yù)報(bào)-{}24小時(shí)天氣預(yù)報(bào).csv'.format(city_name), data1, 1)write_to_csv('天氣預(yù)報(bào)-{}15天天氣預(yù)報(bào).csv'.format(city_name), data14, 14)Creat_Table(city_name)Creat_Table14(city_name)insert_data1(city_name)insert_data14(city_name)plt.style.use('seaborn')matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 解決中文顯示問題matplotlib.rcParams['axes.unicode_minus'] = False # 解決負(fù)號(hào)顯示問題data1 = pd.read_csv('天氣預(yù)報(bào)-{}24小時(shí)天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')data14 = pd.read_csv('天氣預(yù)報(bào)-{}15天天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')# tem_curve(data1,city_name) #24小時(shí)溫度曲線繪制# hum_curve(data1,city_name) #相對濕度曲線繪制# air_curve(data1,city_name) #空氣質(zhì)量曲線繪制# corr_tem_hum(data1,city_name) #溫濕度相關(guān)性分析# tem_curve14(data14,city_name) #15天溫度曲線繪制# wind_radar(data14,city_name) #風(fēng)向雷達(dá)圖# weather_pie(data14,city_name) #繪制天氣餅圖while True:num = int(input("請輸入要查詢的圖表(輸入1查詢24小時(shí)溫度曲線繪制、輸入2查詢相對濕度曲線繪制、""輸入3查詢空氣質(zhì)量曲線繪制、輸入4查詢15天溫度曲線、輸入5風(fēng)向雷達(dá)圖、""輸入6天氣餅圖):"))if num == 1:tem_curve(data1,city_name) #24小時(shí)溫度曲線繪制elif num == 2:hum_curve(data1,city_name) #相對濕度曲線繪制elif num == 3:air_curve(data1,city_name) #空氣質(zhì)量曲線繪制elif num == 4:tem_curve14(data14, city_name) # 15天溫度曲線繪制elif num == 5:wind_radar(data14, city_name) # 風(fēng)向雷達(dá)圖elif num == 6:weather_pie(data14, city_name) # 繪制天氣餅圖else:print("查詢結(jié)束...")return False第一個(gè)whlie這兒做了一個(gè)判斷,如果搜索的城市不存在,會(huì)繼續(xù)讓你進(jìn)行搜索,如果存在,就會(huì)往下繼續(xù)運(yùn)行。
第二個(gè)while是做了個(gè)簡單的查詢,這個(gè)思路來自老師開課的第一課給我們的點(diǎn)名系統(tǒng),對應(yīng)的數(shù)字有對應(yīng)的繪圖?,輸入以外的數(shù)字將彈出循環(huán),程序結(jié)束
全部代碼展示
import requests from fake_useragent import UserAgent import json from bs4 import BeautifulSoup import csv import pandas as pd import matplotlib.pyplot as plt import math import mysql.connector import re import numpy as np import matplotlib"""判斷城市是否存在""" def Judge(city_name):city = re.compile(r'(?<={}:)\d*'.format(city_name))str1 = open('城市代碼.txt', 'r')new_str = str1.readlines()try:city_coding = city.search(str(new_str)).group(0)city_coding = city_namereturn city_nameexcept:return "你這兒是那個(gè)山卡卡"# print(city_coding)"""獲取url""" def getURL(city_name):base_url = 'http://www.weather.com.cn/weather/{}.shtml'city = re.compile(r'(?<={}:)\d*'.format(city_name))str1 = open('城市代碼.txt', 'r')# print(str.readlines())new_str = str1.readlines()# print(new_str)# print(city.search(str).group(0))city_coding = city.search(str(new_str)).group(0)# print(city_coding)#new_url = base_url.format(city_coding)# print(new_url)return new_urldef getURL2(city_name):base_url = 'http://www.weather.com.cn/weather15d/{}.shtml'city = re.compile(r'(?<={}:)\d*'.format(city_name))str1 = open('城市代碼.txt', 'r')# print(str.readlines())new_str = str1.readlines()# print(new_str)# print(city.search(str).group(0))city_coding = city.search(str(new_str)).group(0)# print(city_coding)#new_url = base_url.format(city_coding)# print(new_url)return new_url"""請求獲得網(wǎng)頁內(nèi)容""" def getHTMLtext(url,city_name):"""請求獲得網(wǎng)頁內(nèi)容"""try:headers = {"User-Agent": UserAgent().random,}r = requests.get(url, timeout=30, headers=headers)r.raise_for_status()r.encoding = r.apparent_encodingprint("中國氣象網(wǎng){}24小時(shí)天氣訪問成功".format(city_name))return r.textexcept:print("中國氣象網(wǎng){}24小時(shí)天氣訪問失敗".format(city_name))return " "def getHTMLtext2(url,city_name):"""請求獲得網(wǎng)頁內(nèi)容"""try:headers = {"User-Agent": UserAgent().random,}r = requests.get(url, timeout=30, headers=headers)r.raise_for_status()r.encoding = r.apparent_encodingprint("中國氣象網(wǎng){}15天天氣訪問成功".format(city_name))return r.textexcept:print("中國氣象網(wǎng){}15天天氣訪問失敗".format(city_name))return " """"處理得到有用信息保存數(shù)據(jù)文件""" def get_content(html):final = [] # 初始化一個(gè)列表保存數(shù)據(jù)bs = BeautifulSoup(html, "html.parser") # 創(chuàng)建BeautifulSoup對象body = bs.bodydata = body.find('div', {'id': '7d'}) # 找到div標(biāo)簽且id = 7d# 下面爬取當(dāng)天的數(shù)據(jù)data2 = body.find_all('div', {'class': 'left-div'})text = data2[2].find('script').stringtext = text[text.index('=') + 1:-2] # 移除改var data=將其變?yōu)閖son數(shù)據(jù)jd = json.loads(text)dayone = jd['od']['od2'] # 找到當(dāng)天的數(shù)據(jù)final_day = [] # 存放當(dāng)天的數(shù)據(jù)count = 0for i in dayone:temp = []if count <= 23:temp.append(i['od21']) # 添加時(shí)間temp.append(i['od22']) # 添加當(dāng)前時(shí)刻溫度temp.append(i['od24']) # 添加當(dāng)前時(shí)刻風(fēng)力方向temp.append(i['od25']) # 添加當(dāng)前時(shí)刻風(fēng)級(jí)temp.append(i['od26']) # 添加當(dāng)前時(shí)刻降水量temp.append(i['od27']) # 添加當(dāng)前時(shí)刻相對濕度temp.append(i['od28']) # 添加當(dāng)前時(shí)刻控制質(zhì)量# print(temp)final_day.append(temp)count = count + 1return final_daydef get_content1_7(html):# 下面爬取7天的數(shù)據(jù)final = [] # 初始化一個(gè)列表保存數(shù)據(jù)bs = BeautifulSoup(html, "html.parser") # 創(chuàng)建BeautifulSoup對象body = bs.bodydata = body.find('div', {'id': '7d'}) # 找到div標(biāo)簽且id = 7dul = data.find('ul') # 找到所有的ul標(biāo)簽li = ul.find_all('li') # 找到左右的li標(biāo)簽i = 0 # 控制爬取的天數(shù)for day in li: # 遍歷找到的每一個(gè)liif 7 > i > 0:temp = [] # 臨時(shí)存放每天的數(shù)據(jù)date = day.find('h1').string # 得到日期date = date[0:date.index('日')] # 取出日期號(hào)temp.append(date)inf = day.find_all('p') # 找出li下面的p標(biāo)簽,提取第一個(gè)p標(biāo)簽的值,即天氣temp.append(inf[0].string)tem_low = inf[1].find('i').string # 找到最低氣溫if inf[1].find('span') is None: # 天氣預(yù)報(bào)可能沒有最高氣溫tem_high = Noneelse:tem_high = inf[1].find('span').string # 找到最高氣溫temp.append(tem_low[:-1])if tem_high[-1] == '℃':temp.append(tem_high[:-1])else:temp.append(tem_high)wind = inf[2].find_all('span') # 找到風(fēng)向for j in wind:temp.append(j['title'])wind_scale = inf[2].find('i').string # 找到風(fēng)級(jí)index1 = wind_scale.index('級(jí)')temp.append(int(wind_scale[index1 - 1:index1]))final.append(temp)i = i + 1return finaldef get_content8_14(html):"""處理得到有用信息保存數(shù)據(jù)文件"""final = [] # 初始化一個(gè)列表保存數(shù)據(jù)bs = BeautifulSoup(html, "html.parser") # 創(chuàng)建BeautifulSoup對象body = bs.bodydata = body.find('div', {'id': '15d'}) # 找到div標(biāo)簽且id = 15dul = data.find('ul') # 找到所有的ul標(biāo)簽li = ul.find_all('li') # 找到左右的li標(biāo)簽# final = []i = 0 # 控制爬取的天數(shù)for day in li: # 遍歷找到的每一個(gè)liif i < 8:temp = [] # 臨時(shí)存放每天的數(shù)據(jù)date = day.find('span', {'class': 'time'}).string # 得到日期date = date[date.index('(') + 1:-2] # 取出日期號(hào)temp.append(date)weather = day.find('span', {'class': 'wea'}).string # 找到天氣temp.append(weather)tem = day.find('span', {'class': 'tem'}).text # 找到溫度temp.append(tem[tem.index('/') + 1:-1]) # 找到最低氣溫temp.append(tem[:tem.index('/') - 1]) # 找到最高氣溫wind = day.find('span', {'class': 'wind'}).string # 找到風(fēng)向if '轉(zhuǎn)' in wind: # 如果有風(fēng)向變化temp.append(wind[:wind.index('轉(zhuǎn)')])temp.append(wind[wind.index('轉(zhuǎn)') + 1:])else: # 如果沒有風(fēng)向變化,前后風(fēng)向一致temp.append(wind)temp.append(wind)wind_scale = day.find('span', {'class': 'wind1'}).string # 找到風(fēng)級(jí)index1 = wind_scale.index('級(jí)')temp.append(int(wind_scale[index1 - 1:index1]))final.append(temp)return final"""保存為csv文件""" def write_to_csv(file_name, data, day=14):"""保存為csv文件"""with open(file_name, 'w', errors='ignore', newline='') as f:if day == 14:header = ['日期', '天氣', '最低氣溫', '最高氣溫', '風(fēng)向1', '風(fēng)向2', '風(fēng)級(jí)']else:header = ['小時(shí)', '溫度', '風(fēng)力方向', '風(fēng)級(jí)', '降水量', '相對濕度', '空氣質(zhì)量']f_csv = csv.writer(f)f_csv.writerow(header)f_csv.writerows(data)"""創(chuàng)建表""" def Creat_Table(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()cursor.execute('DROP TABLE IF EXISTS {}weather'.format(city_name))sql_set = 'CREATE TABLE IF NOT EXISTS {}weather(Time INT,Temperature INT ,' \'wind_direction VARCHAR(255), wind INT, rainfall INT, Humidity INT)'.format(city_name)try:cursor.execute(sql_set)con.commit()print('創(chuàng)建{}24小時(shí)天氣情況數(shù)據(jù)表成功'.format(city_name))except:con.rollback()print("創(chuàng)建{}24小時(shí)天氣情況數(shù)據(jù)表失敗".format(city_name))con.close()def Creat_Table14(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()cursor.execute('DROP TABLE IF EXISTS {}weather14d'.format(city_name))sql_set = 'CREATE TABLE IF NOT EXISTS {}weather14d(Date INT,Weather VARCHAR(255) ,' \'Min_temperature INT, Max_temperature INT, wind_direction_1 VARCHAR(255), wind_direction_2 VARCHAR(255), wind_level INT)'.format(city_name)try:cursor.execute(sql_set)con.commit()print('創(chuàng)建{}15天天氣情況數(shù)據(jù)表成功'.format(city_name))except:con.rollback()print('創(chuàng)建{}15天天氣情況數(shù)據(jù)表失敗'.format(city_name))con.close()"""在表中插入數(shù)據(jù)""" def insert_data1(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()data1 = pd.read_csv('天氣預(yù)報(bào)-{}24小時(shí)天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')for i in range(data1.shape[0]):Time = list(data1['小時(shí)'])[i]Temperature = list(data1['溫度'])[i]wind_direction = list(data1['風(fēng)力方向'])[i]wind = list(data1['風(fēng)級(jí)'])[i]rainfall = list(data1['降水量'])[i]Humidity = list(data1['相對濕度'])[i]# Time = list(data1['空氣質(zhì)量'])[1]data = (Time, Temperature, wind_direction, wind, rainfall, Humidity)sql = "INSERT INTO {}weather(Time, Temperature, wind_direction, wind, rainfall, Humidity) values ".format(city_name) + str(data) + ";"try:cursor.execute(sql) #執(zhí)行sql語句con.commit() #連接提交except:con.rollback()print("插入{}24小時(shí)天氣情況數(shù)據(jù)失敗".format(city_name))print('插入{}24小時(shí)天氣情況數(shù)據(jù)成功'.format(city_name))cursor.close()con.close()# sql = "INSERT INTO weather(Time, Temperature, wind_direction, wind, rainfall, Humidity) values('1', '1', 's', '1', '1', '1');"# try:# cursor.execute(sql)# cursor.execute(sql)# con.commit()# print('插入數(shù)據(jù)成功')# except:# con.rollback()# print("插入數(shù)據(jù)失敗")# con.close()def insert_data14(city_name):config = {"host": "localhost","port": "3306","user": "root","password": "628","database": "python"}con = mysql.connector.connect(**config)cursor = con.cursor()data1 = pd.read_csv('天氣預(yù)報(bào)-{}15天天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')for i in range(data1.shape[0]):Date = list(data1['日期'])[i]Weather = list(data1['天氣'])[i]Min_temperature = list(data1['最低氣溫'])[i]Max_temperature = list(data1['最高氣溫'])[i]wind_direction_1 = list(data1['風(fēng)向1'])[i]wind_direction_2 = list(data1['風(fēng)向2'])[i]wind_level = list(data1['風(fēng)級(jí)'])[i]# Time = list(data1['空氣質(zhì)量'])[1]data = (Date, Weather, Min_temperature, Max_temperature, wind_direction_1, wind_direction_2,wind_level)sql = "INSERT INTO {}weather14d(Date, Weather, Min_temperature, Max_temperature, wind_direction_1, wind_direction_2,wind_level) values ".format(city_name) + str(data) + ";"try:cursor.execute(sql) #執(zhí)行sql語句con.commit() #連接提交except:con.rollback()print("插入{}半個(gè)月天氣情況數(shù)據(jù)失敗")print('插入{}15天天氣情況數(shù)據(jù)成功'.format(city_name))cursor.close()con.close()"""溫度曲線繪制""" def tem_curve(data,city_name ):"""溫度曲線繪制"""# plt.style.use('seaborn')hour = list(data['小時(shí)'])# print(hour)tem = list(data['溫度'])for i in range(0, 24):if math.isnan(tem[i]):tem[i] = tem[i - 1]tem_ave = sum(tem) / 24 # 求平均溫度tem_max = max(tem)tem_max_hour = hour[tem.index(tem_max)] # 求最高溫度tem_min = min(tem)tem_min_hour = hour[tem.index(tem_min)] # 求最低溫度x = []y = []for i in range(0, 24):x.append(i)y.append(tem[hour.index(i)])plt.style.use('seaborn')matplotlib.rcParams['font.sans-serif'] = ['SimHei']matplotlib.rcParams['axes.unicode_minus'] = Falseplt.figure(1)plt.plot(x, y, color='red', label='溫度',marker = '^') # 畫出溫度曲線plt.scatter(x, y, color='red') # 點(diǎn)出每個(gè)時(shí)刻的溫度點(diǎn)plt.plot([0, 24], [tem_ave, tem_ave], c='blue', linestyle='--', label='平均溫度') # 畫出平均溫度虛線plt.text(tem_max_hour + 0.15, tem_max + 0.15, str(tem_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高溫度plt.text(tem_min_hour + 0.15, tem_min + 0.15, str(tem_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低溫度plt.xticks(x)plt.legend()plt.title('一天溫度變化曲線圖')plt.xlabel('時(shí)間/h')plt.ylabel('攝氏度/℃')plt.savefig('image/{}24小時(shí)溫度曲線.png'.format(city_name), bbox_inches='tight')plt.show()"""相對濕度曲線繪制""" def hum_curve(data,city_name):"""相對濕度曲線繪制"""hour = list(data['小時(shí)'])hum = list(data['相對濕度'])for i in range(0, 24):if math.isnan(hum[i]) == True:hum[i] = hum[i - 1]hum_ave = sum(hum) / 24 # 求平均相對濕度hum_max = max(hum)hum_max_hour = hour[hum.index(hum_max)] # 求最高相對濕度hum_min = min(hum)hum_min_hour = hour[hum.index(hum_min)] # 求最低相對濕度x = []y = []for i in range(0, 24):x.append(i)y.append(hum[hour.index(i)])plt.figure(2)plt.plot(x, y, color='blue', label='相對濕度',marker = '^') # 畫出相對濕度曲線plt.scatter(x, y, color='blue') # 點(diǎn)出每個(gè)時(shí)刻的相對濕度plt.plot([0, 24], [hum_ave, hum_ave], c='red', linestyle='--', label='平均相對濕度',marker = '*') # 畫出平均相對濕度虛線plt.text(hum_max_hour + 0.15, hum_max + 0.15, str(hum_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高相對濕度plt.text(hum_min_hour + 0.15, hum_min + 0.15, str(hum_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低相對濕度plt.xticks(x)plt.legend()plt.title('一天相對濕度變化曲線圖')plt.xlabel('時(shí)間/h')plt.ylabel('百分比/%')plt.savefig('image/{}相對濕度曲線.png'.format(city_name), bbox_inches='tight')plt.show()"""空氣質(zhì)量曲線繪制""" def air_curve(data,city_name):"""空氣質(zhì)量曲線繪制"""hour = list(data['小時(shí)'])air = list(data['空氣質(zhì)量'])# print(type(air[0]))for i in range(0, 24):if math.isnan(air[i]) == True:air[i] = air[i - 1]air_ave = sum(air) / 24 # 求平均空氣質(zhì)量air_max = max(air)air_max_hour = hour[air.index(air_max)] # 求最高空氣質(zhì)量air_min = min(air)air_min_hour = hour[air.index(air_min)] # 求最低空氣質(zhì)量x = []y = []for i in range(0, 24):x.append(i)y.append(air[hour.index(i)])plt.figure(3)for i in range(0, 24):if y[i] <= 50:plt.bar(x[i], y[i], color='lightgreen', width=0.7) # 1等級(jí)elif y[i] <= 100:plt.bar(x[i], y[i], color='wheat', width=0.7) # 2等級(jí)elif y[i] <= 150:plt.bar(x[i], y[i], color='orange', width=0.7) # 3等級(jí)elif y[i] <= 200:plt.bar(x[i], y[i], color='orangered', width=0.7) # 4等級(jí)elif y[i] <= 300:plt.bar(x[i], y[i], color='darkviolet', width=0.7) # 5等級(jí)elif y[i] > 300:plt.bar(x[i], y[i], color='maroon', width=0.7) # 6等級(jí)plt.plot([0, 24], [air_ave, air_ave], c='black', linestyle='--') # 畫出平均空氣質(zhì)量虛線plt.text(air_max_hour + 0.15, air_max + 0.15, str(air_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高空氣質(zhì)量plt.text(air_min_hour + 0.15, air_min + 0.15, str(air_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低空氣質(zhì)量plt.xticks(x)plt.title('一天空氣質(zhì)量變化曲線圖')plt.xlabel('時(shí)間/h')plt.ylabel('空氣質(zhì)量指數(shù)AQI')plt.savefig('image/{}空氣質(zhì)量曲線.png'.format(city_name), bbox_inches='tight')plt.show()"""計(jì)算相關(guān)系數(shù)""" def calc_corr(a, b):"""計(jì)算相關(guān)系數(shù)"""a_avg = sum(a) / len(a)b_avg = sum(b) / len(b)cov_ab = sum([(x - a_avg) * (y - b_avg) for x, y in zip(a, b)])sq = math.sqrt(sum([(x - a_avg) ** 2 for x in a]) * sum([(x - b_avg) ** 2 for x in b]))corr_factor = cov_ab / sqreturn corr_factor"""溫濕度相關(guān)性分析""" def corr_tem_hum(data,city_name):"""溫濕度相關(guān)性分析"""tem = data['溫度']hum = data['相對濕度']plt.scatter(tem, hum, color='blue')plt.title("溫濕度相關(guān)性分析圖")plt.xlabel("溫度/℃")plt.ylabel("相對濕度/%")# plt.text(13, 40, "相關(guān)系數(shù)為:" + str(calc_corr(tem, hum)), fontdict={'size': '10', 'color': 'red'})plt.savefig('image/{}溫濕度相關(guān)性.png'.format(city_name), bbox_inches='tight')plt.show()# print("相關(guān)系數(shù)為:" + str(calc_corr(tem, hum)))"""15天溫度曲線繪制""" def tem_curve14(data,city_name):date = list(data['日期'])tem_low = list(data['最低氣溫'])tem_high = list(data['最高氣溫'])for i in range(0, 14):if math.isnan(tem_low[i]):tem_low[i] = tem_low[i - 1]if math.isnan(tem_high[i]):tem_high[i] = tem_high[i - 1]tem_high_ave = sum(tem_high) / 14 # 求平均高溫tem_low_ave = sum(tem_low) / 14 # 求平均低溫tem_max = max(tem_high)tem_max_date = tem_high.index(tem_max) # 求最高溫度tem_min = min(tem_low)tem_min_date = tem_low.index(tem_min) # 求最低溫度x = range(1, 15)plt.figure(1)plt.plot(x, tem_high, color='red', label='高溫',marker = '^') # 畫出高溫度曲線plt.scatter(x, tem_high, color='red') # 點(diǎn)出每個(gè)時(shí)刻的溫度點(diǎn)plt.plot(x, tem_low, color='blue', label='低溫',marker = '^') # 畫出低溫度曲線plt.scatter(x, tem_low, color='blue') # 點(diǎn)出每個(gè)時(shí)刻的溫度點(diǎn)plt.plot([1, 15], [tem_high_ave, tem_high_ave], c='black', linestyle='--') # 畫出平均溫度虛線plt.plot([1, 15], [tem_low_ave, tem_low_ave], c='black', linestyle='--') # 畫出平均溫度虛線plt.legend()plt.text(tem_max_date + 0.15, tem_max + 0.15, str(tem_max), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最高溫度plt.text(tem_min_date + 0.15, tem_min + 0.15, str(tem_min), ha='center', va='bottom', fontsize=10.5) # 標(biāo)出最低溫度plt.xticks(x)plt.title('未來14天高溫低溫變化曲線圖')plt.xlabel('未來天數(shù)/天')plt.ylabel('攝氏度/℃')plt.savefig('image/{}15天溫度曲線.png'.format(city_name), bbox_inches='tight')plt.show()"""改變風(fēng)向""" def change_wind(wind):for i in range(0, 14):if wind[i] == "北風(fēng)":wind[i] = 90elif wind[i] == "南風(fēng)":wind[i] = 270elif wind[i] == "西風(fēng)":wind[i] = 180elif wind[i] == "東風(fēng)":wind[i] = 360elif wind[i] == "東北風(fēng)":wind[i] = 45elif wind[i] == "西北風(fēng)":wind[i] = 135elif wind[i] == "西南風(fēng)":wind[i] = 225elif wind[i] == "東南風(fēng)":wind[i] = 315return wind"""風(fēng)向雷達(dá)圖""" def wind_radar(data,city_name):wind1 = list(data['風(fēng)向1'])wind2 = list(data['風(fēng)向2'])wind_speed = list(data['風(fēng)級(jí)'])wind1 = change_wind(wind1)wind2 = change_wind(wind2)degs = np.arange(45, 361, 45)temp = []for deg in degs:speed = []# 獲取 wind_deg 在指定范圍的風(fēng)速平均值數(shù)據(jù)for i in range(0, 14):if wind1[i] == deg:speed.append(wind_speed[i])if wind2[i] == deg:speed.append(wind_speed[i])if len(speed) == 0:temp.append(0)else:temp.append(sum(speed) / len(speed))# print(temp)N = 8theta = np.arange(0. + np.pi / 8, 2 * np.pi + np.pi / 8, 2 * np.pi / 8)# 數(shù)據(jù)極徑radii = np.array(temp)# 繪制極區(qū)圖坐標(biāo)系plt.axes(polar=True)# 定義每個(gè)扇區(qū)的RGB值(R,G,B),x越大,對應(yīng)的顏色越接近藍(lán)色colors = [(1 - x / max(temp), 1 - x / max(temp), 0.6) for x in radii]plt.bar(theta, radii, width=(2 * np.pi / N), bottom=0.0, color=colors)plt.title('未來14天風(fēng)級(jí)圖', x=0.2, fontsize=20)plt.savefig('image/{}風(fēng)向曲線.png'.format(city_name), bbox_inches='tight')plt.show()"""繪制天氣餅圖""" def weather_pie(data,city_name):weather = list(data['天氣'])dic_wea = {}for i in range(0, 14):if weather[i] in dic_wea.keys():dic_wea[weather[i]] += 1else:dic_wea[weather[i]] = 1# print(dic_wea)explode = [0.01] * len(dic_wea.keys())color = ['lightskyblue', 'silver', 'yellow', 'salmon', 'grey', 'lime', 'gold', 'red', 'green', 'pink']plt.pie(dic_wea.values(), explode=explode, labels=dic_wea.keys(), autopct='%1.1f%%', colors=color)plt.title('未來14天氣候分布餅圖')plt.savefig('image/{}天氣餅圖.png'.format(city_name), bbox_inches='tight')plt.show()def main():"""主函數(shù)"""city_name = input("請輸入要查詢的城市:")judge = Judge(city_name)while judge == "你這兒是那個(gè)山卡卡":print("你勒兒是那個(gè)山卡卡,我查不到,你換個(gè)塔塔誒")city_name = input("請輸入要查詢的城市:")judge = Judge(city_name)print(judge)if judge == city_name:url_1 = getURL(city_name) # 7天天氣中國天氣網(wǎng)# print(url_1)url_2 = getURL2(city_name)html1 = getHTMLtext(url_1,city_name)data1 = get_content(html1) # 獲得1-7天和當(dāng)天的數(shù)據(jù)data1_7 = get_content1_7(html1)html2 = getHTMLtext2(url_2,city_name)data8_14 = get_content8_14(html2)data14 = data1_7 + data8_14write_to_csv('天氣預(yù)報(bào)-{}24小時(shí)天氣預(yù)報(bào).csv'.format(city_name), data1, 1)write_to_csv('天氣預(yù)報(bào)-{}15天天氣預(yù)報(bào).csv'.format(city_name), data14, 14)Creat_Table(city_name)Creat_Table14(city_name)insert_data1(city_name)insert_data14(city_name)plt.style.use('seaborn')matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 解決中文顯示問題matplotlib.rcParams['axes.unicode_minus'] = False # 解決負(fù)號(hào)顯示問題data1 = pd.read_csv('天氣預(yù)報(bào)-{}24小時(shí)天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')data14 = pd.read_csv('天氣預(yù)報(bào)-{}15天天氣預(yù)報(bào).csv'.format(city_name), encoding='gb2312')# tem_curve(data1,city_name) #24小時(shí)溫度曲線繪制# hum_curve(data1,city_name) #相對濕度曲線繪制# air_curve(data1,city_name) #空氣質(zhì)量曲線繪制# corr_tem_hum(data1,city_name) #溫濕度相關(guān)性分析# tem_curve14(data14,city_name) #15天溫度曲線繪制# wind_radar(data14,city_name) #風(fēng)向雷達(dá)圖# weather_pie(data14,city_name) #繪制天氣餅圖while True:num = int(input("請輸入要查詢的圖表(輸入1查詢24小時(shí)溫度曲線繪制、輸入2查詢相對濕度曲線繪制、""輸入3查詢空氣質(zhì)量曲線繪制、輸入4查詢15天溫度曲線、輸入5風(fēng)向雷達(dá)圖、""輸入6天氣餅圖圖):"))if num == 1:tem_curve(data1,city_name) #24小時(shí)溫度曲線繪制elif num == 2:hum_curve(data1,city_name) #相對濕度曲線繪制elif num == 3:air_curve(data1,city_name) #空氣質(zhì)量曲線繪制elif num == 4:tem_curve14(data14, city_name) # 15天溫度曲線繪制elif num == 5:wind_radar(data14, city_name) # 風(fēng)向雷達(dá)圖elif num == 6:weather_pie(data14, city_name) # 繪制天氣餅圖else:print("查詢結(jié)束...")return Falseif __name__ == '__main__':main()這算是我第一次真正意義上自己獨(dú)立完成的python程序,做下來還是比較興奮的,同時(shí)還有許多想法,比如加個(gè)scrapy框架,再搞個(gè)pyqt5的gui,讓這個(gè)程序更加完美,可惜現(xiàn)在的知識(shí)儲(chǔ)備不足,所以暫時(shí)只能做這么多。這也是我發(fā)布的第一篇csdn,以后編程中遇到的,收獲的,我都會(huì)繼續(xù)在csdn發(fā)布?
總結(jié)
以上是生活随笔為你收集整理的Python天气查询系统(连接数据库版)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Netty心跳机制-长连接
- 下一篇: 幂等和高并发在电商系统中的使用