我正试图下载一个站点供离线查看,这需要我做一些DOM操作(相信我,wget只是不做我需要做的事情.)。
--我发现,包含带有不寻常文本内容的标签的网页正在将saveHTML抛出。
对于某些url,如果我使用curl读取页面并输出为
echo $contents;那一切都很好。
例如,页面中有一个部分包含以下源:
<div id="area2516" class="component interaction_component float-none clear-none ">
<div id="area2516">
<script type="text/javascript">
window.bm = window.bm || {};
bm.data = bm.data || [];
bm.data['area2516'] = {};
</script>
<link rel="stylesheet" type="text/css" href="/somecss.css">
<script type="text/javascript" src="somejs.js">
</script>
<script class="main-template" type="text/x-handlebars-template">
<div class="content_area">
<div class="bg_image cf"></div>
{{#each rollovers}}
<div class="rollover_content" style="left: {{x}}; top: {{y}}; display: none;" data-rollover-id="{{id}}">
{{{this.content}}}
</div>
{{/each}}
</div>
<div class="rollover_links">
<ul>
{{#each rollovers}}
<li>
<a class="rollover_link" href="#" data-rollover-id="{{id}}">
{{{link}}}
</a>
</li>
{{/each}}
</ul>
</div>
</script>
<script type="text/javascript">
bm.data['area2516'].assets = {};
bm.data['area2516'].initial_json = '';
</script>从上面的回音中可以看到卷曲响应。
现在,如果我这么做
$doc = new DOMDocument();
@$doc->loadHTML($contents);
$xpath = new DOMXpath($doc);
echo $doc->saveHTML();HTML会使混乱,因此上面的内容现在变成如下:
<div id="area2516" class="component interaction_component float-none clear-none ">
<div id="area2516">
<script type="text/javascript">
window.bm = window.bm || {};
bm.data = bm.data || [];
bm.data['area2516'] = {};
</script>
<link rel="stylesheet" type="text/css" href="/somecss.css"> .
<script type="text/javascript" src="/somejs.js"></script>
<script class="main-template" type="text/x-handlebars-template">
<div class="content_area">
<div class="bg_image cf">
</script>
</div>
{{#each rollovers}}
<div class="rollover_content" style="left: {{x}}; top: {{y}}; display: none;" data-rollover-id="{{id}}">
{{{this.content}}}
</div>
{{/each}}
</div>
<div class="rollover_links">
<ul>
{{#each rollovers}}
<li>
<a class="rollover_link" href="#" data-rollover-id="{{id}}">
{{{link}}}
</a>
</li>
{{/each}}
</ul></div>
<script type="text/javascript">
bm.data['area2516'].assets = {};
bm.data['area2516'].initial_json = '';
</script>不好意思,这个新编辑器太烦人了。关键是,您可以看到一些相当大的差异,我不确定saveHTML是如何导致对源的这种修改的。我怀疑这与编码和模板系统使用的这些双大括号和三重大括号的特性有关,但尽管尝试使用各种编码参数,我也得到了相同的结果。然后我想可能与特殊的字符有关,转义,但我只是不确定需要什么函数来阻止saveHTML破坏输出。
想法?
谢谢
发布于 2018-12-21 03:39:19
根据HTML4规范,不能将任意文本放入<script>元素中。(尽管这个在HTML 5中是可能的,libxml解析器并不是那么新的。)
如果正确地转义元素的内容,则代码应按预期工作。
$content = <<< HTML
<div id="area2516" class="component interaction_component float-none clear-none ">
<div id="area2516">
<script type="text/javascript">
window.bm = window.bm || {};
bm.data = bm.data || [];
bm.data['area2516'] = {};
</script>
<link rel="stylesheet" type="text/css" href="/somecss.css">
<script type="text/javascript" src="somejs.js">
</script>
<script class="main-template" type="text/x-handlebars-template">
<div class="content_area">
<div class="bg_image cf"></div>
{{#each rollovers}}
<div class="rollover_content" style="left: {{x}}; top: {{y}}; display: none;" data-rollover-id="{{id}}">
{{{this.content}}}
</div>
{{/each}}
</div>
<div class="rollover_links">
<ul>
{{#each rollovers}}
<li>
<a class="rollover_link" href="#" data-rollover-id="{{id}}">
{{{link}}}
</a>
</li>
{{/each}}
</ul>
</div>
</script>
<script type="text/javascript">
bm.data['area2516'].assets = {};
bm.data['area2516'].initial_json = '';
</script>
HTML;
$doc = new DOMDocument();
$doc->loadHTML($content, LIBXML_HTML_NODEFDTD|LIBXML_HTML_NOIMPLIED);
echo $doc->saveHTML();产出与预期相符:
<div id="area2516" class="component interaction_component float-none clear-none ">
<div id="area2516">
<script type="text/javascript">
window.bm = window.bm || {};
bm.data = bm.data || [];
bm.data['area2516'] = {};
</script>
<link rel="stylesheet" type="text/css" href="/somecss.css">
<script type="text/javascript" src="somejs.js">
</script>
<script class="main-template" type="text/x-handlebars-template">
<div class="content_area">
<div class="bg_image cf"></div>
{{#each rollovers}}
<div class="rollover_content" style="left: {{x}}; top: {{y}}; display: none;" data-rollover-id="{{id}}">
{{{this.content}}}
</div>
{{/each}}
</div>
<div class="rollover_links">
<ul>
{{#each rollovers}}
<li>
<a class="rollover_link" href="#" data-rollover-id="{{id}}">
{{{link}}}
</a>
</li>
{{/each}}
</ul>
</div>
</script>
<script type="text/javascript">
bm.data['area2516'].assets = {};
bm.data['area2516'].initial_json = '';
</script></div></div>注意,您的HTML在其他方面是无效的;重复的id属性和缺少的结束元素。
发布于 2018-12-21 04:17:14
输入甚至不像HTML,而是类似于细枝 (或类似的)模板.
为了获得HTML输出,首先需要通过模板引擎进行推送;
除非通过(array) $rollovers ...this,否则肯定不会产生所需的结果。
如果这些不是你自己的模板文件,你可能下载错了URL .
而另一边的人忘了阻止访问模板。
https://stackoverflow.com/questions/53877365
复制相似问题