python爬蟲入門,獲取全國(guó)氣象站24小時(shí)整點(diǎn)氣象數(shù)據(jù)(一)
python爬蟲入門,獲取全國(guó)氣象站24小時(shí)整點(diǎn)氣象數(shù)據(jù)(二)
中國(guó)天氣網(wǎng)(http://www.weather.com.cn/)有全國(guó)各地氣象站點(diǎn)的24小時(shí)整點(diǎn)數(shù)據(jù)。
天氣網(wǎng)的頁(yè)面,以武漢市為例:


但是網(wǎng)頁(yè)上只會(huì)顯示從當(dāng)前時(shí)間開始前溯24小時(shí)的整點(diǎn)數(shù)據(jù)。那么,如果需要?dú)v史數(shù)據(jù),則只有手動(dòng)的每天記錄,很麻煩,這次的目標(biāo)是使用python寫一個(gè)爬蟲程序,實(shí)現(xiàn)自動(dòng)化的數(shù)據(jù)記錄。
注意,代碼基于python3實(shí)現(xiàn)。
1.爬蟲需要用到的庫(kù)
使用python爬取網(wǎng)頁(yè)數(shù)據(jù),常用的庫(kù)包括:
urllib:發(fā)送網(wǎng)絡(luò)請(qǐng)求
BeautifulSoup:解析網(wǎng)頁(yè)
2.發(fā)送請(qǐng)求與網(wǎng)頁(yè)解析
以武漢市為例,在中國(guó)天氣網(wǎng)中搜索武漢,發(fā)現(xiàn)瀏覽器的url是http://www.weather.com.cn/weather1d/101200101.shtml#input
經(jīng)驗(yàn)證最后的#input是可選參數(shù),可以去掉。所以我們請(qǐng)求http://www.weather.com.cn/weather1d/101200101.shtml就可以獲取武漢的網(wǎng)頁(yè)了。代碼如下
url = 'http://www.weather.com.cn/weather1d/101200101.shtml'
html = urllib.request.urlopen(url).read()
接下來要解析網(wǎng)頁(yè),獲取數(shù)據(jù)。我們發(fā)現(xiàn)中國(guó)天氣網(wǎng)直接將24小時(shí)的天氣數(shù)據(jù)以json格式寫在網(wǎng)頁(yè)中了,那解析就簡(jiǎn)單了,哈哈。
這個(gè)json在頁(yè)面中第5個(gè)<script>標(biāo)簽中,我們使用BeautifulSoup解析網(wǎng)頁(yè),代碼如下
soup = BeautifulSoup(html,'html.parser',from_encoding='utf-8')
res_data = soup.findAll('script') #獲取頁(yè)面內(nèi)的所有<script>標(biāo)簽
weather_data = res_data[4] #獲取第5個(gè)<script>標(biāo)簽,返回一個(gè)list
for x in weather_data: #因?yàn)閣eather_data是一個(gè)list,我們?nèi)ist的第一個(gè)
weather1 = x
index_start = weather1.find("{") #目前weather1還是一個(gè)字符串,需要將里面的json截取出來
index_end = weather1.find(";")
weather_str = weather1[index_start:index_end]
weather = eval(weather_str) #將字符串轉(zhuǎn)換成json
json變量weather如下
{"od":
{"od0":"20180202190000",
"od1":"武漢",
"od2":[{"od21":"19","od22":"2","od23":"30","od24":"東北風(fēng)","od25":"3","od26":"0.0","od27":"44","od28":""},
......
{"od21":"19","od22":"2","od23":"20","od24":"北風(fēng)","od25":"0","od26":"0.0","od27":"69","od28":"120"}]
}
};
od0是當(dāng)前數(shù)據(jù)的時(shí)間,od1是當(dāng)前數(shù)據(jù)的地點(diǎn),od2就是24小時(shí)的氣象數(shù)據(jù)了,接下來把時(shí)間數(shù)據(jù)掏出來即可。
weather_dict = weather["od"]
weather_date = weather_dict["od0"] #時(shí)間
weather_position_name = weather_dict["od1"] #地點(diǎn)
weather_list = list(reversed(weather["od"]["od2"]))
insert_list = [] #存放每小時(shí)的數(shù)據(jù)的list,用于之后插入數(shù)據(jù)庫(kù)
for item in weather_list:
#od21小時(shí),od22溫度,od26降雨,od24風(fēng)向,od25風(fēng)力
weather_item = {}
weather_item['time'] = item['od21']
weather_item['temperature'] = item['od22']
weather_item['rain'] = item['od26']
weather_item['humidity'] = item['od27']
weather_item['windDirection'] = item['od24']
weather_item['windPower'] = item['od25']
weather_item['od23'] = item['od23']
insert_list.append(weather_item)
#打印查看變量
print("weather_date:",weather_date)
print("weather_position_name:",weather_position_name)
print("weather_list:",weather_list)
print ("insert_list:",insert_list)
輸出如下
weather_date: 20180202200000
weather_position_name: 武漢
weather_list: [{'od21': '20', 'od22': '1', 'od23': '33', 'od24': '東北風(fēng)', 'od25': '0', 'od26': '0.0', 'od27': '73', 'od28': '120'}, {'od21': '21', 'od22': '1', 'od23': '22', 'od24': '北風(fēng)', 'od25': '0', 'od26': '0.0', 'od27': '81', 'od28': '128'}, {'od21': '22', 'od22': '2', 'od23': '11', 'od24': '北風(fēng)', 'od25': '0', 'od26': '0.0', 'od27': '83', 'od28': '129'}, {'od21': '23', 'od22': '1', 'od23': 'null', 'od24': '暫無(wú)風(fēng)向', 'od25': '0', 'od26': '0.0', 'od27': '79', 'od28': '123'}, {'od21': '00', 'od22': '1', 'od23': '22', 'od24': '北風(fēng)', 'od25': '1', 'od26': '0.0', 'od27': '85', 'od28': '112'}, {'od21': '01', 'od22': '1', 'od23': '316', 'od24': '西北風(fēng)', 'od25': '1', 'od26': '0.0', 'od27': '83', 'od28': '104'}, {'od21': '02', 'od22': '0', 'od23': '353', 'od24': '北風(fēng)', 'od25': '1', 'od26': '0.0', 'od27': '83', 'od28': '99'}, {'od21': '03', 'od22': '0', 'od23': '349', 'od24': '北風(fēng)', 'od25': '2', 'od26': '0.0', 'od27': '85', 'od28': '99'}, {'od21': '04', 'od22': '-1', 'od23': '342', 'od24': '北風(fēng)', 'od25': '1', 'od26': '0.0', 'od27': '89', 'od28': '95'}, {'od21': '05', 'od22': '0', 'od23': '339', 'od24': '北風(fēng)', 'od25': '2', 'od26': '0.0', 'od27': '89', 'od28': '89'}, {'od21': '06', 'od22': '-1', 'od23': '222', 'od24': '西南風(fēng)', 'od25': '0', 'od26': '0.0', 'od27': '90', 'od28': '88'}, {'od21': '07', 'od22': '-2', 'od23': '313', 'od24': '西北風(fēng)', 'od25': '0', 'od26': '0.0', 'od27': '93', 'od28': '88'}, {'od21': '08', 'od22': '0', 'od23': '357', 'od24': '北風(fēng)', 'od25': '2', 'od26': '0.0', 'od27': '79', 'od28': '88'}, {'od21': '09', 'od22': '3', 'od23': '5', 'od24': '北風(fēng)', 'od25': '3', 'od26': '0.0', 'od27': '52', 'od28': '87'}, {'od21': '10', 'od22': '5', 'od23': '10', 'od24': '北風(fēng)', 'od25': '3', 'od26': '0.0', 'od27': '40', 'od28': '80'}, {'od21': '11', 'od22': '5', 'od23': '7', 'od24': '北風(fēng)', 'od25': '4', 'od26': '0.0', 'od27': '34', 'od28': '88'}, {'od21': '12', 'od22': '6', 'od23': '4', 'od24': '北風(fēng)', 'od25': '4', 'od26': '0.0', 'od27': '30', 'od28': '88'}, {'od21': '13', 'od22': '7', 'od23': '347', 'od24': '北風(fēng)', 'od25': '4', 'od26': '0.0', 'od27': '28', 'od28': '90'}, {'od21': '14', 'od22': '8', 'od23': '15', 'od24': '北風(fēng)', 'od25': '5', 'od26': '0.0', 'od27': '28', 'od28': '86'}, {'od21': '15', 'od22': '7', 'od23': '15', 'od24': '北風(fēng)', 'od25': '3', 'od26': '0.0', 'od27': '33', 'od28': '85'}, {'od21': '16', 'od22': '6', 'od23': '13', 'od24': '北風(fēng)', 'od25': '3', 'od26': '0.0', 'od27': '32', 'od28': '86'}, {'od21': '17', 'od22': '5', 'od23': '14', 'od24': '北風(fēng)', 'od25': '3', 'od26': '0.0', 'od27': '35', 'od28': '76'}, {'od21': '18', 'od22': '3', 'od23': '36', 'od24': '東北風(fēng)', 'od25': '4', 'od26': '0.0', 'od27': '38', 'od28': '83'}, {'od21': '19', 'od22': '2', 'od23': '30', 'od24': '東北風(fēng)', 'od25': '3', 'od26': '0.0', 'od27': '44', 'od28': '84'}, {'od21': '20', 'od22': '1', 'od23': '36', 'od24': '東北風(fēng)', 'od25': '3', 'od26': '0.0', 'od27': '42', 'od28': ''}]
insert_list: [{'time': '20', 'temperature': '1', 'rain': '0.0', 'humidity': '73', 'windDirection': '東北風(fēng)', 'windPower': '0', 'od23': '33'}, {'time': '21', 'temperature': '1', 'rain': '0.0', 'humidity': '81', 'windDirection': '北風(fēng)', 'windPower': '0', 'od23': '22'}, {'time': '22', 'temperature': '2', 'rain': '0.0', 'humidity': '83', 'windDirection': '北風(fēng)', 'windPower': '0', 'od23': '11'}, {'time': '23', 'temperature': '1', 'rain': '0.0', 'humidity': '79', 'windDirection': '暫無(wú)風(fēng)向', 'windPower': '0', 'od23': 'null'}, {'time': '00', 'temperature': '1', 'rain': '0.0', 'humidity': '85', 'windDirection': '北風(fēng)', 'windPower': '1', 'od23': '22'}, {'time': '01', 'temperature': '1', 'rain': '0.0', 'humidity': '83', 'windDirection': '西北風(fēng)', 'windPower': '1', 'od23': '316'}, {'time': '02', 'temperature': '0', 'rain': '0.0', 'humidity': '83', 'windDirection': '北風(fēng)', 'windPower': '1', 'od23': '353'}, {'time': '03', 'temperature': '0', 'rain': '0.0', 'humidity': '85', 'windDirection': '北風(fēng)', 'windPower': '2', 'od23': '349'}, {'time': '04', 'temperature': '-1', 'rain': '0.0', 'humidity': '89', 'windDirection': '北風(fēng)', 'windPower': '1', 'od23': '342'}, {'time': '05', 'temperature': '0', 'rain': '0.0', 'humidity': '89', 'windDirection': '北風(fēng)', 'windPower': '2', 'od23': '339'}, {'time': '06', 'temperature': '-1', 'rain': '0.0', 'humidity': '90', 'windDirection': '西南風(fēng)', 'windPower': '0', 'od23': '222'}, {'time': '07', 'temperature': '-2', 'rain': '0.0', 'humidity': '93', 'windDirection': '西北風(fēng)', 'windPower': '0', 'od23': '313'}, {'time': '08', 'temperature': '0', 'rain': '0.0', 'humidity': '79', 'windDirection': '北風(fēng)', 'windPower': '2', 'od23': '357'}, {'time': '09', 'temperature': '3', 'rain': '0.0', 'humidity': '52', 'windDirection': '北風(fēng)', 'windPower': '3', 'od23': '5'}, {'time': '10', 'temperature': '5', 'rain': '0.0', 'humidity': '40', 'windDirection': '北風(fēng)', 'windPower': '3', 'od23': '10'}, {'time': '11', 'temperature': '5', 'rain': '0.0', 'humidity': '34', 'windDirection': '北風(fēng)', 'windPower': '4', 'od23': '7'}, {'time': '12', 'temperature': '6', 'rain': '0.0', 'humidity': '30', 'windDirection': '北風(fēng)', 'windPower': '4', 'od23': '4'}, {'time': '13', 'temperature': '7', 'rain': '0.0', 'humidity': '28', 'windDirection': '北風(fēng)', 'windPower': '4', 'od23': '347'}, {'time': '14', 'temperature': '8', 'rain': '0.0', 'humidity': '28', 'windDirection': '北風(fēng)', 'windPower': '5', 'od23': '15'}, {'time': '15', 'temperature': '7', 'rain': '0.0', 'humidity': '33', 'windDirection': '北風(fēng)', 'windPower': '3', 'od23': '15'}, {'time': '16', 'temperature': '6', 'rain': '0.0', 'humidity': '32', 'windDirection': '北風(fēng)', 'windPower': '3', 'od23': '13'}, {'time': '17', 'temperature': '5', 'rain': '0.0', 'humidity': '35', 'windDirection': '北風(fēng)', 'windPower': '3', 'od23': '14'}, {'time': '18', 'temperature': '3', 'rain': '0.0', 'humidity': '38', 'windDirection': '東北風(fēng)', 'windPower': '4', 'od23': '36'}, {'time': '19', 'temperature': '2', 'rain': '0.0', 'humidity': '44', 'windDirection': '東北風(fēng)', 'windPower': '3', 'od23': '30'}, {'time': '20', 'temperature': '1', 'rain': '0.0', 'humidity': '42', 'windDirection': '東北風(fēng)', 'windPower': '3', 'od23': '36'}]
至此,我們已經(jīng)成功爬取到了一個(gè)城市的天氣數(shù)據(jù)。
那么如何擴(kuò)展到爬取全國(guó)所有站點(diǎn)的數(shù)據(jù)呢,請(qǐng)聽下回分解。