2017-10-09 84 views
-1

我是Python新手(實際上第二次嘗試學習語言,所以我知道一些東西),並且我正在嘗試構建一個腳本來擦除天氣預報。python web scraping Weatherforecast

現在我有一個小問題找到正確的html類導入到python。我現在有這樣的代碼:

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) 

問題是,這只是返回「無」

我發現,通過鍍鉻的代碼搜索和檢查網頁的類。如果我通過蟒蛇用下面的代碼導出HTML頁面:

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

然後我看到在cmd中的HTML頁面(如預期),但我也無法找到「類_ =‘天氣widget__city名’ '所以我並不驚訝,蟒蛇也無法。我的問題是,爲什麼python給我的html代碼不同於Chrome代碼顯示在網站上的html代碼?我是否在嘗試通過BeautifulSoup以這種方式查找天氣小部件時遇到了問題?

這是一張來自頁面的圖片,我試圖颳去的部分是用紅色圈起來的。

Screenshot from website

提前感謝!

+0

你已經得到了你的問題,三個答案,但你還是沒有照顧到他們的回答迴應,甚至也不覺得有必要說感謝。多麼文明! – SIM

回答

0

該網站加載了JS。

Python請求不會激活這些腳本。其中一個腳本負責加載你正在查找的數據(你可以看到它是JS,也許有點jQuery,我沒有真正檢查,在加載時由旋轉圓圈檢查)。

我的建議是使用網站API

我沒有訂閱該網站,所以我不能在這裏展示一個例子,但訣竅很簡單。您使用基本(免費)計劃訂閱網站API,獲取API密鑰並開始向API URL發送獲取請求。 這也將進一步簡化您的工作,因爲您不需要BeautifulSoup進行解析。所有回覆均以JSON格式顯示。

還有另一種更糟糕的方式,那就是使用selenium。該模塊將模擬Web瀏覽器及其所有的JS激活,HTML渲染,CSS加載機制。

我有兩種經驗,我強烈建議堅持API(如果該選項存在)。

+0

謝謝你的回答!我已經看過API,但沒有得到這個工作(我已經註冊了,但每小時只有幾個請求被允許,所以我無法測試到我的喜好)。另一方面,我嘗試了另一個來自國際空間站的API,它的功能就像一個魅力。所以對於未來我肯定會更關注API。 – Blub21

0

對於使用JS發送更多請求的站點,在我們請求初始URL之後,一種可行的方法是研究Chrome開發人員工具(或任何其他瀏覽器中的等效項)的網絡選項卡。

您通常會發現瀏覽器請求的大量URL。他們中的大多數對我們的目的來說是不必要其中很少涉及其他網站,如Google,Facebook。

在這種特殊情況下,在請求初始URL之後,您會發現一些'.js'文件正在被檢索,之後會有三個腳本(預測,天氣,每日)對應於最終得到的數據由瀏覽器呈現。

從這三者中,您要求的數據來自'天氣'腳本。如果您在網絡選項卡中點擊它,另一側欄會打開其中將包含頭信息,預覽等

在頭選項卡,你會發現,你需要使用的URL,這是:

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

b1b15e88fa797225412429c1c50c122a1可能是分配給瀏覽器請求的通用API密鑰。我不確定。但是我們需要知道的是它不會改變。我試過兩種不同的系統,這個值不會改變。

2743477當然是城市ID。您可以下載其網站本身各個城市的參考及其ID:

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

正如nutmeg64說,該網站實際上是一個JSON文件響應。 API和在瀏覽器的網絡選項卡中找到的此URL的請求都是這種情況。

至於出現在JSON的代碼,該網站給你一個參考代碼及其含義:

https://openweathermap.org/weather-conditions

有了這些信息,你可以使用requestsjson檢索和操縱數據。下面是一個示例腳本:

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) 

然而,正如nutmeg64說,這是更好地使用API​​,並抵制誘惑,轟炸更多的要求比你真正需要的網站。

你可以找到所有關於他們的API在這裏:在BeautifulSoup組合

https://openweathermap.org/current

+0

謝謝你的回答!我試過了代碼,它確實幫助我瞭解了這個網站是如何構建的,並且我確信我可以使用這種技術作爲未來的參考 – Blub21

0

使用硒從沒有困苦頁面得到任何表。這裏是你如何能做到:

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) 

部分結果:

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

感謝您的建議!我一定會考慮它! – Blub21