🌐 編程基礎第一期《9-30》–使用python中的第三方模塊requests,和三個內置模塊(re、json、pprint),實現百度地圖的近15天天氣信息抓取
記得安裝
pip install requests
📑 項目介紹
網絡爬蟲是Python最受歡迎的應用場景之一,通過爬蟲技術,我們可以自動獲取互聯網上的各種數據資源。本文將帶您實現一個簡易爬蟲,抓取百度地圖的15天天氣預報數據,這是一個非常實用的入門級爬蟲項目。
🔍 爬蟲實現思路
爬蟲開發的核心步驟通常包括:網頁分析、構造請求、數據提取和數據處理。下面我們將按照這個流程來實現我們的天氣數據爬蟲。
1. 網頁結構分析
首先,我們需要分析目標網頁的結構,找出我們需要的數據在哪里。
步驟一:訪問目標頁面
步驟二:查看頁面內容
步驟三:打開開發者工具
進入瀏覽器控制臺,可以按F12
,或者鼠標右鍵 —》檢查
步驟四:定位數據元素
這個案例是需要獲取天氣的【日期、溫度、天氣】,這三個字段
如果是直接搜索相應的數據的話,是搜不到的,而且有點亂【Ctrl+F:搜索】,所以就用最笨的方法查看數據了,博主也是很快定位到了數據【15_day_forecast】
通過分析,我們發現天氣數據是通過JavaScript動態加載的,數據存儲在window.tplData
變量中,具體是在15_day_forecast
對象里。這意味著我們需要使用正則表達式從頁面源碼中提取這部分數據。
2. 獲取請求參數
為了模擬瀏覽器發送請求,我們需要獲取完整的請求參數,包括headers、cookies等。
使用工具轉換請求格式
我們可以使用curlconverter.com工具,將瀏覽器復制的curl命令轉換為Python代碼:
這個工具可以幫助我們快速生成請求所需的cookies、headers和params等參數,大大簡化了爬蟲開發過程。
3. 代碼實現
下面是完整的Python爬蟲代碼實現:
import requests
import re
import json
from pprint import pprintcookies = {'BAIDUID': 'D9390E952557E33F7CCC1A0109B7FA36:FG=1','PSTM': '1724329650','BIDUPSID': '32FE4B5E017DB09C400649766FC53D1B','H_WISE_SIDS_BFESS': '60360_60621_60630_60665_60677','BAIDUID_BFESS': 'D9390E952557E33F7CCC1A0109B7FA36:FG=1','ZFY': 'G4IF74JdDWkiPzA7wsun:A9:AdrfYQK3wASfOCR3zneJ0:C','__bid_n': '196e65bedde90245f15fbf','H_WISE_SIDS': '62325_62967_63195_63241_63247_63266','BDRCVFR[VXHUG3ZuJnT]': 'I67x6TjHwwYf0','H_PS_PSSID': '61672_62325_62967_63148_63195_63211_63241_63247_63255_63266_63325_63366_63389_63380_63186_63395_63392_63390_63403','delPer': '0','PSINO': '1','BDORZ': 'FFFB88E999055A3F8A630C64834BD6D0','BA_HECTOR': '242lah0h85202k00202lal8h0k0ga61k3b6p924','Hm_lvt_3535ee208b02ecdf4b2576fd444e8473': '1748343601','Hm_lpvt_3535ee208b02ecdf4b2576fd444e8473': '1748343601','HMACCOUNT': 'BF9680BBBCADEAE7',
}headers = {'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','accept-language': 'zh-CN,zh;q=0.9','cache-control': 'no-cache','pragma': 'no-cache','priority': 'u=0, i','referer': 'https://www.baidu.com/link?url=ajB3uWQlmNXyVidQRV-1nepXkS-ZUJDTJP3_HkueruWRBti13-iGBZJC1qMnR8pVgkLXHUxRWG8iv9tlJZFuVD0UqvTN1KpXcH5Sjltgq93cArc4Ocpl5irtWM2zRTYi0nVOHUeSWeV3ArpliNJvgErF2AaOpuWN6Jzb_yPJd3_DDH4uDBSFAENIXFV98SgaWmQyD7eE7wSJtPaZK-Y_5a&wd=&eqid=e24cffc50001782a0000000368359b29','sec-ch-ua': '"Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"','sec-fetch-dest': 'document','sec-fetch-mode': 'navigate','sec-fetch-site': 'same-site','sec-fetch-user': '?1','upgrade-insecure-requests': '1','user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',# 'cookie': 'BAIDUID=D9390E952557E33F7CCC1A0109B7FA36:FG=1; PSTM=1724329650; BIDUPSID=32FE4B5E017DB09C400649766FC53D1B; H_WISE_SIDS_BFESS=60360_60621_60630_60665_60677; BAIDUID_BFESS=D9390E952557E33F7CCC1A0109B7FA36:FG=1; ZFY=G4IF74JdDWkiPzA7wsun:A9:AdrfYQK3wASfOCR3zneJ0:C; __bid_n=196e65bedde90245f15fbf; H_WISE_SIDS=62325_62967_63195_63241_63247_63266; BDRCVFR[VXHUG3ZuJnT]=I67x6TjHwwYf0; H_PS_PSSID=61672_62325_62967_63148_63195_63211_63241_63247_63255_63266_63325_63366_63389_63380_63186_63395_63392_63390_63403; delPer=0; PSINO=1; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; BA_HECTOR=242lah0h85202k00202lal8h0k0ga61k3b6p924; Hm_lvt_3535ee208b02ecdf4b2576fd444e8473=1748343601; Hm_lpvt_3535ee208b02ecdf4b2576fd444e8473=1748343601; HMACCOUNT=BF9680BBBCADEAE7',
}params = {'query': '廣東深圳天氣','srcid': '4982','forecast': 'long_day_forecast',
}response = requests.get('https://weathernew.pae.baidu.com/weathernew/pc', params=params, cookies=cookies,headers=headers)
# 獲取天氣數據
tplData = re.findall(r'window.tplData = (.*?);', response.text)[0]
# 這個數據是`str`類型,所以需要轉換成json數據類型,然后再獲取數據
tpl_15_day_forecast = json.loads(tplData)['15_day_forecast']['info']
# 定義一個空列表
recently_data = []
for tpl in tpl_15_day_forecast:date = tpl['date']temperature = tpl['temperature_night'] + ' ~ ' + tpl['temperature_day'] + '°C'weather = tpl['weather_night']recently_data.append({"date": date, "temperature": temperature, "weather": weather})# 整齊輸出
pprint(recently_data)
4. 運行效果
執行上述代碼后,我們可以得到格式化的15天天氣預報數據:
🔎 代碼解析與知識點
這個簡單的爬蟲項目涵蓋了多個Python爬蟲開發的關鍵知識點,下面我們來詳細分析:
1. HTTP請求與網絡通信
- requests模塊應用:使用Python最流行的HTTP客戶端庫發送GET請求
- 請求參數構造:通過params、cookies和headers參數模擬瀏覽器行為
- 防反爬策略:通過設置User-Agent、Referer等頭信息,避免被目標網站識別為爬蟲
# 發送HTTP GET請求示例
response = requests.get('https://weathernew.pae.baidu.com/weathernew/pc', params=params, cookies=cookies,headers=headers)
2. 正則表達式數據提取
- re模塊應用:使用Python內置的正則表達式模塊提取特定模式的文本
- 貪婪與非貪婪匹配:使用
.*?
進行非貪婪匹配,精確定位目標數據 - 捕獲組:使用括號
()
創建捕獲組,提取匹配的內容
# 正則表達式提取示例
tplData = re.findall(r'window.tplData = (.*?);', response.text)[0]
3. JSON數據處理
- json模塊應用:使用Python內置的JSON模塊解析字符串為Python對象
- 數據序列化與反序列化:將字符串轉換為Python對象(反序列化)
- 復雜數據結構訪問:通過鍵名訪問嵌套的JSON數據
# JSON解析示例
tpl_15_day_forecast = json.loads(tplData)['15_day_forecast']['info']
4. 數據結構與處理
- 列表操作:創建空列表并使用append方法添加元素
- 字典操作:創建包含多個鍵值對的字典對象
- 循環遍歷:使用for循環遍歷列表中的每個元素
- 字符串拼接:使用
+
運算符連接多個字符串
# 數據處理示例
recently_data = []
for tpl in tpl_15_day_forecast:date = tpl['date']temperature = tpl['temperature_night'] + ' ~ ' + tpl['temperature_day'] + '°C'weather = tpl['weather_night']recently_data.append({"date": date, "temperature": temperature, "weather": weather})
5. 格式化輸出
- pprint模塊應用:使用Python的美化打印模塊,以更易讀的方式顯示復雜數據結構
- 數據可視化:將提取的數據以結構化、易讀的方式展示
# 格式化輸出示例
pprint(recently_data)
📚 學習要點總結
- 網絡爬蟲基礎:HTTP請求、響應處理、模擬瀏覽器行為
- 數據提取技術:正則表達式、JSON解析
- Python模塊應用:requests、re、json、pprint
- 網頁分析方法:使用開發者工具定位數據元素
- 數據處理技巧:列表、字典操作,數據結構轉換
- 爬蟲倫理與合規:遵守網站robots.txt規則,合理控制請求頻率
通過這個項目,您可以掌握Python爬蟲開發的基本流程和技術要點,為進一步學習更復雜的爬蟲項目打下堅實基礎。
今日分享語錄
與其攀比他人,不如攀比昨天的自己