我希望能够抓取一个HTML页面并仅使用Javascript解析它,没有任何东西触及服务器。
假设我可以获得html响应(解决了跨域问题),如何在完整的html文档中使用jQuery?
示例如下( here is a full gist with a remote example ):
<!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");
没有给我任何东西。我不确定如何使用jQuery遍历这个完整的html文档。我试图删除<!DOCTYPE...>
标记,但这并没有太大作用。
这样的事情可能吗?
我一直在忙着John Resig's Javascript HTML Parser,但还没有完全覆盖它。
是否有更适合的XPath javascript库?
答案 0 :(得分:8)
问题不在于jQuery,而是浏览器.innerHTML
实现的差异。不同的浏览器以不同的方式处理这个问题,例如在Opera中你的例子可以正常工作,Firefox可以调整,在IE8中它可以调整一半,而Chrome可以解决所有问题。
关于他们如何处理.innerHTML
来电,这就是jQuery uses internally时的creating document fragments。
Here's a quick test page using the exact HTML you have,以及一些浏览器的结果:
Chrome 6 (运行alert()
,几乎删除所有内容):
<div id="child_div"></div>
<head>
并且内容已被删除,无法获取 IE8 (运行alert()
,保留<meta>
,但作为顶级元素,test it in IE here):
<META name=keywords content="parent, html, parsing">
<DIV id=child_div></DIV>
$(html).filter("meta").attr("name")
:“keywords”<title>
被剥夺了 Firefox 3.6 (运行alert()
,保留<head>
内容,但又作为顶级元素test it here):
<title>Sub Page to Parse</title>
<meta name="keywords" content="parent, html, parsing">
<div id="child_div"></div>
$(html).filter("meta").attr("name")
:“keywords”$(html).filter("title").html()
:“Sub Page to Parse” Opera 10.6 (运行alert()
,仅删除脚本,test it here):
<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")
:“keywords”$(html).find("title").html()
:“Sub Page to Parse”所以问题不是jQuery per-say,而是不同的浏览器在他们的.innerHTML
方法中正在做什么来去掉他们想要的东西。这使得解析<head>
中的任何内容都特别不可靠,注意它完全保留时,它可能是也可能不是顶级元素,例如$(html).length
会有所不同。
我想说你在这里有两个选择,但两者看起来都不太吸引人:
很抱歉答案很糟糕,但似乎是跨浏览器问题,除非你自己解析,否则会成为杀手锏,并使jQuery无用。
答案 1 :(得分:-1)
如何使用DocumentFragment?您仍然可能需要使用您获得的文本,但您至少已将解析卸载到浏览器,希望知道它正在做什么。它也不在页面的DOM中。
答案 2 :(得分:-2)
鉴于你有一些HTML标记作为JavaScript字符串,你可以将它交给jQuery并解析它。
var tagSoup = '<html><head>.and so on..</html>';
var tag$ = $(tagSoup);
var someValue = tag$.find('#someId).val();