欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

#python爬取天气数据——和风天气

程序员文章站 2022-07-14 17:01:42
...

@TOC#python爬取天气数据——和风天气

Python爬取和风天气(自学,不足之处大家包涵)

这是博主第一篇博客,也是断断续续自学python以来第一个试验的爬虫项目。之前看过许多项目,一直担心封IP和反爬之类的问题,直到看到和风天气有个免费API,于是决定尝试一下!接下来会分为几个 模块进行。

1、前期准备–注册和风天气,添加应用并拿到免费KEY

注册地址
*https://dev.heweather.com/*

注册成功后在应用管理里面添加应用,就可以添加KEY,这样就可以获取你的个人KEY
#python爬取天气数据——和风天气获取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可以接受城市拼音、经纬度、城市代码等多种方式,由于使用拼音可能会出现相同的情况(比如山西和陕西等),我们直接爬取城市代码表格,保证实时更新。
#python爬取天气数据——和风天气
**获取城市代码爬取链接:**开发文档——参考资料——城市代码——下载
获取的下载链接为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文件打开如下:
#python爬取天气数据——和风天气
查看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吧!

相关标签: 爬虫天气