這個代碼是一個用于爬取國家統計局網站數據的Python腳本。下面我將詳細解釋代碼的各個部分及其設計思路。
代碼結構概述
import requests # 發送HTTP請求
from bs4 import BeautifulSoup # 解析HTML
import pandas as pd # 數據處理和存儲
import time # 時間控制
import random # 隨機數生成
import os # 文件系統操作
import re # 正則表達式
函數設計思路
1. 請求頭設置
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp...','referer': 'https://www.stats.gov.cn/sj/zxfbhjd/202508/t20250822_1960866.html'
}
設計思路:
-
模擬真實瀏覽器行為,避免被網站反爬機制攔截
-
設置Referer頭,使請求看起來是從合法頁面跳轉而來
-
使用常見的User-Agent字符串,增加請求的合法性
2. 隨機延遲機制
time.sleep(random.uniform(1, 3))
設計思路:
-
避免過于頻繁的請求導致IP被封
-
使用隨機時間間隔,模擬人類操作的不規律性
-
1-3秒的間隔既不會太慢影響效率,也不會太快觸發反爬
3. 請求與響應處理
response = requests.get(url, headers=headers, timeout=30)
response.encoding = 'utf-8' # 設置編碼
設計思路:
-
設置30秒超時,避免長時間等待無響應
-
顯式設置編碼為UTF-8,確保中文正確顯示
-
檢查狀態碼,確保請求成功
4. 表格解析與處理
tables = soup.find_all('table')
# 分析表格結構
max_cols = 0
for j, row in enumerate(rows):cells = row.find_all(['td', 'th'])if len(cells) > max_cols:max_cols = len(cells)
設計思路:
-
查找頁面中的所有表格
-
分析每個表格的結構,確定最大列數
-
確保每行數據有相同的列數,避免DataFrame創建時出錯
代碼解析
1. tables = soup.find_all('table')
-
作用:查找HTML文檔中的所有
<table>
元素 -
設計思路:國家統計局的數據通常以表格形式展示,所以首先找到所有表格
2. cells = row.find_all(['td', 'th'])
-
作用:在每一行中查找所有的
<td>
(表格數據單元格)和<th>
(表格標題單元格)元素 -
為什么同時查找td和th:
-
<td>
是普通數據單元格 -
<th>
是表頭單元格,通常包含列標題 -
兩者都需要提取,因為表頭也包含重要信息
-
有些表格可能混合使用td和th,或者使用th作為行標題
-
3. if len(cells) > max_cols: max_cols = len(cells)
-
作用:確定表格的最大列數
-
為什么需要這個:
-
HTML表格可能有不規則結構(某些行可能有合并的單元格)
-
為了創建規整的DataFrame,需要知道表格的最大寬度
-
確保所有行都有相同的列數,不足的用空值填充
-
設計思路詳解
1. 處理不規則表格
HTML表格可能有不規則結構,例如:
<table><tr><th>標題1</th><th>標題2</th><th>標題3</th></tr><tr><td>數據1</td><td colspan="2">合并單元格</td> <!-- 這一行只有2個單元格,但占據2列 --></tr>
</table>
在這種情況下,代碼會:
-
第一行:找到3個單元格(th),設置max_cols=3
-
第二行:找到2個單元格(td),但max_cols保持3
-
后續處理時,第二行會被填充到3列(添加一個空單元格)
2. 確保數據規整性
通過確定最大列數,可以:
-
創建統一結構的DataFrame
-
避免因列數不一致導致的數據錯位
-
保持數據的完整性,便于后續分析
3. 完整的工作流程
這段代碼是完整表格處理流程的一部分:
-
找到所有表格
-
對每個表格,確定最大列數
-
逐行處理,確保每行有相同的列數
-
創建規整的二維數組
-
轉換為DataFrame進行后續處理
<