2017-10-09 2 views
-1

Ich bin neu bei Python (eigentlich das zweite Mal, ich versuche, die Sprache zu lernen, damit ich etwas weiß) und ich versuche ein Skript zu erstellen, das die Wettervorhersage schabt.Python Web Scraping Weatherforecast

Jetzt habe ich ein kleines Problem mit dem Finden der richtigen HTML-Klassen, um in Python zu importieren. Ich habe diesen Code jetzt:

import requests 
from bs4 import BeautifulSoup 

page = requests.get("https://openweathermap.org/city/2743477") 
soup = BeautifulSoup(page.content, 'html.parser') 
city_name = soup.find(class_="weather-widget__city-name") 
print(city_name) 

Problem ist, dass dies nur zurückgibt ‚Keine‘

ich die Klasse gefunden, dass der Code sucht über Chrom und Seite überprüfen. Wenn ich mit dem folgenden Code der HTML-Seite durch Python exportieren:

import requests 
from bs4 import BeautifulSoup 

page = requests.get("https://openweathermap.org/city/2743477") 
soup = BeautifulSoup(page.content, 'html.parser') 
city_name = soup.find(class_="weather-widget__city-name") 
print(soup.prettify()) 

Dann habe ich die HTML-Seite in cmd sehen (wie erwartet), aber ich bin auch nicht in der Lage Klasse zu finden‘_ =‚Wetter-widget__city-name‘ Ich bin also nicht erstaunt, dass Python das auch nicht kann. Meine Frage ist, warum ist der HTML-Code, den Python mir anders gibt als der HTML-Code, den Chrome auf der Site zeigt? Und mache ich etwas falsch damit, auf diese Weise das Wetter-Widget von BeautifulSoup zu finden?

Hier ist ein Bild von der Seite, der Teil, den ich versuche zu kratzen ist in rot eingekreist.

Screenshot from website

Vielen Dank im Voraus!

+0

Du hast haben drei Antworten auf Ihre Frage, aber nach wie vor weder Sie betreut ihre Antworten zu reagieren und nicht einmal fühlte es notwendig, Dank zu sagen. Was für eine Höflichkeit !!!! – SIM

Antwort

0

Diese Site ist mit JS geladen.

Python-Anfragen aktivieren diese Skripte nicht. Eines dieser Skripte ist verantwortlich für das Laden der Daten, die Sie suchen (Sie können sehen, es ist JS, vielleicht mit ein bisschen jQuery Ich habe nicht wirklich überprüft, durch den rotierenden Kreis, während es geladen wird).

Mein Vorschlag hier ist die Verwendung der Websites API.

Ich habe die Seite nicht abonniert, also kann ich hier kein Beispiel zeigen, aber der Trick ist einfach. Sie abonnieren die Website-API mit dem einfachen (und kostenlosen) Plan, erhalten einen API-Schlüssel und starten das Senden von get-Anfragen an die API-URLs. Dies wird auch die Dinge für Sie weiter vereinfachen, da Sie BeautifulSoup für das Parsing nicht benötigen würden. Die Antworten sind alle in JSON.

Es gibt einen anderen näheren Weg drum herum und das benutzt selenium. Dieses Modul simuliert den Webbrowser und alle JS-aktivierenden, HTML-Rendering-, CSS-Lade-Mechanismen.

Ich habe Erfahrung mit beiden und ich empfehle dringend, bei der API zu bleiben (wenn diese Option existiert).

+0

Vielen Dank für Ihre Antwort! Ich habe in die API geschaut, aber diese nicht zum Laufen gebracht (ich habe mich angemeldet, aber es sind nur wenige Anfragen pro Stunde erlaubt, so dass ich nicht genug nach meinen Wünschen testen konnte). Auf der anderen Seite habe ich ein anderes API von ISS versucht und das funktioniert wie ein Zauber. Für die Zukunft würde ich auf jeden Fall mehr in APIs schauen. – Blub21

0

Für Websites, die JS verwenden, um weitere Anforderungen zu senden, nachdem wir die anfängliche URL angefordert haben, können Sie die Netzwerkregisterkarte der Chrome-Entwicklertools (oder die Entsprechung in jedem anderen Browser) untersuchen.

In der Regel finden Sie eine große Liste von URLs, die vom Browser angefordert werden. Die meisten von ihnen sind für unsere Zwecke unnötig. Und wenige von ihnen beziehen sich auf andere Seiten wie Google, Facebook.

In diesem speziellen Fall, nachdem die anfängliche URL angefordert wurde, finden Sie ein paar '.js' Dateien, die abgerufen werden, und danach drei Skripte (Vorhersage, Wetter, täglich), die den Daten entsprechen, die schließlich ankommen präsentiert vom Browser.

Aus diesen drei stammen die Daten, nach denen Sie fragen, aus dem "Wetter" -Skript. Wenn Sie auf der Registerkarte Netzwerk auf es klicken, wird ein anderes Seitenfenster geöffnet, das Kopfzeileninformationen, Vorschau usw. enthält.

In der Registerkarte Header finden Sie die URL, die Sie verwenden müssen, nämlich:

https://openweathermap.org/data/2.5/weather?id=2743477&units=metric&appid=b1b15e88fa797225412429c1c50c122a1 

Die b1b15e88fa797225412429c1c50c122a1 ist möglicherweise ein allgemeiner API-Schlüssel, der einer Browseranforderung zugewiesen ist. Ich weiß es nicht genau. Aber alles, was wir wissen müssen, ist, dass es sich nicht ändert. Ich habe zwei verschiedene Systeme ausprobiert und dieser Wert ändert sich nicht.

Die 2743477 ist natürlich die City ID. Sie können eine Referenz von verschiedenen Städten herunterladen und ihre IDs in ihrer Website selbst:

http://bulk.openweathermap.org/sample/

Wie nutmeg64 sagte, die Website reagiert tatsächlich mit einer JSON-Datei. Dies ist sowohl bei der API als auch bei der Anforderung dieser URL der Fall, die auf der Registerkarte "Netzwerk" eines Browsers zu finden ist.

Wie für die Codes im JSON erscheinen, gibt Ihnen die Website einen Verweis auf die Codes und ihre Bedeutung:

https://openweathermap.org/weather-conditions

Mit diesen Informationen können Sie verwenden requests und json abrufen und manipulieren die Daten. Hier ist ein Beispielskript:

from pprint import pprint 
import json 

import requests 

city_id = 2743477 
url = 'https://openweathermap.org/data/2.5/weather?id={}&units=metric&appid=b1b15e88fa797225412429c1c50c122a1'.format(city_id) 

req_headers = { 
    'Accept': '*/*', 
    'Accept-Encoding': 'gzip, deflate, br', 
    'Accept-Language': 'en-US,en;q=0.8', 
    'Connection': 'keep-alive', 
    'Host': 'openweathermap.org', 
    'Referer': 'https://openweathermap.org/city/2743477', 
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36' 
} 

s = requests.Session() 
r = s.get(url, headers=req_headers) 

d = json.loads(r.text) 
pprint(d) 

Doch wie nutmeg64 gesagt, es ist besser, die API zu verwenden, und der Versuchung widerstehen Sie die Seite mit mehr Anfragen überhäuft, als Sie wirklich brauchen.

Sie können hier alles über ihre API finden:

https://openweathermap.org/current

+0

Vielen Dank für Ihre Antwort !! Ich habe den Code ausprobiert und es hat mir wirklich geholfen, zu verstehen, wie diese Site aufgebaut wurde, und ich bin mir sicher, dass ich diese Technik für zukünftige Referenz verwenden kann. – Blub21

0

Verwendung Selen mit BeautifulSoup in Kombination ohne Not von dieser Seite eine der Tabelle zu erhalten. Hier ist, wie Sie tun können:

from selenium import webdriver 
from bs4 import BeautifulSoup 

driver=webdriver.Chrome() 
driver.get("https://openweathermap.org/city/2743477") 
soup = BeautifulSoup(driver.page_source, 'lxml') 
driver.quit() 
table_tag = soup.select(".weather-widget__items")[0] 
tab_data = [[item.text.strip() for item in row_data.select("td")] 
       for row_data in table_tag.select("tr")] 

for data in tab_data: 
    print(data) 

Teilergebnis:

['Wind', 'Gentle Breeze,\n  3.6 m/s, Southwest (220)'] 
['Cloudiness', 'Broken clouds'] 
['Pressure', '1014 hpa'] 
['Humidity', '100 %'] 
['Sunrise', '11:53'] 
+0

Danke für deinen Rat !! Ich werde mich definitiv darum kümmern !! – Blub21