在爬虫项目中,我们爬取到的海量数据(比如二手房信息、图书数据)最终需要落地存储,而 MySQL 作为最常用的关系型数据库,是很多开发者的首选。但用 Python 操作 MySQL 时,你是否也遇到过 “数据插入失败”“日期格式错误”“表结构不匹配” 等问题?
今天就以实际爬虫项目为例,聊聊 PyMySQL 的核心用法与避坑指南,帮你从 “爬取数据” 到 “数据库存储” 实现无缝衔接。
一、为什么选择 PyMySQL?
在 Python 中操作 MySQL 的库有很多,而 PyMySQL 因其轻量、易用、兼容性好成为主流选择。它允许我们用 Python 代码直接执行 SQL 语句,实现数据库连接、表创建、数据插入等操作,尤其适合爬虫这类需要批量处理数据的场景。
比如我们今天爬取的二手房信息、图书数据,都可以通过 PyMySQL 快速存入数据库,方便后续分析或展示。
二、PyMySQL 核心操作:从连接到存储全流程
1. 数据库连接:参数配置是基础
连接 MySQL 的第一步是配置参数,核心参数包括主机地址(host)、用户名(user)、密码(password)、数据库名(db)等。这些参数建议用字典统一管理,方便维护:
python
运行
db_config = {
"host": "127.0.0.1", # 本地数据库默认地址
"user": "root", # 数据库用户名
"password": "123456", # 数据库密码(替换为你的密码)
"db": "rapper", # 数据库名(需提前创建)
"charset": "utf8mb4", # 支持中文及特殊字符
"port": 3306 # MySQL默认端口
}
# 建立连接
import pymysql
conn = pymysql.connect(**db_config)
cursor = conn.cursor() # 创建游标(执行SQL的工具)
避坑点:
- 数据库名(db)需提前在 MySQL 中创建(可通过
CREATE DATABASE rapper;实现),否则会报 “数据库不存在” 错误。 - 字符集建议用
utf8mb4,避免中文乱码(utf8不支持部分特殊字符)。
2. 创建表:字段设计要 “留有余地”
爬取数据前,需先创建对应的表结构。以二手房信息为例,我们需要存储 “卖点、楼盘、地址、户型、面积、单价” 等字段,表结构设计如下:
python
运行
# 创建表的SQL语句
create_table_sql = """
CREATE TABLE IF NOT EXISTS houseinfo (
id INT PRIMARY KEY AUTO_INCREMENT, # 自增主键,方便查询
title VARCHAR(255), # 卖点标题(长度留有余地)
community VARCHAR(255), # 楼盘名称
address VARCHAR(255), # 地址
house_type VARCHAR(50), # 户型(如3室2厅)
area VARCHAR(50), # 面积(如89㎡)
price VARCHAR(50) # 单价(如16465元/㎡)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"""
# 执行创建表操作
cursor.execute(create_table_sql)
conn.commit() # 提交事务
避坑点:
- 字段类型选择要灵活:爬虫数据格式可能不固定(比如面积可能带 “㎡”,单价带 “元 /㎡”),先用
VARCHAR存储更稳妥,后续可再清洗为数值型。 - 用
IF NOT EXISTS避免重复创建:多次运行代码时,不会因 “表已存在” 报错。
3. 插入数据:批量操作更高效
爬取并解析数据后,需要将数据批量插入数据库。PyMySQL 的executemany方法支持批量插入,比单条插入效率高 10 倍以上:
python
运行
# 假设爬取到的二手房数据是列表套列表格式
house_data = [
["急售!精装三房", "万科金域学府", "重庆市渝中区XX路", "3室2厅", "89㎡", "16465元/㎡"],
["地铁口两居室", "龙湖时代天街", "重庆市江北区XX街", "2室1厅", "65㎡", "18230元/㎡"]
]
# 插入数据的SQL(用%s作为占位符,避免SQL注入)
insert_sql = """
INSERT INTO houseinfo (title, community, address, house_type, area, price)
VALUES (%s, %s, %s, %s, %s, %s)
"""
# 批量插入
cursor.executemany(insert_sql, house_data)
conn.commit() # 提交事务(必须执行,否则数据不生效)
避坑点:
- 占位符必须用
%s:即使字段是数值型,也用%s,PyMySQL 会自动处理类型转换。 - 务必提交事务:MySQL 默认需要手动提交(
conn.commit()),否则插入的数据不会真正保存到数据库。
4. 错误处理:事务回滚保数据一致
爬虫数据可能存在格式异常(比如缺失字段、日期格式错误),需用try-except捕获错误,并通过rollback回滚事务,避免部分数据插入成功、部分失败导致的不一致:
python
运行
try:
cursor.executemany(insert_sql, house_data)
conn.commit()
print(f"成功插入{len(house_data)}条数据")
except Exception as e:
conn.rollback() # 出错时回滚事务
print(f"插入失败:{e}")
finally:
# 无论成功与否,都要关闭游标和连接,释放资源
cursor.close()
conn.close()
常见错误及解决:
Incorrect date value:日期字段格式错误(如空字符串、非YYYY-MM-DD格式),需将无效日期转为None(对应 MySQL 的NULL)。Column count doesn't match:插入的字段数量与表结构不一致,检查insert_sql的字段顺序与数据列表是否对应。
三、实战技巧:让爬虫数据存储更稳
-
动态处理异常数据
爬取的数据可能存在缺失(比如部分房源没有单价),插入前需用默认值填充:python
运行
# 处理空值:将空字符串转为None clean_data = [] for item in house_data: cleaned = [x if x.strip() else None for x in item] clean_data.append(cleaned) -
分页数据分批插入
爬取多页数据时,每爬一页插入一页,避免内存占用过高:python
运行
for page in range(1, 11): # 爬取1-10页 html = get_html(f"http://www.bspider.top/anjuke/?page={page}") data = parser(html) # 解析当前页数据 save_to_mysql(data) # 调用插入函数 -
用上下文管理器自动关闭连接
用with语句管理连接和游标,无需手动关闭,代码更简洁:python
运行
with pymysql.connect(** db_config) as conn: with conn.cursor() as cursor: cursor.executemany(insert_sql, house_data) conn.commit()
四、总结:从 0 到 1 掌握 PyMySQL 的核心
PyMySQL 作为 Python 操作 MySQL 的利器,在爬虫项目中不可或缺。核心步骤可总结为:
- 配置连接参数,建立数据库连接;
- 设计合理的表结构,用
CREATE TABLE创建表; - 用
executemany批量插入数据,提高效率; - 用
try-except捕获错误,commit和rollback管理事务; - 关闭连接,释放资源。
掌握这些技巧,你就能轻松搞定爬虫数据的存储问题,让数据从 “临时变量” 真正变成 “可复用的资产”。下次爬取数据时,不妨试试这套流程,避坑又高效!
3440

被折叠的 条评论
为什么被折叠?



