提问者:小点点

Web抓取天气数据400错误


我尝试过使用带参数的get请求、带json和不带json的post请求。转储,但我似乎无法从网页上得到正确的回应。

我想要一个包含所有天气数据的文本文件。附加了我的代码、我想要的数据以及使用inspect on chrome的post请求的标题。

谢谢你的帮助!

您还可以通过以下方式访问数据:

>

  • 去http://climod2.nrcc.cornell.edu
  • 单击每日数据列表
  • 输入从2018年6月1日到当前日期的日期
  • 选择csv而不是html
  • 然后键入NY City Central Park作为站点选择,该站点将返回该站点的搜索结果,然后单击go。

    以下是截图:

    1. 尝试
    2. 由于不能发布超过8个链接,不得不删除
    3. 标题
    4. 所需数据
    5. 响应数据`

    从urllib.request导入urlopenas uReq从bs4导入漂亮的汤作为汤导入请求导入日期时间导入json

    有效载荷={'method':'POST','params':{“elems”:[{“name”:“maxt”,“add”:“t”},{“name”:“mint”,“add”:“t”},{“name”:“snow”,“add”:“t”},{“name”:“snwd”,“add”:“t”}],“sId”:“94728 1”,“sDate”:“2018-06-01”,“eDate”:“2018-06-28”},'output”:“json”}

    参数={“elems”:[{“name”:“maxt”,“add”:“t”},{“name”:“mint”,“add”:“t”},{“name”:“pcpn”,“add”:“t”},{“name”:“snow”,“add”:“t”},{“name”:“snwd”,“add”:“t”},“sid”:“94728 1”,“sDate”:“2018-06-01”,“eDate”:“2018-06-28”}

    Headers={接受:应用程序/json,文本/javascript,/;q=0.01,内容类型:应用程序/x-wow-form-urlencoded;charset=UTF-8,起源:http://climod2.nrcc.cornell.edu,裁判:http://climod2.nrcc.cornell.edu/elems=name

    dataurl='1〕https://data.rcc-acis.org/StnData'

    r=请求。post(dataurl,data=json.dumps(有效负载),headers=headers)

    打印(r.status_code)打印(r.appeased)打印(r.json)打印(r.text)`


  • 共1个答案

    匿名用户

    您只需将有效负载设置正确即可。

    这样就行了。

    import requests
    from pprint import pprint
    
    url = "https://data.rcc-acis.org/StnMeta"
    
    payload = {
        "output": "json",
        "params": {"elems":[{"name":"maxt","add":"t"},{"name":"mint","add":"t"},{"name":"pcpn","add":"t"},{"name":"snow","add":"t"},{"name":"snwd","add":"t"}],"sDate":"2018-06-01","eDate":"2018-06-29","meta":["name","state","ll","sids"],"bbox":[-74.44262803978918,40.4207924883181,-73.48808216021084,41.144936911681896]}
    }
    r = requests.post(url, json=payload)
    data = r.json()
    

    命名为data的对象现在将由具有天气数据的每个地方的dicts列表组成。每个判决都包含一个sid,您需要输入返回实际天气数据的endpoint。

    每个判决看起来像这样:

    {'ll': [-74.42259, 40.47282],
      'name': 'NEW BRUNSWICK 3 SE',
      'sids': ['286055 2', 'USC00286055 6', 'NBRN4 7'],
      'state': 'NJ'}
    

    假设你想循环通过所有这些和返回的天气数据为每个你首先需要抓住sid的和存储在一个列表中

    其中一些不包含天气数据。他们会看起来像这样:

    "US1NJES0018 6"
    

    ... 而那些有天气数据的人里面没有字母。正则表达式可以利用这一点过滤掉所有包含字母的sid。

    所以把这个附加到代码中:

    import re # the regex library
    sids_list = []
    
    is_garbage = re.compile('[a-zA-z]+') # will match everything with a letter in
    meta = data['meta']
    for m in meta:
        name = m['name']
        sid = m['sids'][0]
        if not is_garbage.search(sid):
            sids_list.append([name,sid])
    

    现在您已经有了一个sid列表,您所需要做的就是使用正确的有效负载到达最终endpoint,设置需要数据的日期,然后开始一个循环。

    start_date = "2018-06-01"
    end_date = "2018-07-01"
    for name, sid in sids_list:
        print("------------- DATA FOR {} (sid: {}) -------------".format(name,sid))
        print()
        payload2 = {
            "params": {
                "elems":
                [
                    {"name":"maxt","add":"t"},
                    {"name":"mint","add":"t"},
                    {"name":"pcpn","add":"t"},
                    {"name":"snow","add":"t"},
                    {"name":"snwd","add":"t"}
                ],
                "sid": sid,
                "sDate":start_date,
                "eDate":end_date},
            "output": "json"
        }
    
        weather_url = "https://data.rcc-acis.org/StnData"
        r = requests.post(weather_url, json=payload2)
        weather_data = r.json()['data']
        print("{:15}{:15}{:15}{:15}{:15}{:15}".format("Date", "MaxTemperature", "MinTemperature", "Precipitation", "Snowfall", "SnowDepth"))
        for Date, MaxTemperature, MinTemperature, Precipitation, Snowfall, SnowDepth in weather_data:
            print("{:15}{:15}{:15}{:15}{:15}{:15}".format(Date, MaxTemperature[0], MinTemperature[0], Precipitation[0], Snowfall[0], SnowDepth[0]))
        print()
    

    在这里,我只是在一个格式良好的视图中将数据打印到屏幕上。希望这能解决你的问题。干杯