Curl抓取含特殊字符内容后,截取与条件判断异常求助
问题:Curl抓取含特殊字符内容后,截取/匹配异常
用户使用以下Curl脚本抓取网页内容:
$ch = curl_init(); curl_setopt($ch, CURLOPT_PROXY, 'XXXXXXXXXXXXX'); curl_setopt($ch, CURLOPT_PROXYUSERPWD,$loginpassw); curl_setopt($ch, CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_ENCODING ,"UTF-8"); curl_setopt($ch,array( CURLOPT_USERAGENT=>'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36', CURLOPT_ENCODING=>'gzip, deflate', CURLOPT_HTTPHEADER=>array( 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language: es-ES,en;q=0.5', 'Connection: keep-alive', 'Upgrade-Insecure-Requests: 1', ), )); $output=curl_exec($ch); curl_close($ch);
待抓取页面为UTF-8编码,包含西班牙语特殊字符(如número中的ú),直接显示抓取内容时正常,但使用substr/mb_substr截取,或进行条件判断时出现异常:
- 截取
número时返回&Uacute - 条件判断无法匹配目标字符串,例如:
if(substr($content,0,6)=="número") { print "yes"; }
始终无法输出yes。用户已尝试调整Curl编码设置,问题仍未解决。
问题原因与解决方案
核心原因
页面中的特殊字符是以HTML实体编码形式存在的(ú被编码为Ú),直接显示时浏览器会自动解码为正常字符,但PHP处理时会将实体编码当作普通字符串解析,导致截取、匹配逻辑出错。另外Curl代码中重复设置了CURLOPT_ENCODING,但这不是引发问题的核心因素。
解决方案
1. 解码HTML实体
使用PHP内置的html_entity_decode()函数,将抓取到的内容中的HTML实体转换为UTF-8原生字符:
$output = curl_exec($ch); curl_close($ch); // 解码HTML实体,指定UTF-8编码确保特殊字符正确转换 $output = html_entity_decode($output, ENT_QUOTES, 'UTF-8');
解码后再进行截取或条件判断,即可正常识别ú这类特殊字符。
2. 修复Curl重复配置(可选)
代码中重复设置了CURLOPT_ENCODING(先设为UTF-8,后又设为gzip, deflate),建议合并为统一配置,避免潜在冲突:
$ch = curl_init(); curl_setopt($ch, CURLOPT_PROXY, 'XXXXXXXXXXXXX'); curl_setopt($ch, CURLOPT_PROXYUSERPWD, $loginpassw); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, array( CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36', CURLOPT_ENCODING => 'gzip, deflate', CURLOPT_HTTPHEADER => array( 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language: es-ES,en;q=0.5', 'Connection: keep-alive', 'Upgrade-Insecure-Requests: 1', ), ));
3. 正确使用多字节字符串函数
处理UTF-8字符时,优先使用mb_substr()而非substr(),确保按字符数而非字节数截取:
$content = html_entity_decode($output, ENT_QUOTES, 'UTF-8'); // 指定UTF-8编码截取 $subContent = mb_substr($content, 0, 6, 'UTF-8'); // 条件判断示例 if (mb_substr($content, 0, 6, 'UTF-8') === "número") { print "yes"; }
内容的提问来源于stack exchange,提问作者Jean
相关产品推荐
相关产品推荐

