# Python收集数据存储到MySQL数据库的完整指南
## 1. 环境准备与数据库连接
### 1.1 安装必要的Python库
```python
# 安装pymysql库用于连接MySQL数据库
pip install pymysql
# 安装pandas库用于数据处理(可选)
pip install pandas
```
### 1.2 建立数据库连接
```python
import pymysql
def connect_mysql():
"""
连接MySQL数据库的基本方法
"""
try:
# 创建数据库连接
connection = pymysql.connect(
host='localhost', # 数据库主机地址
user='root', # 数据库用户名
password='password', # 数据库密码
database='test_db', # 数据库名称
charset='utf8mb4', # 字符编码
cursorclass=pymysql.cursors.DictCursor # 返回字典格式的结果
)
print("数据库连接成功!")
return connection
except pymysql.Error as e:
print(f"数据库连接失败: {e}")
return None
```
## 2. 数据存储的多种实现方式
### 2.1 基础单条数据插入
```python
def insert_single_data(connection, data):
"""
插入单条数据到数据库
"""
try:
with connection.cursor() as cursor:
# SQL插入语句
sql = """
INSERT INTO movie_info
(title, rating, director, release_year)
VALUES (%s, %s, %s, %s)
"""
# 执行SQL语句
cursor.execute(sql, (data['title'], data['rating'],
data['director'], data['release_year']))
# 提交事务
connection.commit()
print("数据插入成功!")
except pymysql.Error as e:
print(f"数据插入失败: {e}")
connection.rollback() # 回滚事务
```
### 2.2 批量数据插入(高效方式)
```python
def batch_insert_data(connection, data_list):
"""
批量插入数据到数据库,提高插入效率
"""
try:
with connection.cursor() as cursor:
sql = """
INSERT INTO movie_info
(title, rating, director, release_year)
VALUES (%s, %s, %s, %s)
"""
# 使用executemany进行批量插入
cursor.executemany(sql, data_list)
connection.commit()
print(f"批量插入 {len(data_list)} 条数据成功!")
except pymysql.Error as e:
print(f"批量插入失败: {e}")
connection.rollback()
```
### 2.3 爬虫数据存储完整示例
```python
import requests
from bs4 import BeautifulSoup
import pymysql
import time
class MovieSpider:
def __init__(self):
self.connection = self.connect_db()
self.create_table()
def connect_db(self):
"""连接数据库"""
return pymysql.connect(
host='localhost',
user='root',
password='password',
database='movie_db',
charset='utf8mb4'
)
def create_table(self):
"""创建数据表"""
with self.connection.cursor() as cursor:
create_table_sql = """
CREATE TABLE IF NOT EXISTS movies (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
rating DECIMAL(3,1),
director VARCHAR(100),
release_year INT,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"""
cursor.execute(create_table_sql)
self.connection.commit()
def crawl_movie_data(self):
"""爬取电影数据"""
# 模拟爬取数据
movie_data = [
('肖申克的救赎', 9.7, '弗兰克·德拉邦特', 1994),
('阿甘正传', 9.5, '罗伯特·泽米吉斯', 1994),
('泰坦尼克号', 9.4, '詹姆斯·卡梅隆', 1997)
]
return movie_data
def store_data(self):
"""存储数据到数据库"""
movie_data = self.crawl_movie_data()
try:
with self.connection.cursor() as cursor:
sql = """
INSERT INTO movies (title, rating, director, release_year)
VALUES (%s, %s, %s, %s)
"""
cursor.executemany(sql, movie_data)
self.connection.commit()
print("电影数据存储成功!")
except Exception as e:
print(f"数据存储失败: {e}")
self.connection.rollback()
def close(self):
"""关闭数据库连接"""
if self.connection:
self.connection.close()
# 使用示例
if __name__ == "__main__":
spider = MovieSpider()
spider.store_data()
spider.close()
```
## 3. 使用Pandas进行数据存储
### 3.1 Pandas DataFrame存储到MySQL
```python
import pandas as pd
from sqlalchemy import create_engine
def pandas_to_mysql(df, table_name):
"""
使用Pandas将DataFrame存储到MySQL数据库
"""
try:
# 创建数据库引擎
engine = create_engine(
'mysql+pymysql://username:password@localhost/database_name'
)
# 将DataFrame存储到数据库
df.to_sql(
name=table_name, # 表名
con=engine, # 数据库连接
if_exists='append', # 如果表存在则追加数据
index=False # 不存储索引列
)
print("Pandas数据存储成功!")
except Exception as e:
print(f"Pandas存储失败: {e}")
# 示例:创建测试数据并存储
data = {
'product_name': ['手机', '电脑', '平板'],
'price': [2999, 5999, 3999],
'stock': [100, 50, 80]
}
df = pd.DataFrame(data)
pandas_to_mysql(df, 'products')
```
## 4. 不同场景下的存储策略对比
| 存储方式 | 适用场景 | 优点 | 缺点 |
|---------|---------|------|------|
| 单条插入 | 数据量小,实时性要求高 | 简单易用,实时性强 | 效率低,不适合大数据量 |
| 批量插入 | 数据量大,批量处理 | 效率高,减少连接开销 | 内存占用较大 |
| Pandas存储 | 数据分析场景 | 与pandas完美集成,支持复杂操作 | 需要额外依赖 |
| Scrapy存储 | 爬虫框架集成 | 框架原生支持,管道化管理 | 学习成本较高 |
## 5. 实战案例:商品评论数据存储
```python
import pymysql
import json
from datetime import datetime
class CommentStorage:
def __init__(self):
self.db_config = {
'host': 'localhost',
'user': 'root',
'password': 'password',
'database': 'comment_db',
'charset': 'utf8mb4'
}
self.init_database()
def init_database(self):
"""初始化数据库和表结构"""
connection = pymysql.connect(**self.db_config)
try:
with connection.cursor() as cursor:
# 创建评论表
create_table_sql = """
CREATE TABLE IF NOT EXISTS product_comments (
id INT AUTO_INCREMENT PRIMARY KEY,
product_id VARCHAR(50) NOT NULL,
user_name VARCHAR(100),
comment_text TEXT,
rating TINYINT,
comment_time DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_product (product_id),
INDEX idx_time (comment_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
"""
cursor.execute(create_table_sql)
connection.commit()
finally:
connection.close()
def store_comments(self, comments_data):
"""存储评论数据"""
connection = pymysql.connect(**self.db_config)
try:
with connection.cursor() as cursor:
sql = """
INSERT INTO product_comments
(product_id, user_name, comment_text, rating, comment_time)
VALUES (%s, %s, %s, %s, %s)
"""
# 准备批量插入数据
batch_data = []
for comment in comments_data:
batch_data.append((
comment['product_id'],
comment['user_name'],
comment['comment_text'],
comment['rating'],
comment['comment_time']
))
# 执行批量插入
cursor.executemany(sql, batch_data)
connection.commit()
print(f"成功存储 {len(comments_data)} 条评论数据")
except Exception as e:
print(f"存储评论数据失败: {e}")
connection.rollback()
finally:
connection.close()
# 模拟评论数据
sample_comments = [
{
'product_id': 'P001',
'user_name': '用户A',
'comment_text': '商品质量很好,送货速度快',
'rating': 5,
'comment_time': datetime.now()
},
{
'product_id': 'P001',
'user_name': '用户B',
'comment_text': '性价比高,会再次购买',
'rating': 4,
'comment_time': datetime.now()
}
]
# 存储示例
storage = CommentStorage()
storage.store_comments(sample_comments)
```
## 6. 最佳实践与注意事项
### 6.1 数据库连接管理
```python
class DatabaseManager:
def __init__(self, config):
self.config = config
self.connection_pool = []
def get_connection(self):
"""获取数据库连接(简单连接池)"""
if not self.connection_pool:
return pymysql.connect(**self.config)
else:
return self.connection_pool.pop()
def release_connection(self, connection):
"""释放连接回连接池"""
if connection.open:
self.connection_pool.append(connection)
```
### 6.2 异常处理与事务管理
```python
def safe_data_operation(operation_func, *args):
"""
安全的数据操作封装
"""
connection = connect_mysql()
if not connection:
return False
try:
result = operation_func(connection, *args)
connection.commit()
return result
except Exception as e:
print(f"操作失败: {e}")
connection.rollback()
return False
finally:
if connection:
connection.close()
```
### 6.3 性能优化建议
1. **使用连接池**:避免频繁创建和关闭连接
2. **批量操作**:大数据量时使用批量插入
3. **索引优化**:为查询字段添加合适索引
4. **事务控制**:合理使用事务保证数据一致性
5. **字符编码**:使用utf8mb4支持emoji等特殊字符
通过以上方法和示例,您可以灵活地将Python收集的各种数据高效、安全地存储到MySQL数据库中。根据具体业务场景选择合适的存储策略,并注意数据库的性能优化和数据一致性保障[ref_1][ref_2][ref_4]。