Я пытаюсь загрузить сайт для просмотра в автономном режиме, и это требует от меня выполнения ряда манипуляций с 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 испортить вывод.
Идеи?
Спасибо
вход даже не похож HTML
, но так прут (или похожий) шаблон …
который нужно было бы сначала протолкнуть через шаблонизатор, чтобы получить HTML
выход;
если не проходить (array) $rollovers
… это не даст желаемых результатов, наверняка.
если это не ваши собственные файлы шаблонов, возможно, вы загружаете неправильный URL
…
а кто-то на другой стороне забыл запретить доступ к шаблонам.
Согласно спецификации HTML 4, вы не можете поместить произвольный текст в <script>
элемент. (Хотя это возможно в HTML 5, libxml
Парсер, включенный в PHP, не так уж нов.)
Если вы правильно экранируете содержимое элемента, ваш код должен работать так, как ожидалось.
$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
атрибуты и отсутствующие закрывающие элементы.