php爬虫存mysql常见报错主因是字符集未对齐,需统一设为utf8mb4;必须用预处理防注入;批量插入+事务提升性能;注意连接释放与编码咬合。

PHP爬虫抓取后直接插入MySQL常见报错
最常遇到的是 mysqli_query() 返回 false,或提示 SQLSTATE[HY000]: General error: 1366 Incorrect string value。这基本不是爬虫逻辑问题,而是字符集没对齐——网页是 UTF-8(带 BOM 或不带),但数据库表的 CHARSET 是 latin1,或者连接时没声明编码。
- 建表必须显式指定
CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci(utf8mb4才支持 emoji 和生僻汉字) - PHP 连接 MySQL 时,必须在
mysqli初始化后立刻执行mysqli_set_charset($conn, 'utf8mb4');用 PDO 则要在 DSN 中加;charset=utf8mb4 - 抓取的 HTML 内容建议先过一遍
mb_convert_encoding($html, 'UTF-8', 'auto'),再用strip_tags()或 DOM 解析,避免乱码污染字段
用 cURL 抓完数据,怎么安全写入数据库不被注入
别拼 SQL 字符串。哪怕只存标题和链接两个字段,只要用了 "INSERT INTO post (title,url) VALUES ('$title','$url')",就等于把入口敞开给 SQL 注入。
- 一律用预处理语句:
mysqli_prepare()+mysqli_stmt_bind_param(),或 PDO 的prepare()+execute() - 注意参数类型匹配:URL 和标题用
s,ID 用i,时间戳用i或s(取决于字段类型),别全写s - 如果内容含换行、单引号、反斜杠,预处理自动转义,不用再调
addslashes()或mysqli_real_escape_string()—— 多做反而可能重复转义
DOMDocument 解析后批量入库性能卡在哪
单条 INSERT 循环插 100 条,比用 INSERT INTO t(a,b) VALUES (?,?),(?,?),... 批量插慢 5–10 倍,网络往返和事务开销是主因。
- 每页解析出的数据,攒够 50–200 条再批量
INSERT,用一个VALUES子句拼多组值(注意 MySQLmax_allowed_packet限制,默认 4MB) - 批量前手动开启事务:
mysqli_begin_transaction($conn),插完再commit;否则每条都隐式提交,IO 拉垮 -
DOMDocument加载大 HTML 易内存溢出,可先用mb_substr($html, 0, 2_000_000)截断非关键部分,或改用更轻量的simple_html_dom(需手动ini_set('memory_limit', '256M'))
爬虫跑着跑着连不上数据库了?检查这三处
不是服务器崩了,大概率是连接没释放、超时或并发冲突。
立即学习“PHP免费学习笔记(深入)”;
- 每次请求结束后,显式调用
mysqli_close($conn)或让 PHP 脚本自然结束——CLI 模式下长连接不关,wait_timeout到期后连接变“僵尸” - 若用
file_get_contents()+str_getcsv()类简易爬法,注意它不走 cURL,DNS 缓存和连接复用策略不同,容易触发 MySQL 的max_connections限制 - 多个爬虫进程同时写同一张表,没加
INSERT ... ON DUPLICATE KEY UPDATE或唯一索引去重,会导致主键冲突报错1062 Duplicate entry,后续插入直接中断











