Очистить HTML-документ с помощью jQuery, это возможно? - PullRequest
3 голосов
/ 10 июля 2010

Я хочу иметь возможность захватывать HTML-страницу и анализировать ее, используя только Javascript, ничто не затрагивает сервер.

Если предположить, что я могу получить ответ html (решены междоменные проблемы), как я могу это сделать?использовать jQuery для полного html-документа?

Пример подобен этому ( Вот полный текст с удаленным примером ):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>Parent Page wanting to Parse Children</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <meta name="keywords" content="parent, html, parsing">
  </head>
  <body>
    <script type="text/javascript">
      $(document).ready(function() {
        //  data looks like this:
        var html = ""
        html += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
        html += '<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">'
        html += '  <head>                                                        '
        html += '    <title>Sub Page to Parse</title>                            '
        html += '    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"><\/script>'
        html += '    <meta name="keywords" content="parent, html, parsing">      '
        html += '  </head>                                                       '
        html += '  <body>                                                        '
        html += '    <script type="text/javascript">                             '
        html += '      alert("im javascript");                                   '
        html += '      setTimeout(function() {                                   '
        html += '        $("body").css("background-color", "#ffaaaa")            '
        html += '      }, 400);                                                  '
        html += '    <\/script>                                                  '
        html += '    <div id="child_div"></div>                                  '
        html += '  </body>                                                       '
        html += '</html>'

// this works fine:
//        $("#parent_div").append(html);
//        $("#child_div")
//          .width(100)
//          .height(100)
//          .css("background-color", "yellow")
//          .append("<p>child text</p>");
// ... but that's not what I am trying to do...

// reason being: i don't want to add this sub-html page to the dom...
// I just want to scrape it for data...

// I want to do this, but I am getting null for every case:
        var meta = $(html).find("meta");
        alert(meta.html());
        var title = $(html).find("title");
        alert(title.html());

      });
    </script>
    <div id="parent_div"></div>
  </body>
</html>

Проблема в том, что var child_body = $(data).find("body"); мне ничего не дает.Я не уверен, как я должен идти об обходе этого полного HTML-документа с использованием jQuery.Я пытался удалить тег <!DOCTYPE...>, но это мало что дает.

Возможно ли что-то подобное?

Я возился с Javascript HTML Джона РезигаParser , но это еще не совсем понятно.

Существует ли библиотека XPath javascript, которая была бы более подходящей?

Ответы [ 3 ]

8 голосов
/ 10 июля 2010

Проблема не совсем в jQuery, а в различиях в реализации браузера .innerHTML.Разные браузеры обрабатывают это по-разному, например, в Opera ваш пример работает нормально, Firefox может работать с настройками, в IE8 он работает наполовину с настройками, а Chrome лишает всех.

Это все о том, как они обрабатывают вызов .innerHTML, это то, что jQuery использует внутренне при создании фрагментов документа .

Вот быстрая тестовая страница, использующая точный HTML, который у вас есть , и результаты нескольких браузеров:


Chrome 6 (запускает alert(), удаляет почти все):

<div id="child_div"></div>
  • Результаты:
    • Весь <head> и содержимое очищено, нечего получить

IE8 (Запускает alert(), сохраняет <meta>, но в качестве элемента верхнего уровня протестируйте его в IE здесь ):

<META name=keywords content="parent, html, parsing">
<DIV id=child_div></DIV>
  • Результаты:
    • $(html).filter("meta").attr("name"): "ключевые слова"
    • <title> было удалено

Firefox 3.6 (Запускает alert(), сохраняет <head> содержимое, но снова в качестве элементов верхнего уровня, проверить его здесь ):

<title>Sub Page to Parse</title>
<meta name="keywords" content="parent, html, parsing">
<div id="child_div"></div> 
  • Результаты:
    • $(html).filter("meta").attr("name"): "ключевые слова"
    • $(html).filter("title").html(): "Sub Page to Parse"

Opera 10.6 (Запускает alert(), разбирает только сценарии, проверяет здесь ):

<head> 
  <title>Sub Page to Parse</title>
  <meta name="keywords" content="parent, html, parsing"> 
</head> 
<div id="child_div"></div>
  • Результаты:
    • $(html).find("meta").attr("name"): «ключевые слова»
    • $(html).find("title").html(): «Sub Page to Parse»

Так что проблема нене jQuery, но то, что различные браузеры делают в своих .innerHTML методах, чтобы убрать все, что они хотят.Это делает синтаксический анализ чего-либо в <head> особенно ненадежным, обратите внимание, что когда оно вообще сохраняется, оно может быть или не быть элементом верхнего уровня, например, $(html).length будет отличаться.

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

  • Сделайте запрос через вызов на стороне сервера, он получит необходимую вам информацию
  • Сам анализируем HTML, но вы не получите никакой пользы от jQuery в этом отделе, будут здесь убийцами и сделают jQuery практически бесполезным.
0 голосов
/ 10 июля 2010

Как насчет использования DocumentFragment ?Вам, вероятно, все равно придется возиться с полученным текстом, но вы, по крайней мере, загрузили анализ в браузер, который, надеюсь, знает, что он делает.Это также не в DOM страницы.

0 голосов
/ 10 июля 2010

Учитывая, что у вас есть некоторая HTML-разметка в виде строки JavaScript, вы можете передать ее в jQuery и проанализировать ее.

var tagSoup = '<html><head>.and so on..</html>';

var tag$ = $(tagSoup);

var someValue = tag$.find('#someId).val();
...