python爬虫入门,获取全国气象站24小时整点气象数据(一)
python爬虫入门,获取全国气象站24小时整点气象数据(二)
中国天气网(http://www.weather.com.cn/)有全国各地气象站点的24小时整点数据。
天气网的页面,以武汉市为例:
但是网页上只会显示从当前时间开始前溯24小时的整点数据。那么,如果需要历史数据,则只有手动的每天记录,很麻烦,这次的目标是使用python写一个爬虫程序,实现自动化的数据记录。
注意,代码基于python3实现。
1.爬虫需要用到的库
使用python爬取网页数据,常用的库包括:
urllib:发送网络请求
BeautifulSoup:解析网页
2.发送请求与网页解析
以武汉市为例,在中国天气网中搜索武汉,发现浏览器的url是http://www.weather.com.cn/weather1d/101200101.shtml#input
经验证最后的#input是可选参数,可以去掉。所以我们请求http://www.weather.com.cn/weather1d/101200101.shtml就可以获取武汉的网页了。代码如下
url = 'http://www.weather.com.cn/weather1d/101200101.shtml'
html = urllib.request.urlopen(url).read()
接下来要解析网页,获取数据。我们发现中国天气网直接将24小时的天气数据以json格式写在网页中了,那解析就简单了,哈哈。这个json在页面中第5个<script>标签中,我们使用BeautifulSoup解析网页,代码如下
soup = BeautifulSoup(html,'html.parser',from_encoding='utf-8')
res_data = soup.findAll('script') #获取页面内的所有<script>标签
weather_data = res_data[4] #获取第5个<script>标签,返回一个list
for x in weather_data: #因为weather_data是一个list,我们取list的第一个
weather1 = x
index_start = weather1.find("{") #目前weather1还是一个字符串,需要将里面的json截取出来
index_end = weather1.find(";")
weather_str = weather1[index_start:index_end]
weather = eval(weather_str) #将字符串转换成json
json变量weather如下
{"od":
{"od0":"20180202190000",
"od1":"武汉",
"od2":[{"od21":"19","od22":"2","od23":"30","od24":"东北风","od25":"3","od26":"0.0","od27":"44","od28":""},
......
{"od21":"19","od22":"2","od23":"20","od24":"北风","od25":"0","od26":"0.0","od27":"69","od28":"120"}]
}
};
od0是当前数据的时间,od1是当前数据的地点,od2就是24小时的气象数据了,接下来把时间数据掏出来即可。
weather_dict = weather["od"]
weather_date = weather_dict["od0"] #时间
weather_position_name = weather_dict["od1"] #地点
weather_list = list(reversed(weather["od"]["od2"]))
insert_list = [] #存放每小时的数据的list,用于之后插入数据库
for item in weather_list:
#od21小时,od22温度,od26降雨,od24风向,od25风力
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': '东北风', 'od25': '0', 'od26': '0.0', 'od27': '73', 'od28': '120'}, {'od21': '21', 'od22': '1', 'od23': '22', 'od24': '北风', 'od25': '0', 'od26': '0.0', 'od27': '81', 'od28': '128'}, {'od21': '22', 'od22': '2', 'od23': '11', 'od24': '北风', 'od25': '0', 'od26': '0.0', 'od27': '83', 'od28': '129'}, {'od21': '23', 'od22': '1', 'od23': 'null', 'od24': '暂无风向', 'od25': '0', 'od26': '0.0', 'od27': '79', 'od28': '123'}, {'od21': '00', 'od22': '1', 'od23': '22', 'od24': '北风', 'od25': '1', 'od26': '0.0', 'od27': '85', 'od28': '112'}, {'od21': '01', 'od22': '1', 'od23': '316', 'od24': '西北风', 'od25': '1', 'od26': '0.0', 'od27': '83', 'od28': '104'}, {'od21': '02', 'od22': '0', 'od23': '353', 'od24': '北风', 'od25': '1', 'od26': '0.0', 'od27': '83', 'od28': '99'}, {'od21': '03', 'od22': '0', 'od23': '349', 'od24': '北风', 'od25': '2', 'od26': '0.0', 'od27': '85', 'od28': '99'}, {'od21': '04', 'od22': '-1', 'od23': '342', 'od24': '北风', 'od25': '1', 'od26': '0.0', 'od27': '89', 'od28': '95'}, {'od21': '05', 'od22': '0', 'od23': '339', 'od24': '北风', 'od25': '2', 'od26': '0.0', 'od27': '89', 'od28': '89'}, {'od21': '06', 'od22': '-1', 'od23': '222', 'od24': '西南风', 'od25': '0', 'od26': '0.0', 'od27': '90', 'od28': '88'}, {'od21': '07', 'od22': '-2', 'od23': '313', 'od24': '西北风', 'od25': '0', 'od26': '0.0', 'od27': '93', 'od28': '88'}, {'od21': '08', 'od22': '0', 'od23': '357', 'od24': '北风', 'od25': '2', 'od26': '0.0', 'od27': '79', 'od28': '88'}, {'od21': '09', 'od22': '3', 'od23': '5', 'od24': '北风', 'od25': '3', 'od26': '0.0', 'od27': '52', 'od28': '87'}, {'od21': '10', 'od22': '5', 'od23': '10', 'od24': '北风', 'od25': '3', 'od26': '0.0', 'od27': '40', 'od28': '80'}, {'od21': '11', 'od22': '5', 'od23': '7', 'od24': '北风', 'od25': '4', 'od26': '0.0', 'od27': '34', 'od28': '88'}, {'od21': '12', 'od22': '6', 'od23': '4', 'od24': '北风', 'od25': '4', 'od26': '0.0', 'od27': '30', 'od28': '88'}, {'od21': '13', 'od22': '7', 'od23': '347', 'od24': '北风', 'od25': '4', 'od26': '0.0', 'od27': '28', 'od28': '90'}, {'od21': '14', 'od22': '8', 'od23': '15', 'od24': '北风', 'od25': '5', 'od26': '0.0', 'od27': '28', 'od28': '86'}, {'od21': '15', 'od22': '7', 'od23': '15', 'od24': '北风', 'od25': '3', 'od26': '0.0', 'od27': '33', 'od28': '85'}, {'od21': '16', 'od22': '6', 'od23': '13', 'od24': '北风', 'od25': '3', 'od26': '0.0', 'od27': '32', 'od28': '86'}, {'od21': '17', 'od22': '5', 'od23': '14', 'od24': '北风', 'od25': '3', 'od26': '0.0', 'od27': '35', 'od28': '76'}, {'od21': '18', 'od22': '3', 'od23': '36', 'od24': '东北风', 'od25': '4', 'od26': '0.0', 'od27': '38', 'od28': '83'}, {'od21': '19', 'od22': '2', 'od23': '30', 'od24': '东北风', 'od25': '3', 'od26': '0.0', 'od27': '44', 'od28': '84'}, {'od21': '20', 'od22': '1', 'od23': '36', 'od24': '东北风', 'od25': '3', 'od26': '0.0', 'od27': '42', 'od28': ''}]
insert_list: [{'time': '20', 'temperature': '1', 'rain': '0.0', 'humidity': '73', 'windDirection': '东北风', 'windPower': '0', 'od23': '33'}, {'time': '21', 'temperature': '1', 'rain': '0.0', 'humidity': '81', 'windDirection': '北风', 'windPower': '0', 'od23': '22'}, {'time': '22', 'temperature': '2', 'rain': '0.0', 'humidity': '83', 'windDirection': '北风', 'windPower': '0', 'od23': '11'}, {'time': '23', 'temperature': '1', 'rain': '0.0', 'humidity': '79', 'windDirection': '暂无风向', 'windPower': '0', 'od23': 'null'}, {'time': '00', 'temperature': '1', 'rain': '0.0', 'humidity': '85', 'windDirection': '北风', 'windPower': '1', 'od23': '22'}, {'time': '01', 'temperature': '1', 'rain': '0.0', 'humidity': '83', 'windDirection': '西北风', 'windPower': '1', 'od23': '316'}, {'time': '02', 'temperature': '0', 'rain': '0.0', 'humidity': '83', 'windDirection': '北风', 'windPower': '1', 'od23': '353'}, {'time': '03', 'temperature': '0', 'rain': '0.0', 'humidity': '85', 'windDirection': '北风', 'windPower': '2', 'od23': '349'}, {'time': '04', 'temperature': '-1', 'rain': '0.0', 'humidity': '89', 'windDirection': '北风', 'windPower': '1', 'od23': '342'}, {'time': '05', 'temperature': '0', 'rain': '0.0', 'humidity': '89', 'windDirection': '北风', 'windPower': '2', 'od23': '339'}, {'time': '06', 'temperature': '-1', 'rain': '0.0', 'humidity': '90', 'windDirection': '西南风', 'windPower': '0', 'od23': '222'}, {'time': '07', 'temperature': '-2', 'rain': '0.0', 'humidity': '93', 'windDirection': '西北风', 'windPower': '0', 'od23': '313'}, {'time': '08', 'temperature': '0', 'rain': '0.0', 'humidity': '79', 'windDirection': '北风', 'windPower': '2', 'od23': '357'}, {'time': '09', 'temperature': '3', 'rain': '0.0', 'humidity': '52', 'windDirection': '北风', 'windPower': '3', 'od23': '5'}, {'time': '10', 'temperature': '5', 'rain': '0.0', 'humidity': '40', 'windDirection': '北风', 'windPower': '3', 'od23': '10'}, {'time': '11', 'temperature': '5', 'rain': '0.0', 'humidity': '34', 'windDirection': '北风', 'windPower': '4', 'od23': '7'}, {'time': '12', 'temperature': '6', 'rain': '0.0', 'humidity': '30', 'windDirection': '北风', 'windPower': '4', 'od23': '4'}, {'time': '13', 'temperature': '7', 'rain': '0.0', 'humidity': '28', 'windDirection': '北风', 'windPower': '4', 'od23': '347'}, {'time': '14', 'temperature': '8', 'rain': '0.0', 'humidity': '28', 'windDirection': '北风', 'windPower': '5', 'od23': '15'}, {'time': '15', 'temperature': '7', 'rain': '0.0', 'humidity': '33', 'windDirection': '北风', 'windPower': '3', 'od23': '15'}, {'time': '16', 'temperature': '6', 'rain': '0.0', 'humidity': '32', 'windDirection': '北风', 'windPower': '3', 'od23': '13'}, {'time': '17', 'temperature': '5', 'rain': '0.0', 'humidity': '35', 'windDirection': '北风', 'windPower': '3', 'od23': '14'}, {'time': '18', 'temperature': '3', 'rain': '0.0', 'humidity': '38', 'windDirection': '东北风', 'windPower': '4', 'od23': '36'}, {'time': '19', 'temperature': '2', 'rain': '0.0', 'humidity': '44', 'windDirection': '东北风', 'windPower': '3', 'od23': '30'}, {'time': '20', 'temperature': '1', 'rain': '0.0', 'humidity': '42', 'windDirection': '东北风', 'windPower': '3', 'od23': '36'}]
至此,我们已经成功爬取到了一个城市的天气数据。
那么如何扩展到爬取全国所有站点的数据呢,请听下回分解。