从零到精通的实战指南
目录导读
- 抓取脚本的核心逻辑与工具选择
- 环境搭建:Python与必要库的安装
- 第一步:分析网页表格结构(HTML与XPath/CSS)
- 第二步:编写基础抓取代码(静态表格与动态表格)
- 第三步:批量处理URL与数据导出
- 第四步:应对反爬与异常处理
- 实战案例:抓取政府公开数据表格
- 常见问题解答(FAQ)
抓取脚本的核心逻辑与工具选择
在批量抓取网页表格前,需要理解三个核心概念:

- 结构化数据:网页表格通常以
<table>标签呈现,但现代网页常使用<div>+CSS模拟表格。 - 动态加载:部分表格内容由JavaScript渲染(如AJAX请求),需使用Selenium或Playwright。
- 合规性:抓取前务必检查
robots.txt,避免侵犯版权或违反服务条款。
推荐工具栈:
- 基础版:Python + Requests + BeautifulSoup(适合静态页面)。
- 进阶版:Python + Selenium + Pandas(适合动态页面与大数据处理)。
- 轻量版:Node.js + Puppeteer(适合前端开发者)。
选择标准:
- 若表格数据在页面源码中直接可见 → 选Requests+BeautifulSoup。
- 若需模拟滚动、点击等交互 → 选Selenium或Playwright。
环境搭建:Python与必要库的安装
步骤:
- 安装Python 3.8+(建议使用虚拟环境)。
- 打开终端,执行以下命令:
pip install requests beautifulsoup4 lxml pandas selenium
- 若使用Selenium,还需下载浏览器驱动(如ChromeDriver),并放置于系统PATH或指定路径。
验证安装:
import requests
from bs4 import BeautifulSoup
print("环境准备就绪!")
第一步:分析网页表格结构
方法:
- 右键目标网页 → “检查” → 定位到表格区域。
- 查看标签:
- 静态表格:
<table>→<tr>行 →<td>单元格。 - 动态表格:
<div class="table-wrap">→ JS生成的数据。
- 静态表格:
提取关键信息:
- XPath示例:
//table[@id='data-table']//tr - CSS选择器示例:
table#data-table tr
工具推荐:
- 浏览器开发者工具直接复制XPath。
- 使用Chrome插件“XPath Helper”快速测试。
第二步:编写基础抓取代码
1 静态表格抓取(以天池大赛公开数据集为例)
import requests
from bs4 import BeautifulSoup
url = "https://tianchi.aliyun.com/dataset/XXX" # 示例域名
response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})
soup = BeautifulSoup(response.text, 'lxml')
# 定位表格
table = soup.find('table', {'class': 'table'}) # 根据实际调整
rows = table.find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
cols = [ele.text.strip() for ele in cols]
data.append(cols)
print(data)
2 动态表格抓取(需Selenium)
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
driver.get("https://example.com/dynamic-table") # 示例域名
time.sleep(3) # 等待页面渲染
# 抓取所有行
rows = driver.find_elements(By.XPATH, "//div[@class='table-row']")
for row in rows:
cells = row.find_elements(By.TAG_NAME, "span")
print([cell.text for cell in cells])
driver.quit()
第三步:批量处理URL与数据导出
1 批量URL管理
- 从CSV或文本文件读取URL列表:
urls = [] with open('urls.txt', 'r') as f: urls = [line.strip() for line in f]
2 循环抓取与去重
import pandas as pd
all_data = []
for url in urls:
# 抓取代码(同上)
# 添加去重逻辑(使用集合检查URL是否已抓取)
all_data.extend(data) # 合并数据
df = pd.DataFrame(all_data)
df.to_csv('output.csv', index=False, encoding='utf-8-sig')
第四步:应对反爬与异常处理
1 常见反爬策略
- IP限制:使用代理池(如付费代理或免费代理列表)。
- User-Agent检测:随机切换UA:
from fake_useragent import UserAgent ua = UserAgent() headers = {'User-Agent': ua.random} - Cookie验证:模拟登录后保存Session。
- 验证码:使用OCR库(如Tesseract)或手动标注。
2 异常处理模板
import time
from requests.exceptions import RequestException
def safe_request(url, retries=3):
for i in range(retries):
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
return response
except RequestException as e:
print(f"第{i+1}次重试:{e}")
time.sleep(2)
return None
实战案例:抓取政府公开数据表格
场景:抓取某省统计局发布的月季数据表格(静态页面)。
步骤:
- 分析URL模式:
https://data.stat.gov.cn/table?page=1→ 分页参数为page。 - 编写循环脚本,逐页抓取。
- 使用Pandas清洗数据(去除空行、合并重复列)。
- 导出为Excel或CSV。
关键代码:
for page in range(1, 11):
url = f"https://data.stat.gov.cn/table?page={page}"
data = fetch_table(url)
df = pd.DataFrame(data)
df.to_excel(f'output_page{page}.xlsx', index=False)
常见问题解答(FAQ)
Q1:抓取到的表格数据出现乱码怎么办?
A:在requests.get()中指定编码:response.encoding = 'utf-8'或gbk(根据网页实际编码)。
Q2:表格内容动态加载,Selenium抓取速度太慢?
A:可尝试直接抓取AJAX接口(按F12查看网络请求,找到返回JSON的URL)。
Q3:如何判断表格是静态还是动态?
A:在浏览器中禁用JavaScript后刷新页面,若表格消失则为动态。
Q4:抓取大量数据时被封IP如何解决?
A:使用代理队列,每次请求更换IP,并设置合理的请求间隔(如2-5秒)。
Q5:表格格式不统一(合并单元格)如何提取?
A:使用rowspan或colspan属性解析,或直接定位每个单元格的CSS类。
Q6:抓取结果中带有\n或多余空格怎么办?
A:使用strip()方法清理,或正则替换:re.sub(r'\s+', ' ', text)。
Q7:需要抓取的表格数量超过1000个,脚本容易中断?
A:加入断点续传功能,记录已成功抓取的URL,失败URL写入日志。
Q8:是否有可视化工具可直接抓取表格?
A:Octoparse、Web Scraper(Chrome插件)适合非开发者,但灵活性不如脚本。
Q9:抓取的数据如何自动存入数据库?
A:使用sqlite3(小规模)或pymysql(大规模),将DataFrame直接写入数据库。
Q10:脚本运行一直报错“元素未找到”?
A:检查网页是否使用iframe嵌套表格,需先切换iframe:
driver.switch_to.frame('iframe_name')
通过以上步骤,你已掌握从分析网页结构到编写完整抓取脚本的全流程,关键在于:先小规模测试,再批量执行,实际项目中,建议先抓取3-5个页面验证逻辑,确认无误后再扩展,遵守目标网站的robots.txt是长期稳定抓取的前提,打开你的IDE,开始实践吧!