#python爬取天气数据——和风天气
@TOC#python爬取天气数据——和风天气
Python爬取和风天气(自学,不足之处大家包涵)
这是博主第一篇博客,也是断断续续自学python以来第一个试验的爬虫项目。之前看过许多项目,一直担心封IP和反爬之类的问题,直到看到和风天气有个免费API,于是决定尝试一下!接下来会分为几个 模块进行。
1、前期准备–注册和风天气,添加应用并拿到免费KEY
注册地址为
*https://dev.heweather.com/*
注册成功后在应用管理里面添加应用,就可以添加KEY,这样就可以获取你的个人KEY。
获取KEY:控制台——应用管理——新建应用——添加KEY。
爬取链接 :
免费版:https://free-api.heweather.net/s6/weather/{weather-type}?location=xxx&key=xxx
商业版:https://api.heweather.net/s6/weather/{weather-type}?location=xxx&key=xxx
【参数weather-type包括now\forecast\hourly\lifestyle几种;参数参数location代表城市ID;参数key为获取的个人KEY】
需要用到的模块先导入。
#! python3
# -*- coding:utf-8 -*-
# Usage:爬取天气预报到excel
import os
import requests
import csv
import openpyxl
import datetime
import time
os.chdir('C:\\Users\\Administrator\\Desktop')
【博主习惯放在桌面,方便查看和测试】
2、爬取城市代码列表
和风天气可以爬取全国近3000个市区县地级城市的天气数据,参数location可以接受城市拼音、经纬度、城市代码等多种方式,由于使用拼音可能会出现相同的情况(比如山西和陕西等),我们直接爬取城市代码表格,保证实时更新。
**获取城市代码爬取链接:**开发文档——参考资料——城市代码——下载
获取的下载链接为https://a.hecdn.net/download/dev/china-city-list.csv
【列表类型为csv格式,当然也可以直接下载】
代码如下:
def get_citylist(url):
headers = {
'content - encoding': 'gzip',
'content - location': 'city.html',
'content - type': 'text / html; charset = UTF - 8',
'date': 'Mon, 06 Apr 2020 08:35:40 GMT',
'last - modified': 'Thu, 20 Feb 2020 14:40:26 GMT',
'status': '304',
'tcn': 'choice',
'vary': 'negotiate'
}
response = requests.get(url, headers=headers)
with open('citylist.csv', 'wb') as f: # 下载城市列表
f.write(response.content)
f.close()
print('done1')
csvtoxlsx('citylist.csv')
【刚开始并没有使用请求头,好像也可以下载。下载的文件为csv格式,可以直接使用excel打开。做个done1的指针】
3、csv文件转成excel
下载的csv列表文件,在python里不好通过openpyxl使用,所以做一个文件格式转换。
这一步需要注意一下,csv文件不可以直接被读取,要进行utf-8转换编码。
查看citylist文件中,发现第一行为标题行,第二行为表头,所以在转换格式时就先做了一个查询表头和查找列数的代码【注释行】。后来想到可以在Excel文件中查询,而且放在下一个模块中,就可以方便下载csv表格后,直接另存为Excel文件的情况,所以就选择注释掉。
def csvtoxlsx(csvname):
csvfile = open(csvname, encoding='utf-8') # 对文件进行转码,转成utf-8模式,否则读取不出来
csvreader = csv.reader(csvfile)
wb = openpyxl.Workbook()
sheet = wb.active
sheet.title = 'cityweather'
# searchbiaotou = 0 # 寻找表头所属行数
# searchlieshu = [0] # 寻找表格最大列数
for row in csvreader:
for i in range(len(row)):
sheet.cell(row=csvreader.line_num, column=i+1).value = row[i]
# if len(row) > max(searchlieshu):
# searchlieshu.append(len(row))
# searchbiaotou += 1
wb.save('cityweather.xlsx')
# print('最后一行表头在ROW%s' % searchbiaotou, '最大列数为COLUMN%s' % max(searchlieshu))
print('done2')
xunzhaobiaotou('cityweather.xlsx')
【做个done2的指针】
4、在excel中查询表头情况
在上一模块中,csv文件直接转换成excel文件,并未删除标题行,因此来做一个查询表头和最大列数的代码。
excel文件打开如下:
查看excel文件发现自第3行开始为数据,第14列开始为空白列。但运行代码时,直接使用ws.max_column返回数值为14,这就会导致查询表头失败,因此在if判断语句中,列数为最大列数减1,即判断第13列数据。
def xunzhaobiaotou(xlsxname):
wb = openpyxl.load_workbook(xlsxname) # load_workbook()为打开已存在Excel,Workbook()为新建Excel
ws = wb.active
print(ws.max_row, ws.max_column)
searchbiaotou = 0 # 寻找表头所属行数
for row in range(1, ws.max_row+1): # 查看表格后发现,最后一列并无内容
if ws.cell(row=row, column=ws.max_column-1).value is None:
searchbiaotou += 1
else:
break
print('最后一行表头在ROW%s' % searchbiaotou, '最大行数为ROW%s' % ws.max_row, '最大列数为COLUMN%s' % (ws.max_column - 1))
paquweather(xlsxname, searchbiaotou, ws.max_row, (ws.max_column - 1))
【做个打印表头行数、总行数、最大列数的指针】
5、爬取天气数据主程序
利用转换出的excel进行数值确定和爬取天气数据。博主选择的参数weather_type为forecast,可以查询自今日、明日、后日三日天气。
1)第1个for循环用来制作列名,分别为今日、明日、后日时间+‘Weather’作为列名。使用datetime模块中的函数创建,并打印okbiaotou指针。
2)第2个for循环用来爬取数据,先拿到excel中城市代码id,在第一列,并组成数据连接url(其中personal KEY应换成自己的KEY)。进行requests.get()爬取后返回的数据不是字典,需要使用.json()转换成字典格式才可以继续分析。
3)第3个for循环用来分析数据,可以先将responseweather01打印出来,利用JSON编辑工具查看节点情况,写出来目标数据路径,最后写到excel中,并打印okNO.row的指针。
4)最后一个if判断语句,是希望每爬取50个数据就暂停2秒。不过和风开发好像不会封IP,可能也就不需要这样了。
def paquweather(xlsxname, biaotou, hangshu, lieshu):
wb = openpyxl.load_workbook(xlsxname) # load_workbook()为打开已存在Excel,Workbook()为新建Excel
ws = wb.active
atime = datetime.datetime.now()
for i in range(3):
ws.cell(row=biaotou + 1, column=lieshu + 1 + i).value \
= str(atime.year) + '/' + str(atime.month) + '/' + str(atime.day + i) + 'Weather'
print('okbiaotou')
for row in range(biaotou+2, hangshu+1):
citynameid = ws.cell(row=row, column=1).value
url = 'https://free-api.heweather.net/s6/weather/forecast?location=' + str(citynameid) + \
'&key=' + 'personal KEY'
responseweather01 = requests.get(url).json() # .json()进行格式转换
for j in range(3):
ws.cell(row=row, column=lieshu + 1 + j).value \
= responseweather01['HeWeather6'][0]['daily_forecast'][j]['cond_txt_d']
print('okNo.' + str(row))
if row % 50 == 0:
time.sleep(2)
wb.save('cityweather2.xlsx')
【如果出现‘utf-8’的错误,可能是因为爬取数据中有中文,这时候就在代码开头写上**# -- coding:utf-8 --**】
6、程序运行
写一个代码运行就可以了!
if __name__ == '__main__':
get_citylist('https://a.hecdn.net/download/dev/china-city-list.csv')
print('ok')
【打印ok指针】
后记
【改进】博主其实还想再加一段代码,将不需要给出去的数据删除掉,重新存一个只有城市名称(包括上级城市名称)和三日天气数据的excel,但是感觉意义不大,就没再码了。
【小结】这是博主自学以来,第一个独立做的实践项目,运行了一下 ,还是可以的。可能有些朋友也发现了,和风开发免费API一天只能访问1000次,这就会导致大量爬取的时候出错,大概爬到980多,就会报NO REQUESTS。这时候要么升级个人开发者或者充钱,要么就多注册几个KEY,快到1000,就换个KEY吧!
上一篇: 将博客搬至CSDN
下一篇: MAC内存整理软件-iFreeMem