You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP cURL抓取不同日文站点出现UTF-8编码异常的通用方案问询

PHP cURL采集多站点编码兼容通用解决方案

问题根因

两个日本站点分别使用了不同的编码规则,站点1为标准UTF-8编码,站点2为日文场景常用的Shift_JIS/EUC-JP编码。原有方案的缺陷如下:

  • mb_detect_encoding默认未开启严格检测,且检测列表未覆盖日文常用编码,容易将非UTF-8编码误判为UTF-8
  • utf8_decode仅支持UTF-8转ISO-8859-1编码,仅适用于西欧字符场景,完全不匹配日文编码转换需求

通用处理方案

按照「HTTP响应头声明编码 > HTML页面meta标签声明编码 > 严格模式自动检测」的优先级获取原始编码,再统一转换为目标编码(推荐统一转UTF-8),具体实现代码如下:

$ua= "Mozilla/5.0 (X11; Linux i686; rv:36.0) Gecko/20100101 Firefox/36.0 SeaMonkey/2.33.1";     
$options = array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FAILONERROR => true, 
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_ENCODING => "",
    CURLOPT_USERAGENT => $ua,
    CURLOPT_AUTOREFERER => true,
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_MAXREDIRS => 5,
    CURLOPT_FORBID_REUSE => true
);
        
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);

// 编码转换逻辑开始
$originCharset = null;
// 优先级1:从HTTP响应头Content-Type字段提取编码
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if (preg_match('/charset=([a-zA-Z0-9_-]+)/i', $contentType, $matches)) {
    $originCharset = strtoupper(trim($matches[1]));
}

// 优先级2:从HTML meta标签提取编码
if (!$originCharset) {
    // 匹配HTML5标准meta charset声明
    if (preg_match('/<meta\s+charset=["\']?([a-zA-Z0-9_-]+)["\']?/i', $content, $matches)) {
        $originCharset = strtoupper(trim($matches[1]));
    }
    // 匹配旧版Content-Type meta声明
    elseif (preg_match('/<meta\s+http-equiv=["\']Content-Type["\']\s+content=["\'].*?charset=([a-zA-Z0-9_-]+)["\']?/i', $content, $matches)) {
        $originCharset = strtoupper(trim($matches[1]));
    }
}

// 优先级3:严格模式自动检测编码,可根据采集站点区域调整检测列表
if (!$originCharset) {
    // 日文站点检测列表,中文站可替换为['UTF-8', 'GBK', 'GB2312', 'BIG5']
    $detectList = ['UTF-8', 'SHIFT-JIS', 'EUC-JP', 'ISO-8859-1'];
    $originCharset = mb_detect_encoding($content, $detectList, true);
}

// 统一转换为UTF-8编码
if ($originCharset && $originCharset !== 'UTF-8') {
    $content = mb_convert_encoding($content, 'UTF-8', $originCharset);
}
curl_close($ch);

// 转码完成后再做HTML解析
$html = str_get_html($content);

注意事项

  • 可根据采集站点的所属区域调整自动检测的编码列表,进一步提升检测准确率
  • 必须在HTML解析前完成全量内容转码,不要对解析后的DOM节点文本单独转码,避免解析阶段就出现字符丢失

内容的提问来源于stack exchange,提问作者ErickBest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 13:45:02