C# 爬虫实战复盘:如何安全高效写入 MySQL 数据库及防注入技巧

大家好,我是零点博客。在做 EMLOG 插件开发以及一些在线工具后端时,我们经常需要处理爬虫抓取的数据。最近在重构一套自动采集脚本时,我发现很多新手开发者(包括以前的自己)在对接 MySQL数据库 时,总是习惯用字符串拼接 SQL,这简直是在“裸奔”。

今天这篇文章,咱们就抛开那些虚头巴脑的理论,直接用源码案例来复盘一下,如何用 C# 安全、高效地将数据写入 MySQL数据库。

痛点:为什么严禁使用字符串拼接 SQL?

在早期的开发中,我常写这样的代码:

string sql = "INSERT INTO articles (title, content) VALUES ('" + title + "', '" + content + "')";

看着很省事?大错特错!如果爬虫抓取的数据里包含恶意字符(比如单引号 `'`),整个 SQL 语句就会报错甚至导致SQL注入攻击。所以,引入预处理语句是必须的。

核心:C# 连接 MySQL 数据库的正确姿势

咱们结合 JSON 解析和数据库操作,写一个完整的入库逻辑。

1. 引用 NuGet 包

首先,确保你的项目安装了 MySql.Data 包。没有的话,去 NuGet 控制台输入 Install-Package MySql.Data 即可。

2. 封装数据库操作类

下面是一段可直接落地的代码示例。注意看 using (MySqlConnection conn = new MySqlConnection(connStr)) 这一段,它自动处理了资源释放,非常方便。

using System;
using System.Data;
using MySql.Data.MySqlClient;
using Newtonsoft.Json; // 引用 Newtonsoft.Json 处理 JSON

public class DatabaseHelper
{
    private static string connStr = "Server=localhost;Database=mydb;Uid=root;Pwd=password;CharSet=utf8mb4;";

    public void SaveSpiderData(DataTable spiderTable)
    {
        using (MySqlConnection conn = new MySqlConnection(connStr))
        {
            conn.Open();
            // 开始事务,防止多条插入失败导致数据不一致
            using (MySqlTransaction trans = conn.BeginTransaction())
            {
                try
                {
                    string sql = "INSERT INTO logs (title, json_data, create_time) VALUES (@title, @json, @time)";
                    using (MySqlCommand cmd = new MySqlCommand(sql, conn, trans))
                    {
                        // 关键点:使用 Parameters.AddWithValue 防注入
                        cmd.Parameters.AddWithValue("@title", spiderTable.Rows[0]["title"]);
                        cmd.Parameters.AddWithValue("@json", spiderTable.Rows[0].ToJson()); // 假设 DataTable 有 ToJson 方法
                        cmd.Parameters.AddWithValue("@time", DateTime.Now);

                        cmd.ExecuteNonQuery();
                    }
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    Console.WriteLine($"数据库操作失败: {ex.Message}");
                }
            }
        }
    }
}

底层拆解与避坑指南

在实战中,除了写对 SQL,还有两个坑必须得填:

  • 连接池配置: C# 自带连接池,默认是开启的。如果你频繁创建销毁连接,会严重影响性能。尽量复用连接字符串配置。
  • 字段类型匹配: 在操作 MySQL数据库 时,要注意 DateTime、Decimal 的类型转换。有时候 JSON 转过来的数据是字符串,插入时可能会报类型不匹配错误。建议在插入前用 C# 的 DateTime.Parse 或 Convert 方法做一层预处理。

很多时候,爬虫抓回来的数据是杂乱的,我们需要用到正则表达式清洗一下 HTML 标签,剩下的才能存入数据库。这也是我经常在零点博客分享的内容。

总结

安全开发永远第一位。无论是做 PHP 后端还是 C# 后端,对待 MySQL数据库 一定要敬畏之心。掌握预处理语句,不仅能保命,还能让你的代码在必应和百度的 SEO 搜索结果中跑得更快(因为代码更健壮,Bug 更少)。

如果你有更好的 MySQL 优化技巧,欢迎在评论区交流,咱们下期见!