一、爬取中國天氣網所有地區當天的天氣數據(PyCharm):
網址:https://www.weather.com.cn/
下面爬取數據:
因為現在已經到了夜間,所以白天的數據已經不見了,但原理是一樣的。
二、代碼以及詳情解釋:
?具體的代碼的url以及headers是要從檢查里面找的:
?
以及這些元素代碼的尋找:
這個代碼是一個用于從中國天氣網(weather.com.cn
)抓取天氣信息的Python腳本。它使用了?requests
?庫發送HTTP請求,并使用?BeautifulSoup
?庫解析HTML內容。以下是代碼的主要功能和相關知識點的羅列:
代碼功能概述
-
遍歷多個地區:代碼通過遍歷一個地區列表(
area
),構造不同的URL來獲取不同地區的天氣信息。 -
發送HTTP請求:使用?
requests.get()
?發送HTTP請求,獲取網頁的HTML內容。 -
解析HTML:使用?
BeautifulSoup
?解析HTML內容,提取所需的天氣信息。 -
提取天氣信息:從HTML中提取城市名稱、上午天氣、上午風力風向、上午最高溫度、晚上天氣、晚上風力風向、晚上最低溫度等信息。
-
去重處理:使用集合?
processed_cities
?來避免重復處理同一個城市的天氣信息。 -
打印結果:將提取的天氣信息格式化輸出到控制臺。
涉及的知識點
1. Python基礎
-
列表與循環:
-
使用列表?
area
?存儲地區代碼。 -
使用?
for
?循環遍歷列表中的每個地區。
-
-
字符串格式化:
-
使用?
f-string
(如?f"https://www.weather.com.cn/textFC/{page}.shtml"
)動態構造URL。
-
-
集合(Set):
-
使用集合?
processed_cities
?來存儲已經處理過的城市名稱,確保每個城市只被處理一次。
-
2. HTTP請求
-
requests
?庫:-
使用?
requests.get()
?發送HTTP GET請求,獲取網頁內容。 -
設置請求頭?
headers
,模擬瀏覽器訪問,避免被網站反爬蟲機制攔截。 -
使用?
res.encoding = 'utf-8'
?設置響應內容的編碼為UTF-8,確保中文內容正確顯示。
-
3. HTML解析
-
BeautifulSoup
?庫:-
使用?
BeautifulSoup(res.text, 'lxml')
?解析HTML內容,lxml
?是解析器。 -
使用?
soup.select()
?方法通過CSS選擇器查找HTML元素。 -
使用?
find()
?和?find_all()
?方法查找特定的HTML標簽和屬性。
-
4. HTML結構與CSS選擇器
-
HTML表格結構:
-
網頁中的天氣信息以表格形式展示,代碼通過查找?
<div class="conMidtab2">
?和?<tr>
、<td>
?標簽來提取數據。
-
-
CSS選擇器:
-
使用?
div.conMidtab2
?選擇所有?class
?為?conMidtab2
?的?<div>
?元素。 -
使用?
tr
?選擇表格行,td
?選擇表格單元格。
-
-
HTML屬性:
-
通過?
width
?屬性(如?width='83'
)定位特定的表格單元格。
-
5. 數據提取與處理
-
提取文本內容:
-
使用?
.string
?提取HTML標簽內的文本內容(如?tr.find('td', width='83').a.string
)。
-
-
條件判斷:
-
使用?
if
?語句檢查是否存在某個HTML元素或屬性,避免因元素不存在而報錯。
-
-
數據格式化與輸出:
-
使用?
print()
?函數將提取的天氣信息格式化輸出。
-
6. 去重與集合
-
集合(Set):
-
使用集合?
processed_cities
?存儲已經處理過的城市名稱,利用集合的唯一性特性避免重復處理。
-
7. 異常處理(未顯式實現)
-
代碼中沒有顯式的異常處理(如?
try-except
),但在實際應用中,建議添加異常處理機制,以應對網絡請求失敗或HTML解析錯誤等情況。
代碼執行流程
-
遍歷地區列表:
-
對每個地區代碼(如?
hb
、db
?等),構造對應的URL。
-
-
發送HTTP請求:
-
使用?
requests.get()
?獲取網頁內容。
-
-
解析HTML:
-
使用?
BeautifulSoup
?解析HTML,查找包含天氣信息的表格。
-
-
提取天氣信息:
-
遍歷表格行,提取城市名稱、天氣、風力風向、溫度等信息。
-
-
去重處理:
-
使用集合?
processed_cities
?避免重復處理同一城市。
-
-
輸出結果:
-
將提取的天氣信息格式化輸出到控制臺。
-
總結
這段代碼展示了如何使用Python進行網頁抓取和HTML解析,涉及的知識點包括:
-
Python基礎(列表、循環、字符串格式化、集合)
-
HTTP請求(
requests
?庫) -
HTML解析(
BeautifulSoup
?庫) -
HTML結構與CSS選擇器
-
數據提取與處理
-
去重與集合
通過這段代碼,可以學習如何從網頁中提取結構化數據,并將其用于進一步的分析或存儲。
import requests
from bs4 import BeautifulSoup# 定義地區列表
area = ["hb", "db", "hd", "hz", "hn", "xb", "xn", "gat"]for page in area:# 構造 URLurl = f"https://www.weather.com.cn/textFC/{page}.shtml"headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0"}# 發送 HTTP 請求獲取網頁內容res = requests.get(url=url, headers=headers)res.encoding = 'utf-8' # 設置編碼為 UTF-8# 使用 BeautifulSoup 解析網頁內容soup = BeautifulSoup(res.text, 'lxml')# 用于存儲已經處理過的城市名稱processed_cities = set()# 遍歷所有 class 為 conMidtab2 的 div 元素for div in soup.select('div.conMidtab2'):# 遍歷 div 中的所有 tr 元素(表格行)for tr in div.select('tr'):# 檢查當前行是否包含寬度為 83 的 td 元素,該元素可能包含城市信息if tr.find('td', width='83'):# 檢查寬度為 83 的 td 元素中是否有 a 標簽,a 標簽內通常是城市名if tr.find('td', width='83').a:# 提取城市名city = tr.find('td', width='83').a.string# 如果城市已經處理過,則跳過if city in processed_cities:continue# 否則,將城市添加到已處理集合中processed_cities.add(city)# 打印城市名print(f"城市:{city}")# 提取上午天氣信息morning_weather_td = tr.find('td', width='89')if morning_weather_td:morning_weather = morning_weather_td.stringprint(f"上午天氣:{morning_weather}")# 提取上午風力風向信息morning_wind_td = tr.find('td', width='162')if morning_wind_td:spans = morning_wind_td.find_all('span')if len(spans) >= 2:morning_wind_1 = spans[0].stringmorning_wind_2 = spans[1].stringprint(f"上午風力風向:{morning_wind_1} {morning_wind_2}")# 提取上午最高溫度morning_max_temp_td = tr.find('td', width='92')if morning_max_temp_td:morning_max_temp = morning_max_temp_td.stringprint(f"上午最高溫度:{morning_max_temp}")# 提取晚上天氣信息night_weather_td = tr.find('td', width='98')if night_weather_td:night_weather = night_weather_td.stringprint(f"晚上天氣:{night_weather}")# 提取晚上風力風向信息night_wind_td = tr.find('td', width='177')if night_wind_td:spans = night_wind_td.find_all('span')if len(spans) >= 2:night_wind_1 = spans[0].stringnight_wind_2 = spans[1].stringprint(f"晚上風力風向:{night_wind_1} {night_wind_2}")# 提取晚上最低溫度night_min_temp_td = tr.find('td', width='86')if night_min_temp_td:night_min_temp = night_min_temp_td.stringprint(f"晚上最低溫度:{night_min_temp}")# 打印分隔線,用于區分不同城市的天氣信息print('-----------------')else:# 如果當前行不包含寬度為 83 的 td 元素,跳過該行continue
三、代碼運行結果展示:
?
?