Dies ist Qiitas erster Beitrag! Da ich ein Anfänger bin, denke ich, dass es viele Punkte gibt, die ich nicht erreichen kann, aber ich wäre dankbar, wenn Sie herzlich kommentieren könnten!
ruby: 2.7.1 rails: 6.0.3.2
Gehen Sie zur OpenWeatherMap-Homepage und erstellen Sie ein Konto über Anmelden mit Konto erstellen. Wenn Sie es über die gesendete E-Mail aktivieren, erhalten Sie einen API-SCHLÜSSEL.
Speichern Sie dies als Umgebungsvariable oder "Anmeldeinformationen". Dieses Mal werden wir "Anmeldeinformationen" verwenden. In Bezug auf "Anmeldeinformationen" ist der [Artikel] dieser Person (https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39) sehr hilfreich.
EDITOR=vi bin/rails credentials:edit
credentials.yml.enc
open_weahter:
appid: <API_KEY>
uri: https://samples.openweathermap.org/data/2.5/forecast
Da ich dieses Mal alle 3 Stunden das Wetter erhalte, erhalte ich außerdem die URI, um die Anfrage unter Bezugnahme auf das API-Dokument zu senden.
Es scheint, dass es viele Arten von Wetter gibt, die sogar mit der kostenlosen Stufe erhalten werden können! Es ist interessant, verschiedene API-Dokumente zu durchsuchen.
Laden Sie city.list.json
aus der API-Dokumentation herunter (https://openweathermap.org/forecast5). [Screenshot 2020-08-02 15.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684915/9535a511-db9d-f4b3-f042- 028b93b1c498.png)
Erhalten Sie aus dieser Datei die STADT-ID der Stadt, die Sie erhalten möchten. Dies ist ein Teilauszug des Inhalts. Lon bedeutet übrigens Längengrad und Lat bedeutet Breitengrad.
city.list.json
{
"id": 1850147,
"name": "Tokyo",
"state": "",
"country": "JP",
"coord": {
"lon": 139.691711,
"lat": 35.689499
}
},
Ich habe geweint, um diesen Ausweis zu bekommen ... Bitte beachten Sie, dass einige Städte mit demselben Namen unterschiedliche Breiten- und Längengrade haben!
Wenn Sie Excel oder Mac verwenden, sollten Sie sie in Zahlen auflisten und in CSV konvertieren! Die von mir erstellte CSV sieht übrigens so aus. Ich kratzte ein paar Säulen.
db/csv/cities.csv
Sapporo,2128295
Aomori,2130658
Morioka,2111834
Sendai,2111149
Akita,2113126
Yamagata,2110556
Fukushima,2112923
Mito,2111901
Utsunomiya,1849053
Maebashi,1857843
Saitama,6940394
Chiba,2113015
Tokio,1850147
Yokohama,1848354
Niigata,1855431
Toyama,1849876
Kanazawa,1860243
Fukui,1863983
Yamanashi,1848649
Nagano,1856215
Gifu,1863640
Shizuoka,1851715
Nagoya,1856057
Tsu,1849796
Otsu,1853574
Kyoto,1857910
Osaka,1853909
Kobe,1859171
Nara,1855612
Wakayama,1926004
Tottori,1849890
Matsue,1857550
Okayama,1854383
Hiroshima,1862415
Yamaguchi,1848689
Tokushima,1850158
Takamatsu,1851100
Matsuyama,1926099
Kochi,1859146
Fukuoka,1863967
Saga,1853303
Nagasaki,1856177
Kumamoto,1858421
Oita,1854487
Miyazaki,1856717
Kagoshima,1860827
Naha,1856035
Schreiben Sie den Code in seeds.rb
oder task
und speichern Sie ihn in der Datenbank. Dieses Mal habe ich es unter "lib / task" implementiert. CITY ID speichert den Spaltennamen als "location_id".
import_csv.rake
desc 'Import cities'
task cities: [:environment] do
list = []
CSV.foreach('db/csv/cities.csv') do |row|
list << {
name: row[0],
location_id: row[1],
}
end
puts 'start creating cities'
begin
City.create!(list)
puts 'completed!'
rescue ActiveModel::UnknownAttributeError
puts 'raised error: unknown attributes'
end
end
Laden Sie die zuvor mit der Methode CSV.foreach erstellte city.csv
Zeile für Zeile. Sie können den Städtenamen in der ersten Spalte mit "row [0]" und die CITY-ID in der zweiten Spalte mit "row [1]" abrufen. Erstellen Sie also ein Array von Hashes und speichern Sie es in der Datenbank mit "City.create!" Ich bin.
Analysieren Sie vor dem Implementieren der HTTP-Anforderung zunächst die JSON-Datei der Antwort.
API-Dokument enthält eine ausführliche Erläuterung der einzelnen Elemente. Lesen Sie daher das Dokument, um den Schlüssel der gewünschten Daten zu erhalten. Eine Anfrage für eine Stadt wird im folgenden JSON-Format zurückgesendet. (Wenn Sie den Befehl curl oder VScode verwenden, sollten Sie ihn mit REST Client versuchen.)
example_resopnse.json
{
"cod": "200",
"message": 0,
"cnt": 40,
"list": [
{
"dt": 1578409200,
"main": {
"temp": 284.92,
"feels_like": 281.38,
"temp_min": 283.58,
"temp_max": 284.92,
"pressure": 1020,
"sea_level": 1020,
"grnd_level": 1016,
"humidity": 90,
"temp_kf": 1.34
},
"weather": [
{
"id": 804,
"main": "Clouds",
"description": "overcast clouds",
"icon": "04d"
}
],
"clouds": {
"all": 100
},
"wind": {
"speed": 5.19,
"deg": 211
},
"sys": {
"pod": "d"
},
"dt_txt": "2020-01-07 15:00:00"
},
Dieses Mal erstelle ich eine Tabelle mit den folgenden Elementen.
"Regen" wird der Liste nur hinzugefügt, wenn es Niederschlag gibt.
Die Wetter-ID finden Sie unter hier. OpenWeatherMap klassifiziert das Wetter nach ID. Es ist auch möglich, das Wetter aus der Beschreibung zu erhalten. Da es jedoch viele Typen gibt, wird in dieser Implementierung die Wetter-ID in der Datenbank gespeichert und das Wetter von der Methode zugewiesen.
Fügen Sie zunächst httpclient zu Ihrer Gemfile hinzu und installieren Sie das Paket.
gem 'httpclient', '~> 2.8', '>= 2.8.3'
Erstellen Sie dann "lib / api / open_weather_map / request.rb". Ich dachte, es wäre nicht notwendig, es so tief zu machen, aber ich entschied mich, die Dateien so anzuordnen, um andere Klassen für diese API und andere API-Klassen zu implementieren.
Standardmäßig wird nur die Aufgabe unter lib geladen, daher sind die folgenden Einstellungen in config / application.rb
erforderlich. Da es sich um "eifrige_Ladungspfade" handelt, ist auch die Produktionsumgebung in Ordnung.
config/application.rb
config.paths.add 'lib', eager_load: true
Ich würde mich sehr freuen, wenn Sie auf Punkte wie "Hey, das ist großartig" hinweisen könnten. Die Platzierung von Dateien war das größte Problem bei dieser Implementierung ...
WeatherForecast-Tabelle zum Speichern von Anfragen ↓
WeatherForecast | |
---|---|
temp_max | float |
temp_min | float |
temp_feel | float |
weather_id | int |
rainfall | float |
date | datetime |
aquired_at | datetime |
Das Folgende ist die implementierte Request-Klasse.
request.rb
module Api
module OpenWeatherMap
class Request
attr_accessor :query
def initialize(location_id)
@query = {
id: location_id,
units: 'metric',
appid: Rails.application.credentials.open_weather[:appid],
}
end
def request
client = HTTPClient.new
request = client.get(Rails.application.credentials.open_weather[:uri], query) #Der Rückgabewert sind Daten für 5 Tage alle 3 Stunden
JSON.parse(request.body)
end
def self.attributes_for(attrs)
rainfall = attrs['rain']['3h'] if attrs['rain']
date = attrs['dt_txt'].in_time_zone('UTC').in_time_zone
{
temp_max: attrs['main']['temp_max'],
temp_min: attrs['main']['temp_min'],
temp_feel: attrs['main']['feels_like'],
weather_id: attrs['weather'][0]['id'],
rainfall: rainfall,
date: date,
aquired_at: Time.current,
}
end
end
end
end
Die Abfragezeichenfolge wird mit initialize
gesetzt. Die für diese Anforderung erforderliche Abfragezeichenfolge fügt "location_id" und API KEY hinzu, um die CITY-ID anzugeben, und "unit:" metric ", um die Temperaturanzeige in Grad Celsius zu ändern.
Die Methode attribute_for
wird in eine Klassenmethode umgewandelt, um die zurückgegebene Anforderung in ein Formular zu konvertieren, das in der Datenbank gespeichert werden kann.
Was Sie beachten müssen, ist die Niederschlagsmenge und das Prognosedatum.
Informationen zum Umgang mit Zeitzonen finden Sie in diesem Artikel.
Ich möchte die Datenbank regelmäßig speichern / aktualisieren, daher schreibe ich sie in "Rake Task". Trotzdem habe ich die meisten Methoden in der Klasse "Request" früher geschrieben, also muss ich sie nur verwenden.
open_weather_api.rake
namespace :open_weather_api do
desc 'Requests and save in database'
task weather_forecasts: :environment do
City.all.each do |city|
open_weather = Api::OpenWeatherMap::Request.new(city.location_id)
#Anforderungslimit: 60 mal/min
response = open_weather.request
#Speichern Sie alle 3 Stunden 2 Tage Daten
16.times do |i|
params = Api::OpenWeatherMap::Request.attributes_for(response['list'][i])
if weather_forecast = WeatherForecast.where(city: city, date: params[:date]).presence
weather_forecast[0].update!(params)
else
city.weather_forecasts.create!(params)
end
end
end
puts 'completed!'
end
end
Dieses Mal haben wir festgelegt, dass die Daten 2 Tage lang alle 3 Stunden in der Datenbank gespeichert und aktualisiert werden sollen. Der Punkt ist das Anforderungslimit und ob es sich um die Erstellung oder Aktualisierung von Daten handelt.
Anwesenheits
Methode ist eine Methode, die die Gegenwart?
Methode aufruft und den Empfänger selbst zurückgibt, wenn true. Wenn dieselbe Datenbank für dieselbe Stadt bereits in der Datenbank vorhanden ist, wird "update!" Aufgerufen, andernfalls wird "create!" Aufgerufen.Wenn Sie ein Wettersymbol vorbereiten, das der gespeicherten "Wetter-ID" entspricht, sieht es wie eine Wettervorhersage aus! Ich denke, es ist eine gute Idee, API regelmäßig mit Cron oder "Heroku Schedular" für Heroku zu schlagen!
Es wurde so angezeigt!
Vielen Dank für das Lesen des langen Textes!
https://openweathermap.org/api https://qiita.com/yoshito410kam/items/26c3c6e519d4990ed739
Recommended Posts