船说 CMS 采集内容乱码如何处理
学完这篇,你能自己判断船说 CMS 采集回来的内容是哪种乱码,并把它改回正常显示,不用再一条条手工重录。
采集乱码几乎都是编码不一致造成的,但同样是乱码,原因完全不同,先分类再动手,能少走很多弯路。
第一步:看乱码长什么样,确定病因
这一步要做的,是把乱码截图或复制一段出来,对照下面四种典型形态,确定属于哪一种。判断准了,后面才有针对性地改。
- 变成一堆
???或???:数据在转成目标库字符集时被丢弃了。通常是数据库或表不是 utf8mb4,或者 PHP 连接数据库时没指定 utf8mb4。 - 变成
锟斤拷:UTF-8 的内容被当成 GBK 处理(或反过来),这是最经典的一种。 - 变成
ä½ å¥½这种带重音符号的字母:UTF-8 内容被当成 latin1 存取,属于“双重编码”。 - 变成方块、问号混杂,或者夹杂大量不可见字符:多半是源站开了 gzip 压缩,采集到的原始字节流没解压。
注意:不要一看到乱码就去改数据库字符集。
锟斤拷和ä½ å¥½这两类,问题出在采集规则或字段处理上,改数据库反而会把原本正常的数据也搞乱。
第二步:核对目标站的编码和数据库字符集
这一步要确认的是“往哪儿存”,存的地方本身必须是 UTF-8,后面的转换才有意义。
登录宝塔面板(或你用的主机面板),进入「数据库」,点对应库右侧的「管理」打开 phpMyAdmin,选中你的库,点顶部「操作」标签,看「排序规则」一栏,应该是 utf8mb4_general_ci 或 utf8mb4_unicode_ci。再点「结构」看每张表的排序规则是否一致,不一致的单表改。
然后打开船说 CMS 的数据库配置文件,一般在 /config/database.php 或 /application/database.php(ThinkPHP 系版本),确认 charset 一项是 utf8mb4。后台首页顶部会显示你的具体版本号,本文的操作路径以常见的 3.x / 4.x 后台为例,其他版本菜单位置可能略有差异。
第三步:在采集规则里指定源站编码
这一步是解决绝大多数乱码的关键,做完后新采集的内容就不会再乱。
进入后台 →「采集管理」→「采集节点列表」,找到出问题的那个节点,点右侧「编辑规则」。在「基本设置」区块里找「页面编码」或「字符集」下拉框,选项一般是:自动识别、UTF-8、GBK、BIG5。
如果目标源站是老站(GBK),这里必须手动选 GBK,别用「自动识别」——自动识别靠读取页面 <meta charset> 标签,而很多老站标签写的是 UTF-8,实际输出却是 GBK,自动识别就废了。判断方法:用浏览器打开源站某篇文章,右键「查看网页源代码」,看 <meta charset=> 写的是什么,再对比页面实际显示是否正常。
如果后台界面上根本没有这个选项,就需要改采集规则文件。规则文件通常在 /collect/ 或 /app/collect/ 目录下,找到对应节点的 PHP 文件,在获取到 $html 之后、解析之前加一行:
$html = mb_convert_encoding($html, 'UTF-8', 'GBK');
把 GBK 换成源站实际编码。
注意:这行转换只能加一次。如果内容本来就是 UTF-8,再加一次转换就会生产出满屏
锟斤拷。改完先采 3~5 条测试,别一次性跑几千条。
第四步:处理 gzip 压缩和多字节截断
如果乱码形态是方块或不可见字符,检查采集代码里的 curl 请求。加上这句让 curl 自动解压:
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
另外,规则里如果有对标题、简介做长度截断的代码,把 substr($title, 0, 80) 改成 mb_substr($title, 0, 80, 'UTF-8')。用 substr 会把一个汉字切成半个,前台显示出来就是乱码方块。
第五步:修复已经入库的乱码数据
前面几步只管新采集的内容,已经存进库的乱码要单独处理。以「UTF-8 被当 latin1 存」这种最常见的情况为例,在 phpMyAdmin 里执行:
UPDATE 你的表名 SET 标题字段 = CONVERT(BINARY CONVERT(标题字段 USING latin1) USING utf8mb4);
如果是「GBK 被当 UTF-8 存」,把上面语句里的 latin1 和 utf8mb4 位置对调即可。
注意:执行前一定先在 phpMyAdmin 里点「导出」把整张表备份一份。SQL 更新不可撤销,改错了只能靠备份回滚。
第六步:清缓存后验证
后台「系统」→「缓存管理」清一次缓存,然后重新采集 3~5 条,进「内容管理」打开其中一条,再看前台文章页。列表页和详情页都要看,因为有些模板会对标题做二次截断,问题可能只出现在其中一个。
小结
- 先按乱码形态分四类:
???、锟斤拷、ä½ å¥½、方块乱码,病因各不相同。 - 目标站数据库和表统一用
utf8mb4,配置文件charset也要一致。 - 采集规则里的「页面编码」手动指定源站真实编码,不要依赖自动识别。
- curl 采集记得加
CURLOPT_ENCODING处理 gzip,截断一律用mb_substr。 - 已入库的乱码用 SQL 转换修复,动手前先导出备份。
- 每次改完只测采几条,确认正常再批量跑。
原文链接:https://www.gj0.com/thread-584.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。