Python3 OpenWeather API с использованием сокетов - PullRequest
0 голосов
/ 08 февраля 2019

есть простой способ получить тот же вывод, импортируя только «сокеты», как эти 3 строки кода, используя urllib:

url = 'http://api.openweathermap.org/data/2.5/weather?q={}&appid={}&units=metric'.format(city, api_key)
uh = urllib.request.urlopen(url)
weather_decoded = uh.read().decode()

, где, например, город Лондон, а ключ api_key - ваш (выможно запустить в вашем терминале с помощью: curl "the url", чтобы вы могли видеть выходной файл json

weather_decoded теперь содержит файл json с текущей информацией о городе

Есть ли простой/ Smart способ сделать то же самое, используя «импорт сокета» вместо импорта urrlib

На данный момент у меня есть следующее:

импорт сокета

server = 'api.openweathermap.org'
url = 'http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=b498767252de12f92504d2cca9c3fdc1'
port = 80

request = "GET / HTTP/1.1\nHost: " + url + "\n\n"
request_bytes = str.encode(request)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((server, port))
    s.sendall(request_bytes)
    data = s.recv(4096)

print(repr(data))

Но это простовозвращает, что я использую неверный запрос, что я, очевидно, и делаю, но большинство найденных мной запросов пока выглядят так же, как мои.

Вывод, который я получаю:

b'HTTP/1.1 400 Bad Request\r\nServer: openresty\r\nDate: Fri, 08 Feb 2019 18:48:58 GMT\r\nContent-Type: text/html\r\nContent-Length: 166\r\nConnection: close\r\n\r\n<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body bgcolor="white">\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n'

ВыводЯ ищу (файл JSON с URL):

{"coord":{"lon":-0.13,"lat":51.51},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"base":"stations","main":{"temp":282.45,"pressure":993,"humidity":87,"temp_min":281.15,"temp_max":283.15},"visibility":10000,"wind":{"speed":5.7,"deg":230},"clouds":{"all":20},"dt":1549650000,"sys":{"type":1,"id":1414,"message":0.0039,"country":"GB","sunrise":1549610791,"sunset":1549645418},"id":2643743,"name":"London","cod":200}

1 Ответ

0 голосов
/ 08 февраля 2019
url = 'http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=b498767252de12f92504d2cca9c3fdc1'
port = 80

request = "GET / HTTP/1.1\nHost: " + url + "\n\n"

HTTP-запрос должен содержать путь после GET и домен в заголовке Host.Это означает, что запрос должен выглядеть следующим образом:

GET /data/2.5/weather?q=London,... HTTP/1.1
Host: api.openweathermap.org

Кроме того, конец строки должен быть \r\n, а не \n, хотя этому конкретному серверу все равно.Кроме того, лучше использовать HTTP/1.0 вместо HTTP/1.1, чтобы вам не приходилось иметь дело с сообщениями о поддержании соединения и фрагментарными ответами, хотя этот конкретный сервер в настоящее время также не использует это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...