Это мой первый вопрос о стеке.
Я начал с kivy и купил книгу «Создание приложений в Kivy» у Дасти Филлипса, и все шло хорошо, пока он не добрался до главы openweatherapp. (С чем после поиска у других пользователей тоже были проблемы...) Там вы используете API Openweather для поиска местоположения с помощью кнопки, и он должен распечатать результаты в списке.
Это уже не оригинальный код. Другие указывали, что ссылка на сайт изменилась, нужно использовать API-ключ. Конечно, я связал его правильно, я просто набрал здесь «myAPIKey», поэтому он недоступен. Файл JSON внизу — это то, что печатает сайт!
Кроме того, книга отформатировала города в найденном местоположении следующим образом: d['name], d['sys']['country'], что, я думаю, тоже было неправильным, может быть, здесь тоже изменился сайт?
Моя проблема в том, что UrlRequest от kivy ничего не загружает. Или итерация в найденном месте неверна, я не знаю. Он всегда говорит «KeyError: city». И я думаю, это потому, что он вообще не читает его правильно. Я попробовал другой подход с запросами класса python - и он отлично работает! Но я все еще хочу знать, почему это решение не работает.
Мои вопросы: где моя ошибка с итерацией json? У меня действительно проблемы с пониманием, потому что я тоже новичок в python.
Также: Почему запрос находится в голове метода? Где он используется?
Вот код из книги (надеюсь все набрал правильно. Если все же ошибка с переменными, укажите на нее, но я набирал код несколько раз - моя проблема, вероятно, будет где-то еще...):
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.network.urlrequest import UrlRequest
import json
class AddLocationForm(BoxLayout):
search_input = ObjectProperty()
search_results = ObjectProperty()
def search_location(self):
search_template = "http://api.openweathermap.org/data/2.5/forecast/daily?APPID=myAPIKey=" + "{}"
search_url = search_template.format(self.search_input.text)
request = UrlRequest(search_url, self.found_location)
def found_location(self, request, data):
data = json.loads(data.decode()) if not isinstance(data, dict) else data
cities = ["{} ({})".format(d["city"]["name"], d["city"]["country"])for d in data["list"]]
self.search_results.item_strings = cities
КВ файл:
AddLocationForm:
<AddLocationForm>:
orientation: "vertical"
search_input: search_box
search_results: search_results_list
BoxLayout:
height: "40dp"
size_hint_y: None
TextInput:
id: search_box
size_hint_x: 50
Button:
text: "Search"
size_hint_x: 25
on_press: root.search_location()
Button:
text: "Current Location"
size_hint_x: 25
ListView:
id: search_results_list
item_strings: []
JSON-файл:
{
"city": {
"id": 2761369,
"name": "Vienna",
"coord": {
"lon": 16.37208,
"lat": 48.208488
},
"country": "AT",
"population": 0
},
"cod": "200",
"message": 0.0098,
"cnt": 7,
"list": [{
"dt": 1476439200,
"temp": {
"day": 285.58,
"min": 283.71,
"max": 285.58,
"night": 283.71,
"eve": 285.43,
"morn": 285.58
},
"pressure": 985.46,
"humidity": 73,
"weather": [{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}],
"speed": 7.16,
"deg": 154,
"clouds": 0
}, {
"dt": 1476525600,
"temp": {
"day": 287.33,
"min": 282.7,
"max": 291.08,
"night": 285.72,
"eve": 291.01,
"morn": 283.35
},
"pressure": 983.21,
"humidity": 71,
"weather": [{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}],
"speed": 4.51,
"deg": 150,
"clouds": 32,
"rain": 0.23
}, {
"dt": 1476612000,
"temp": {
"day": 286.88,
"min": 283.94,
"max": 287.15,
"night": 283.94,
"eve": 286.44,
"morn": 286.26
},
"pressure": 989.94,
"humidity": 98,
"weather": [{
"id": 501,
"main": "Rain",
"description": "moderate rain",
"icon": "10d"
}],
"speed": 4.36,
"deg": 315,
"clouds": 92,
"rain": 5.51
}, {
"dt": 1476698400,
"temp": {
"day": 287.39,
"min": 283.49,
"max": 287.39,
"night": 284.89,
"eve": 285.05,
"morn": 283.49
},
"pressure": 984.76,
"humidity": 0,
"weather": [{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}],
"speed": 1.64,
"deg": 132,
"clouds": 69,
"rain": 1.55
}, {
"dt": 1476784800,
"temp": {
"day": 285.91,
"min": 283.52,
"max": 285.91,
"night": 283.52,
"eve": 284.45,
"morn": 284.18
},
"pressure": 982.64,
"humidity": 0,
"weather": [{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}],
"speed": 3.23,
"deg": 137,
"clouds": 81,
"rain": 2.4
}, {
"dt": 1476871200,
"temp": {
"day": 283.71,
"min": 282.37,
"max": 283.71,
"night": 282.37,
"eve": 282.52,
"morn": 282.59
},
"pressure": 978.26,
"humidity": 0,
"weather": [{
"id": 502,
"main": "Rain",
"description": "heavy intensity rain",
"icon": "10d"
}],
"speed": 2.68,
"deg": 128,
"clouds": 96,
"rain": 14.37
}, {
"dt": 1476957600,
"temp": {
"day": 286.52,
"min": 282.13,
"max": 286.52,
"night": 282.13,
"eve": 282.72,
"morn": 282.19
},
"pressure": 975.05,
"humidity": 0,
"weather": [{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}],
"speed": 1.47,
"deg": 173,
"clouds": 13,
"rain": 2.83
}]
}
Кстати, это не дубликат как мне использовать json api в моей программе kivy, потому что это не очень помогло... Код больше не работает, потому что изменился API.
(Если кто-то найдет этот вопрос и ищет работающую программу для чтения URL-адресов, вот мой код. Не забудьте импортировать запросы)
def search_location(self):
#Get URL From Weather API + Input
search_template = "http://api.openweathermap.org/data/2.5/forecast/daily?APPID='enteryourweatherAPIKeyhere'&q=" + "{}"
search_url = search_template.format(self.search_input.text)
#Reads the Website and saves it in a string
urlresults = (requests.get(search_url)).text
#Converts Json to Python Dictionary
urlresults = json.loads(urlresults)
cities = ["{} ({})".format(urlresults["city"]["name"], urlresults["city"]["country"])]