Scrapy 通过 SSH 隧道连接远程 MySQL 的配置方法
在使用 Scrapy 抓取数据时,若未在本地安装 MySQL 而是希望直接调用云服务器的数据库,可通过 pymysql 结合 sshtunnel 建立加密通道,将远程服务映射至本地回环地址读写。本文详解依赖安装、Pipeline 正确初始化流程、核心代码实现及服务端端口与防火墙排查步骤。
环境准备与依赖安装
通过 SSH 隧道可以将远程 MySQL 服务的安全暴露转化为本地访问。相比在个人电脑配置数据库环境,直接对接服务器实例能省去大量安装成本,且配合 phpMyAdmin 便于后期维护。实现该方案需确保运行环境为 Python 3.5+,并提前安装必要的第三方库。
安装依赖库
打开终端执行以下命令获取驱动:
pip install pymysql sshtunnel
注意:pymysql 适用于 Python 3.5 及以上版本。若项目仍停留在 Python 3.4 或更早版本,需改用 MySQLdb,但需注意两者 API 存在差异,避免混用导致运行报错。
Pipeline 核心代码实现
许多初学者尝试直接将纯 Python 脚本迁移至 Scrapy 的 pipelines.py,却因作用域和生命周期管理不当引发 AttributeError 或连接复用冲突。正确的做法是利用 Scrapy 管道标准接口 open_spider 与 close_spider 来管理连接的生命周期,确保隧道与数据库句柄安全释放。
第1步:初始化 SSH 隧道与服务连接
目的:建立加密通道并将远程 3306 端口映射至本地回环地址。
入口:pipelines.py 类的 open_spider 生命周期方法。
动作:实例化 SSHTunnelForwarder 启动转发,随后调用 pymysql.connect 建立会话。
重要参数:remote_bind_address 填数据库内网IP与3306端口,local_bind_address 固定为 ('127.0.0.1', 3306),MySQL 链接需校验 host 与 database。
完成状态:控制台打印“✅ SSH 隧道连接成功”与“✅ MySQL 本地映射连接成功”,且无 Timeout 或 Access denied 报错。
import pymysql
import sshtunnel
class SpiderPipeline(object):
def open_spider(self, spider):
# 创建并启动 SSH 转发器
self.ssh_server = sshtunnel.SSHTunnelForwarder(
('远程服务器公网IP', 22),
ssh_username='SSH登录账号',
ssh_password='SSH登录密码',
remote_bind_address=('数据库所在内网IP', 3306),
local_bind_address=('127.0.0.1', 3306)
)
self.ssh_server.start()
print('✅ SSH 隧道连接成功')
# 通过本地映射地址连接数据库
self.db_conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='MySQL账号',
password='MySQL密码',
database='目标库名',
charset='utf8mb4'
)
self.cursor = self.db_conn.cursor()
print('✅ MySQL 本地映射连接成功')
第2步:编写数据插入逻辑
目的:将爬虫抓取的 Item 批量写入表结构。
入口:process_item(self, item, spider) 方法。
动作:构建参数化 INSERT 语句,执行查询并手动提交事务。
重要参数:SQL 模板中使用 %s 占位符防注入,元组参数顺序需严格匹配字段。
完成状态:数据库表新增对应记录,控制台返回更新行数或无异常堆栈。
def process_item(self, item, spider):
sql = """INSERT INTO chapters(charter_name, novel_name) VALUES (%s, %s)"""
try:
self.cursor.execute(sql, (item.get('charter_name'), item.get('book_name')))
self.db_conn.commit()
except Exception as e:
print(f'❌ 数据插入失败: {e}')
self.db_conn.rollback()
return item
第3步:安全释放连接资源
目的:爬虫结束前关闭游标、数据库会话及 SSH 监听端口,防止资源泄露或服务端断开。
入口:close_spider(self, spider) 方法。
动作:按反向顺序依次调用 close() 与 stop()。
重要参数:无需传递额外参数,确保句柄变量已正确绑定到实例属性。
完成状态:控制台打印“✅ 所有连接已安全关闭”,进程正常退出且服务器日志无残留连接警告。
def close_spider(self, spider):
self.cursor.close()
self.db_conn.close()
self.ssh_server.stop()
print('✅ 所有连接已安全关闭')
连接失败的常见排查(端口、防火墙与权限)
若代码逻辑无误但仍提示连接超时或拒绝访问,通常是因为远程数据库未开放外部访问权限或系统防火墙拦截了流量。请按以下顺序核对服务器端配置:
查看与放行 MySQL 监听端口
确认当前服务是否监听 3306:
netstat -an | grep 3306
编辑配置文件开放外部接入。主流路径为 /etc/my.cnf 或 /etc/mysql/my.cnf,找到 bind-address = 127.0.0.1 并在行首添加 # 注释掉,随后重启服务:
service mysqld restart
检查云服务器安全组
除系统防火墙外,务必检查云平台控制台的安全组规则,确保入方向已放行 TCP 协议的 3306 端口,来源可设为 0.0.0.0/0 或限制为本机公网 IP。
系统防火墙放行指令
若服务器使用 firewalld,执行以下命令永久开放端口并刷新配置:
systemctl status firewalld
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
注意事项与优化建议
上述示例采用同步写入模式,在爬取高频或大批量数据时可能成为性能瓶颈。生产环境中建议结合队列异步处理或启用批量 executemany 提升吞吐。此外,代码中的账号与密码切勿硬编码提交至版本控制系统,推荐使用环境变量或配置文件加密读取。涉及删除、覆盖、清除、刷机等风险时,建议先备份 my.cnf 及数据库快照再修改配置。
小结
利用 sshtunnel 搭建安全通道是规避本地环境配置繁琐的最佳实践之一。只要掌握正确的 Scrapy 生命周期管理接口,理清 SSH 转发与本地映射的逻辑关系,便能稳定将采集数据落地至远程 MySQL。以上就是 Scrapy 框架中通过 SSH 连接远程 MySQL 的详细配置方法,更多关于 Python 爬虫数据存储与服务器联调的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













