国家统计局数据爬取——机器学习
这个代码是一个用于爬取国家统计局网站数据的Python脚本。下面我将详细解释代码的各个部分及其设计思路。
代码结构概述
import requests # 发送HTTP请求from bs4 import BeautifulSoup # 解析HTMLimport 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 = 0for 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文档中的所有
元素
设计思路:国家统计局的数据通常以表格形式展示,所以首先找到所有表格
2.
cells = row.find_all([\'td\', \'th\'])
-
作用:在每一行中查找所有的
(表格数据单元格)和 (表格标题单元格)元素 为什么同时查找td和th:
-
是普通数据单元格 是表头单元格,通常包含列标题 两者都需要提取,因为表头也包含重要信息
有些表格可能混合使用td和th,或者使用th作为行标题
3.
if len(cells) > max_cols: max_cols = len(cells)
-
作用:确定表格的最大列数
-
为什么需要这个:
-
HTML表格可能有不规则结构(某些行可能有合并的单元格)
-
为了创建规整的DataFrame,需要知道表格的最大宽度
-
确保所有行都有相同的列数,不足的用空值填充
-
设计思路详解
1. 处理不规则表格
HTML表格可能有不规则结构,例如:
标题1 标题2 标题3 数据1 合并单元格 在这种情况下,代码会:
-
第一行:找到3个单元格(th),设置max_cols=3
-
第二行:找到2个单元格(td),但max_cols保持3
-
后续处理时,第二行会被填充到3列(添加一个空单元格)
2. 确保数据规整性
通过确定最大列数,可以:
-
创建统一结构的DataFrame
-
避免因列数不一致导致的数据错位
-
保持数据的完整性,便于后续分析
3. 完整的工作流程
这段代码是完整表格处理流程的一部分:
-
找到所有表格
-
对每个表格,确定最大列数
-
逐行处理,确保每行有相同的列数
-
创建规整的二维数组
-
转换为DataFrame进行后续处理
<