Как использовать PHP DomDocument, когда элементы скрипта содержат HTML?

Я пытаюсь загрузить сайт для просмотра в автономном режиме, и это требует от меня выполнения ряда манипуляций с 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 испортить вывод.

Идеи?

Спасибо

0

Решение

вход даже не похож HTML, но так прут (или похожий) шаблон …

который нужно было бы сначала протолкнуть через шаблонизатор, чтобы получить HTML выход;

если не проходить (array) $rollovers … это не даст желаемых результатов, наверняка.

если это не ваши собственные файлы шаблонов, возможно, вы загружаете неправильный URL

а кто-то на другой стороне забыл запретить доступ к шаблонам.

0

Другие решения

Согласно спецификации 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">
&lt;div class="content_area"&gt;
&lt;div class="bg_image cf"&gt;&lt;/div&gt;
{{#each rollovers}}
&lt;div class="rollover_content" style="left: {{x}}; top: {{y}}; display: none;" data-rollover-id="{{id}}"&gt;
{{{this.content}}}
&lt;/div&gt;
{{/each}}
&lt;/div&gt;
&lt;div class="rollover_links"&gt;
&lt;ul&gt;
{{#each rollovers}}
&lt;li&gt;
&lt;a class="rollover_link" href="#" data-rollover-id="{{id}}"&gt;
{{{link}}}
&lt;/a&gt;
&lt;/li&gt;
{{/each}}
&lt;/ul&gt;
&lt;/div&gt;
</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">
&lt;div class="content_area"&gt;
&lt;div class="bg_image cf"&gt;&lt;/div&gt;
{{#each rollovers}}
&lt;div class="rollover_content" style="left: {{x}}; top: {{y}}; display: none;" data-rollover-id="{{id}}"&gt;
{{{this.content}}}
&lt;/div&gt;
{{/each}}
&lt;/div&gt;
&lt;div class="rollover_links"&gt;
&lt;ul&gt;
{{#each rollovers}}
&lt;li&gt;
&lt;a class="rollover_link" href="#" data-rollover-id="{{id}}"&gt;
{{{link}}}
&lt;/a&gt;
&lt;/li&gt;
{{/each}}
&lt;/ul&gt;
&lt;/div&gt;
</script>


<script type="text/javascript">
bm.data['area2516'].assets = {};
bm.data['area2516'].initial_json = '';
</script></div></div>

Обратите внимание, что ваш HTML недопустим в других отношениях; повторный id атрибуты и отсутствующие закрывающие элементы.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector