1
votes

I have tried using get requests with params, post requests with and without json.dumps but I can not seem to get the right response from the webpage.

I want to get back a text file with all the weather data. My code, the data I want, and the headers for the post request using the inspect on chrome is attached.

Thank you for any help!

You can also reach the data by

1
post your code here instead of an image file.Abhilash
Thank you! I couldn't figure out how to get the imports in the block though.Jack
select the code and enter Ctrl + K, refer stackoverflow.com/editing-help#code if you need more help.Abhilash

1 Answers

1
votes

You just have to set the payload right.

This will do the trick.

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()

The object named data will now consist of list of dicts for each place that has weather data. Each dict contain amongst other an sid, that you need to feed the endpoint that return the actual weather data.

Each dict will look like this:

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

Assuming that you want to loop through all these and return the weather data for each you first need to grab the sid's and store them in a list

Some of them, tho, does not contain weather data. They will look like this:

"US1NJES0018 6"

... while those that has weather data does not have letters in them. This can be exploited with a regex to filter away all sid's with letters in them.

So append this to the code:

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])

Now that you have a list of sid's, all you need to do is use the right payload to the final endpoint, set the dates you want data for - and start a loop.

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()

Here I'm just printing the data to screen in a nicely formatted view. Hope this solves your issue. Cheers.