Как использовать PHP DomDocument, когда элементы скрипта содержат HTML? - PullRequest
0 голосов
/ 21 декабря 2018

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

Идеи?

Спасибо

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

входные данные даже не похожи HTML, но похожи на шаблон Twig (или аналогичный) ...

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

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

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

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

0 голосов
/ 21 декабря 2018

Согласно спецификации 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 и отсутствующие закрывающие элементы.

...