zoukankan      html  css  js  c++  java
  • Python:requests 爬取40天天气预报

    爬虫对象选择

    打开中国天气网站,例如我要爬取厦门近 40 天的天气情况,打开对应的网页。“weather40d”目录是近 40 天的天气,“101230201”是厦门城市的 id。

    http://www.weather.com.cn/weather40d/101230201.shtml
    


    打开开发者工具,观察到每一天的天气数据还是比较复杂的,所以我们还是要找 API。

    在 network 中观察,Fetch/XHG 中没有任何请求的交互,说明这个网页要么是静态的,要么是用 JavaScript 动态生成的。

    随便找一个在页面中的字符串,例如以 11 月 7 号的天气“多云转小雨”为例,可以看到搜索出一个结果。

    查看这个 JavaScript 文件,可以看到这里罗列了一系列的数据。

    打开详细的数据,发现这个字典里面的数据可以和网页的数据对应,说明这个就是我们想要的 js 文件。

    请求头修改

    查看这个请求的请求头,得到这个 js 文件的 url。

    但是访问这个 url,发现回显 403 错误。403 错误表示资源不可用,也就是服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的。

    也就是说只有特定的地方发起请求才能获取这个资源,查看请求头,发现 “Referer” 字段的值为中国天气网站。Referer 字段用于告诉服务器该网页是从哪个页面链接过来的,因此很有可能我们想要的 js 文件只接受来源于该网站的请求。

    同时还有一个“User-Agent”字段也需要设置,User-Agent 字段会告诉网站服务器访问者是通过什么工具来请求的。如果使用的是爬虫,这个字段会被显式的注明是 Python 爬虫,所以我们要改成浏览器。使用 requests 库的 get 方法,同时夹带头文件进行请求就可以成功。

    import requests
    
    url = "http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html"
    headers = {
        "Referer":"http://www.weather.com.cn/",
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
    }
    r = requests.get(url=url, headers=headers)
    print("请求的状态是:" + str(r.status_code))
    

    数据处理

    观察 Response 的内容,发现除了开头的 “var fc40 = [”这一串字符串,后面的内容都是以 json 的格式存在的。所以只需要把一开始的 “var fc40 = [”删掉,请求的内容就可以以 JSON 的格式解析。

    首先修改编码,然后剔除掉开头的 11 个字符,用 json 库就可以来解析这些数据。会得到一个存有当前页面所有日期的天气数据的 list,每个元素都是一个字典。

    import json
    
    content = r.content.decode(encoding='utf-8')
    weathers = json.loads(content[11:])
    

    最后就是获取我们需要的数据了,我挑选的数据如下:

    字段 含义
    date 日期
    nlyf 农历月份
    nl 农历日期
    w1 天气
    wd1 风向
    max 最高温度
    min 最低温度
    jq 节气
    t1 温度变化
    hmax 历史最高温均值
    hmin 历史最低温均值
    hgl 历史降雨率
    alins 黄历宜
    als 黄历忌
    将这些数据写入 xls 文件,代码如下:
    import xlwt
    
    writebook = xlwt.Workbook()
    sheet = writebook.add_sheet('Sheet1')
    keys = ['date','nlyf','nl','w1','wd1','max','min','jq','t1','hmax','hmin','hgl','alins','als']
    for i in range(len(keys)):
        sheet.write(0, i, keys[i])
    for i in range(len(weathers)):
        for j in range(len(keys)):
            sheet.write(i + 1, j, weathers[i][keys[j]])
    
    writebook.save('weathers.xls')
    

    完整代码

    爬取厦门地区近 40 天天气预报数据,一个简单的爬虫 demo 如下:

    import requests
    import json
    import xlwt
    
    url = "http://d1.weather.com.cn/calendar_new/2021/101230201_202111.html"
    headers = {
        "Referer":"http://www.weather.com.cn/",
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
    }
    r = requests.get(url=url, headers=headers)
    if r.status_code == 200:
        content = r.content.decode(encoding='utf-8')
        weathers = json.loads(content[11:])
    
        writebook = xlwt.Workbook()
        sheet = writebook.add_sheet('Sheet1')
        keys = ['date','nlyf','nl','w1','wd1','max','min','jq','t1','hmax','hmin','hgl','alins','als']
        for i in range(len(keys)):
            sheet.write(0, i, keys[i])
        for i in range(len(weathers)):
            for j in range(len(keys)):
                sheet.write(i + 1, j, weathers[i][keys[j]])
    
        writebook.save('weathers.xls')
    

    爬取的数据如下所示:

  • 相关阅读:
    matrix_2015_1 138
    2014ACM/ICPC亚洲区广州站 北大命题
    无向图的联通分量
    5.1 基础题目选讲
    URAL
    Codeforces Round #274 (Div. 2)
    后缀数组
    poj 1661 help jimmy dp
    hdu 1676 Full Tank? 限制最短路 dp 蛮有技巧的~
    hdu 1023 Train Problem II 双向广搜
  • 原文地址:https://www.cnblogs.com/linfangnan/p/15521967.html
Copyright © 2011-2022 走看看