让我们看看 symfony/dom-crawler 是如何工作的。这是一个开始的例子:
<?php
require 'vendor/autoload.php';
use Symfony\Component\DomCrawler\Crawler;
$html = <<<HTML
<div>测试</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
HTML;
$crawler = new Crawler($html);
print $crawler->html();
它输出:
<div>æµè¯</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
当您通过构造函数传递内容时,Crawler
该类会尽力找出编码。如果它无法解决任何问题,它会退回到ISO-8859-1
; 这是 HTTP 1.1 规范定义的默认字符集。
如果您的 HTML 内容包含字符集元标记,则 Crawler 类将从其中读取字符集,对其进行设置并正确转换。这是上面相同的示例,在 HTML 内容前附加了一个字符集元标记:
<?php
require 'vendor/autoload.php';
use Symfony\Component\DomCrawler\Crawler;
$html = <<<HTML
<meta charset="utf-8">
<div>测试</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
HTML;
$crawler = new Crawler($html);
print $crawler->html();
现在它打印:
<div>测试</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
如果您不想添加字符集元标记,还有另一种方法;addHTMLContent()
方法接受一个字符集作为其第二个参数,默认为UTF-8
. 与其通过构造函数传递 HTML 内容,不如先实例化该类,然后使用此方法添加内容:
<?php
require 'vendor/autoload.php';
use Symfony\Component\DomCrawler\Crawler;
$html = <<<HTML
<div>测试</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
HTML;
$crawler = new Crawler;
// You can safely drop the 2nd argument
$crawler->addHTMLContent($html, 'UTF-8');
print $crawler->html();
现在,没有字符集元标记,它会打印:
<div>测试</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
好的,你可能已经知道了这一切。那么,怎么了测试
?为什么div
内容按原样显示,但script
标签中的相同内容被 html 编码?
Symfony 的Crawler
类,正如它自己解释的那样,由于以下错误而将内容转换为 HTML 实体DOMDocument::loadHTML()
:
在loadHTML()
处理 UTF-8 页面时,可能会遇到 DOM 函数的输出与输入不一样的问题。例如,如果您想获得“Cạnh tranh”,您将收到“Cạnh tranh”。我建议我们mb_convert_encoding
在加载 UTF-8 页面之前使用。
– https://php.net/manual/en/domdocument.loadhtml.php#74777
有人建议Content-Type
在 head 元素中添加 HTML4 元标记。其他一些建议在<?xml encoding="UTF-8">
将 HTML 内容传递给loadHTML()
. 由于您的 HTML 结构不完整(缺少head
、body
等),我建议您只需将输出传递给html_entity_decode()
:
<?php
require 'vendor/autoload.php';
use Symfony\Component\DomCrawler\Crawler;
$html = <<<HTML
<div>测试</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
HTML;
$crawler = new Crawler();
$crawler->addHTMLContent($html, 'UTF-8');
print html_entity_decode($crawler->html());
输出:
<div>测试</div>
<script charset="utf-8" type="text/javascript">
function drawCharts(){
console.log('测试');
}
</script>
这就是你想要的。
您可能还想阅读:
PHP DOMDocument loadHTML not encoding UTF-8 correct