<think>我们正在讨论如何将爬取的数据存入数据库。根据引用内容,我们可以总结出以下关键步骤:
1. 连接数据库:需要提供数据库的地址、端口、用户名、密码、数据库名以及字符编码。
2. 创建游标:通过连接对象创建游标,用于执行SQL语句。
3. 执行SQL语句:包括创建表(如果需要)和插入数据。
4. 提交事务:对于增删改操作,需要提交事务以使更改生效。
5. 关闭连接:操作完成后关闭游标和数据库连接。
引用中提供了两种不同的数据库操作方式:一种是使用MySQLdb(引用[2]),另一种是使用pymysql(引用[3])。MySQLdb是Python2时代常用的库,而pymysql是Python3中更常用的MySQL连接库。
下面我们将分别使用pymysql和MySQLdb(如果环境支持)来演示如何将爬取的数据存入数据库。
步骤:
1. 安装数据库驱动:如果使用pymysql,则安装pymysql;如果使用MySQLdb,则安装mysqlclient(MySQLdb的Python3兼容版本)。
2. 建立数据库连接。
3. 创建游标对象。
4. 执行SQL语句(创建表、插入数据等)。
5. 提交事务。
6. 关闭游标和连接。
示例1:使用pymysql
首先安装pymysql:`pip install pymysql`
然后参考以下代码:
```python
import pymysql
# 1. 连接数据库
db = pymysql.connect(
host="数据库地址",
port=3306, # 端口,默认为3306
user="用户名",
password="密码",
database="数据库名",
charset='utf8mb4' # 一般使用utf8mb4以支持存储Emoji表情
)
# 2. 创建游标
cursor = db.cursor()
# 3. 执行SQL语句
# 创建表(如果表不存在)
create_table_sql = """
CREATE TABLE IF NOT EXISTS articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
url VARCHAR(255) NOT NULL,
tags VARCHAR(255),
create_date DATE,
content TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"""
cursor.execute(create_table_sql)
# 假设我们有一个item,包含需要插入的数据
item = {
'title': '示例标题',
'url': 'https://example.com',
'tags': '示例,标签',
'create_date': '2023-01-01',
'content': '这是文章内容'
}
# 插入数据的SQL语句
insert_sql = """
INSERT INTO articles (title, url, tags, create_date, content)
VALUES (%s, %s, %s, %s, %s)
"""
# 参数列表
params = (
item['title'],
item['url'],
item['tags'],
item['create_date'],
item['content']
)
try:
cursor.execute(insert_sql, params)
db.commit() # 提交事务
print("数据插入成功")
except Exception as e:
print(f"插入数据时发生错误: {e}")
db.rollback() # 发生错误时回滚
finally:
# 关闭游标和连接
cursor.close()
db.close()
```
示例2:使用MySQLdb(或mysqlclient)
安装:`pip install mysqlclient`
代码与pymysql类似,但注意MySQLdb在连接时参数名略有不同,且不需要指定`port`为关键字参数(可以直接在host后面用冒号指定端口,或者使用port关键字参数)。
```python
import MySQLdb
# 1. 连接数据库
db = MySQLdb.connect(
host="数据库地址",
port=3306, # 注意:MySQLdb中port参数是有效的
user="用户名",
passwd="密码", # 注意参数名是passwd
db="数据库名",
charset='utf8mb4',
use_unicode=True
)
# 2. 创建游标
cursor = db.cursor()
# 3. 执行SQL语句(同上,创建表和插入数据)
# ... 省略,与pymysql示例中的SQL执行部分相同
# 注意:在MySQLdb中,插入数据时同样使用%s作为占位符,但参数传递方式相同。
# 最后记得提交、异常处理和关闭连接
```
注意事项:
- 在插入数据时,使用参数化查询(%s作为占位符)可以防止SQL注入攻击。
- 字符编码建议使用utf8mb4,以支持存储Emoji等特殊字符。
- 对于日期类型的字段,确保传入的日期字符串格式正确,或者使用Python的datetime.date对象。
在实际的爬虫项目中,我们通常会将数据库操作封装到一个单独的类或者pipeline中(例如在Scrapy框架中,可以编写一个Item Pipeline来处理数据的存储)。
引用[2]中展示了一个Scrapy的Pipeline示例,其中在`__init__`方法中建立数据库连接,在`process_item`方法中处理每个item的插入操作。
总结:使用Python将爬取的数据存入数据库,主要步骤包括连接数据库、创建游标、执行SQL语句、提交和关闭连接。根据使用的数据库驱动不同(pymysql或MySQLdb),代码略有差异,但整体流程一致。
§§相关问题§§
1. 如何防止在将爬取数据存入数据库时出现重复数据?
2. 如何处理数据库连接异常和超时问题?
3. 在Scrapy框架中如何编写Item Pipeline来存储数据到数据库?
4. 除了MySQL,Python还支持哪些数据库?如何操作?</think>### Python爬虫数据存入数据库的方法
将爬取的数据存入数据库是爬虫开发的关键步骤,以下是详细的操作流程和示例代码:
#### 一、基本步骤
1. **安装数据库驱动**
```bash
pip install pymysql # MySQL
pip install pymongo # MongoDB
```
2. **建立数据库连接**
```python
import pymysql
# 连接MySQL(参数根据实际修改)
db = pymysql.connect(
host="localhost", # 数据库地址
port=3306, # 端口
user="root", # 用户名
password="123456", # 密码
database="spider_db", # 数据库名
charset="utf8mb4" # 编码
)
cursor = db.cursor() # 创建游标
```
[^1][^2]
3. **创建数据表**
```sql
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
url VARCHAR(255) NOT NULL UNIQUE,
content TEXT,
create_date DATE
);
```
4. **插入数据**
```python
item = {
'title': 'Python教程',
'url': 'https://example.com/python',
'content': 'Python基础语法...',
'create_date': '2023-06-15'
}
sql = """
INSERT INTO articles (title, url, content, create_date)
VALUES (%s, %s, %s, %s)
"""
cursor.execute(sql, (
item['title'],
item['url'],
item['content'],
item['create_date']
))
db.commit() # 提交事务
```
5. **关闭连接**
```python
cursor.close()
db.close()
```
#### 二、完整示例(MySQL)
```python
import pymysql
def save_to_mysql(item):
try:
db = pymysql.connect(
host="localhost",
user="root",
password="123456",
database="spider_db",
charset="utf8mb4"
)
cursor = db.cursor()
sql = """INSERT INTO articles (title, url, content, create_date)
VALUES (%s, %s, %s, %s)"""
cursor.execute(sql, (
item['title'],
item['url'],
item['content'],
item['create_date']
))
db.commit()
print("数据插入成功")
except Exception as e:
print(f"数据库错误: {e}")
db.rollback()
finally:
cursor.close()
db.close()
# 示例数据
article = {
'title': '爬虫技巧',
'url': 'https://example.com/spider',
'content': '数据存储方法...',
'create_date': '2023-06-18'
}
save_to_mysql(article)
```
#### 三、关键注意事项
1. **防重复机制**
- 添加`UNIQUE`约束(如url字段)
- 使用`ON DUPLICATE KEY UPDATE`语句
```sql
INSERT INTO ... ON DUPLICATE KEY UPDATE title=VALUES(title)
```
2. **批量插入优化**
```python
# 使用executemany提高效率
sql = "INSERT ... VALUES (%s,%s,%s,%s)"
cursor.executemany(sql, [item1, item2, item3])
```
3. **错误处理**
- 捕获`pymysql.Error`异常
- 网络超时设置:`connect(timeout=10)`
- 使用连接池管理连接[^3]
4. **编码问题**
- 统一使用`utf8mb4`编码
- 数据库、数据表、连接三处编码需一致
#### 四、其他数据库
1. **MongoDB示例**
```python
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client['spider_db']
collection = db['articles']
collection.insert_one({
'title': 'MongoDB存储',
'url': 'https://example.com/mongodb',
'content': 'NoSQL数据库...'
})
```
2. **SQLite示例**
```python
import sqlite3
conn = sqlite3.connect('spider.db')
cursor = conn.cursor()
cursor.execute("CREATE TABLE ...")
```
#### 五、Scrapy集成(pipelines.py)
```python
import pymysql
class MysqlPipeline:
def __init__(self):
self.conn = pymysql.connect(
host='localhost',
user='root',
password='123456',
db='spider_db',
charset='utf8mb4'
)
self.cursor = self.conn.cursor()
def process_item(self, item, spider):
sql = """INSERT INTO articles (title, url, content)
VALUES (%s, %s, %s)"""
self.cursor.execute(sql, (
item['title'],
item['url'],
item['content']
))
self.conn.commit()
return item
def close_spider(self, spider):
self.cursor.close()
self.conn.close()
```
[^2]
---