使用jQuery抓取HTML文档,是否可能?

Lan*_*ard 3 html jquery xpath parsing

我希望能够抓取一个HTML页面并仅使用Javascript解析它,没有任何东西触及服务器.

假设我可以获得html响应(解决了跨域问题),我如何在完整的html文档中使用jQuery?

示例是这样的(这里是一个带有远程示例的完整要点):

<!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>
Run Code Online (Sandbox Code Playgroud)

问题是,var child_body = $(data).find("body");不给我任何东西.我不确定如何使用jQuery遍历这个完整的html文档.我试图删除<!DOCTYPE...>标签,但这没有太大作用.

这样的事情可能吗?

我一直在搞乱John Resig的Javascript HTML Parser,但还没有完全覆盖它.

是否有更适合的XPath javascript库?

Nic*_*ver 8

问题不在于jQuery,而在于浏览器.innerHTML实现的差异.不同的浏览器以不同的方式处理这个问题,例如在Opera中你的例子可以正常工作,Firefox可以调整,在IE8中它可以调整一半,而Chrome可以解决所有问题.

它是关于它们如何处理.innerHTML调用的全部内容,这是jQuery创建文档片段内部使用的内容.

这是一个使用您拥有的确切HTML的快速测试页面,以及一些浏览器的结果:


Chrome 6(运行alert(),剥离几乎所有东西):

<div id="child_div"></div>
Run Code Online (Sandbox Code Playgroud)
  • 结果:
    • 整个<head>和内容被剥离,没有什么可得到的

IE8(运行它alert(),它保留<meta>,但作为顶级元素,在IE中测试它):

<META name=keywords content="parent, html, parsing">
<DIV id=child_div></DIV>
Run Code Online (Sandbox Code Playgroud)
  • 结果:
    • $(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> 
Run Code Online (Sandbox Code Playgroud)
  • 结果:
    • $(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>
Run Code Online (Sandbox Code Playgroud)
  • 结果:
    • $(html).find("meta").attr("name") :"关键字"
    • $(html).find("title").html() :"Sub Page to Parse"

所以问题不是jQuery per-say,而是不同的浏览器在他们的.innerHTML方法中做了什么去除他们想要的东西.这使得解析任何<head>特别不可靠的东西,当它完全保留时通知,它可能是也可能不是顶级元素,例如$(html).length会有所不同.

我会说你有两个选择,但这两个看起来都不太吸引人:

  • 通过服务器端调用发出请求,它会获得您想要的信息
  • 自己解析HTML,但是你不会从那个部门的jQuery中获得任何好处

对不起,答案很糟糕,但似乎跨浏览器问题,除非你自己解析,这将成为杀手,并使jQuery无用.