Python 网络爬虫实战:从原理到数据抓取与存储
什么是网络爬虫?
网络爬虫(Web Crawler),又称为网页蜘蛛或网络机器人,是一种按照既定规则自动抓取万维网信息的程序或脚本。简单来说,它是互联网上的信息搬运工。
爬虫的基本规则
在编写爬虫之前,必须了解并遵守相关规则,尤其是 robots.txt 协议。这是一个存放在网站根目录下的文本文件,用于告知搜索引擎哪些内容可以抓取,哪些禁止抓取。遵循此协议是合法合规爬取数据的前提。
爬虫工作原理
爬虫的工作流程通常包含以下步骤:
- 发送请求:向目标服务器发送 HTTP 请求。
- 获取响应:接收服务器返回的 HTML、JSON 等数据。
- 解析数据:从响应中提取所需信息。
- 保存数据:将提取的数据存储到本地数据库或文件中。
- 循环迭代:根据链接继续抓取下一页或新页面。
项目背景与环境准备
本次实战以爬取某木材价格指数网站的红木价格数据为例,旨在演示如何从静态网页中批量获取结构化数据。
开发环境
- 语言版本:Python 3.7+
- 集成开发环境:PyCharm 或 VS Code
- 浏览器:Chrome(用于抓包分析)
依赖库安装
我们需要安装以下第三方库:
pip install requests lxml
代码中涉及的库说明:
requests:用于发送 HTTP 请求。
lxml:高效的 XML/HTML 解析库,支持 XPath。
csv:标准库,用于将数据写入 CSV 文件。
time / random:用于控制请求频率,模拟人类行为。
第一步:网页结构分析
打开目标网站,按 F12 打开开发者工具,切换到 Network 标签页。刷新页面后,观察请求列表。我们关注的是包含数据的接口请求。
通过观察可以发现:
- 请求方式:GET。
- 请求参数:URL 中包含分页参数(如
page.curPage)和搜索关键词。
- 请求头:包含
User-Agent 等信息,用于标识客户端身份。
为了模拟真实浏览器访问,我们需要构造包含 User-Agent 的请求头,否则服务器可能识别为脚本而拒绝服务。
第二步:单页数据抓取与解析
首先尝试抓取第一页数据。使用 requests.get() 发送请求,并使用 lxml.etree 解析 HTML。
核心代码实现
import csv
import time
import random
import requests
from lxml import etree
headers = {
'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36"
}
url = 'http://yz.yuzhuprice.com:8003/findPriceByName.jspx?page.curPage=1&priceName=%E7%BA%A2%E6%9C%A8%E7%B1%BB'
try:
response = requests.get(url, headers=headers, timeout=10)
response.encoding = response.apparent_encoding
html = response.text
parse = etree.HTML(html)
all_tr = parse.xpath('//table[@id="173200"]//tr')
for tr in all_tr:
name = ''.join(tr.xpath('./td[1]/text()')).strip()
price = ''.join(tr.xpath('./td[2]/text()')).strip()
unit = ''.join(tr.xpath('./td[3]/text()')).strip()
supermarket = ''.join(tr.xpath('./td[4]/text()')).strip()
time_str = ''.join(tr.xpath('./td[5]/text()')).strip()
data = {
'name': name,
'price': price,
'unit': unit,
'supermaket': supermarket,
'time': time_str
}
print(data)
except Exception as e:
print(f"发生错误:{e}")
解析说明
- XPath 语法:
//table[@id="173200"]//tr 表示查找 ID 为 173200 的表格下的所有行。
- 数据清洗:使用
.strip() 去除首尾空格,避免脏数据。
- 异常处理:使用
try...except 捕获网络错误或解析错误,防止程序崩溃。
第三步:多页数据爬取
单页数据量有限,实际应用中通常需要遍历多页。通过观察 URL 参数,我们发现 page.curPage 控制页码。
翻页逻辑
利用 for 循环遍历页码范围,动态拼接 URL。
for page in range(1, 10):
url = f'http://yz.yuzhuprice.com:8003/findPriceByName.jspx?page.curPage={page}&priceName=%E7%BA%A2%E6%9C%A8%E7%B1%BB'
第四步:完善爬虫稳定性
为了防止 IP 被封禁或触发反爬机制,需要增加随机延时和异常重试机制。
最佳实践
- 随机延时:每次请求间隔随机时间(如 1-3 秒),模拟人工操作。
- 代理 IP:在复杂场景下可引入代理池。
- 异常重试:遇到超时或连接错误时自动重试。
完整封装示例
将上述逻辑封装为函数,便于维护和扩展。
import csv
import time
import random
import requests
from lxml import etree
def crawl_page(page_num):
url = f'http://yz.yuzhuprice.com:8003/findPriceByName.jspx?page.curPage={page_num}&priceName=%E7%BA%A2%E6%9C%A8%E7%B1%BB'
headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
try:
response = requests.get(url, headers=headers, timeout=10)
response.encoding = response.apparent_encoding
html = response.text
parse = etree.HTML(html)
all_tr = parse.xpath('//table[@id="173200"]//tr')
data_list = []
for tr in all_tr:
name = ''.join(tr.xpath('./td[1]/text()')).strip()
price = ''.join(tr.xpath('./td[2]/text()')).strip()
unit = ''.join(tr.xpath('./td[3]/text()')).strip()
supermarket = ''.join(tr.xpath('./td[4]/text()')).strip()
time_str = ''.join(tr.xpath('./td[5]/text()')).strip()
if name and price:
data_list.append({
'name': name,
'price': price,
'unit': unit,
'supermaket': supermarket,
'time': time_str
})
return data_list
except Exception e:
()
[]
():
fieldnames = [, , , , ]
(filename, , encoding=, newline=) fp:
writer = csv.DictWriter(fp, fieldnames=fieldnames)
fp.tell() == :
writer.writeheader()
row data_list:
writer.writerow(row)
():
total_pages =
i (, total_pages + ):
()
data = crawl_page(i)
data:
save_to_csv(data)
()
:
()
sleep_time = random.uniform(, )
time.sleep(sleep_time)
()
__name__ == :
main()
结语
本文详细介绍了使用 Python 进行基础网页爬虫的完整流程,包括环境搭建、请求发送、HTML 解析、多页遍历及数据存储。通过本案例,读者可以掌握 requests 和 lxml 库的核心用法。
在实际生产环境中,爬虫技术还可以进一步结合 Scrapy 框架、多线程并发、代理 IP 池以及验证码识别等技术,以应对更复杂的反爬策略。此外,获取数据后的可视化分析(如价格走势图表)也是数据分析的重要环节。
希望本教程能帮助初学者快速入门网络爬虫技术,并在合法合规的前提下高效获取所需数据。