采不到内容就看看JSON吧,很多JS都用这个来实现的。
利用JSON代替XML解决各版本浏览器对DOM支持不同的问题Ajax中数据传递,大家都已经习惯了“异步JavaScript和XML”,XML是看上去的重要 组成部分,它却不是必须的。另外像下面这样的JavaScript,IE6之前的版本(包括IE6)对其支持的都不是很好,基本上会报找不到对象的错误。假如有一种完全独立于语言的文本格式作为数据交换格式,那么这样的问题也就不存在了,JSON(JavaScript Object Notation)帮我们提供了完美的解决方案,同时也完全取代了Ajax中的XML。
var res = xmlHttpReq.responseXML.getElementsByTagName(”Key“);JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。以JavaScript为例,可以把想要执行的语句放在字符串里,通过eval()这个动态执行函数来执行。字符串里的内容会像我们写的脚本 一样被执行。只要数据符合下面的这样的格式:var myJSONObject = {”bindings“: [
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"},
{"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"},
{"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"}
]
};对于其中的第一行的method,我们可以这样操作:myJSONObject.bindings.method // 结果为”newURI”上面提到的eval可以帮我们把字符串转换成为JSON所需要的对象,var myObject = eval(’(’ + myJSONtext + ‘)’);JSON不仅减少了解析XML解析带来的性能问题和兼容性问题,而且对于JavaScript来说使用非常简单。更具体的例子可以参照JSON的主页上,相关的代码可以从那里取到最新版本。
SON的另外一个优势是跨域可行性,例如你在www.minidx.com的网页里使用<scripttype=”text/javascript”src=”http://www.sample.com/some.js”></script>是完全可行的,这就意味着我们可以跨域传递信息。而使用XMLHttpRequest却获取不了跨域的信息,这是JavaScript内部的安全性质所限制的。
网络爬虫如何抓取web2.0 Ajax页面
******伴随着AJAX/Web2.0的流行,如何抓取Ajax页面成了搜索引擎急需解决的一个问题,因为Ajax颠覆了传统的纯HTTP请求/响应协议机制,如果搜索引擎依旧采用“爬”的机制,是无法抓取到AJAX页面的有效数据的。
AJAX,也就是Asychronous Javascript andXML,由于采用了Javascript驱动的异步请求/响应机制,以往的爬虫们缺乏Javascript语义上的理解,基本上是无法模拟触发Javascript的异步调用并解析返回的异步回调逻辑和内容。
另外AJAX的应用中,Javascript会对DOM结构进行大量地变动,甚至页面所有的内容都是通过Javascript直接从服务器端读取并动态绘制出来.这个对于”习惯了”DOM结构相对不变的静态页面,简直是无法理解的.
由此可以看出,以往的爬虫是基于协议驱动的,而对于AJAX这样的技术,所需要的“爬虫”引擎必须是基于事件驱动的。要实现事件驱动,首先需要解决下面几点问题
●Javascript的交互分析和解释
●DOM事件的处理和解释分发
●动态DOM内容语义的抽取
至于具体如何去实现,个人觉得Crawling Ajax-driven Web 2.0 Applications这篇论文很有参考价值。有兴趣地可以研究研究。
[ 本帖最后由 faunus 于 2008-11-8 20:08 编辑 ] 大虫的帖子好好看看
爬虫如何抓取到Asp.Net中__doPostBack获取新页面的数据
在Web 2.0时代,很多网站采用AJAX技术实现,带来较好用户体验的代价是,Javascript得到的内容搜索引擎无法爬到,Google也正在研究此种技术。本文讨论Asp.Net程序生成的链接,爬虫如何能爬进去的问题。问题:某网站出现的数据列表分页显示,而上一页和下一页都是用__doPostBack提交到后台处理,如javascript:__doPostBack('ucInfoListMore$gridInfoList$_ctl21$_ctl1',''),我们根本得不到他绝对链接的地址,而且每一页得下一页传入的参数是一样的。
分析:我们首先理解__doPostBack做了哪些事情。
http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gifhttp://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.giffunction __doPostBack(eventTarget, eventArgument) http://www.cnblogs.com/Images/dot.gif{
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gifvar theform;
http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gifhttp://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gifif (window.navigator.appName.toLowerCase().indexOf("netscape") >
-1) http://www.cnblogs.com/Images/dot.gif{
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.giftheform = document.forms["Form1"];//注意此处的FormID
http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gifhttp://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif}
else
http://www.cnblogs.com/Images/dot.gif{
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.giftheform = document.Form1;//还有此处
http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif}
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.giftheform.__EVENTTARGET.value = eventTarget.split("$").join(":");
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.giftheform.__EVENTARGUMENT.value = eventArgument;
http://www.cnblogs.com/Images/OutliningIndicators/InBlock.giftheform.submit();
http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif}
明白了吧,问题就在.__EVENTTARGET(后台处理的事件)和__EVENTARGUMENT上。这样就简单了,我们可以给这两个参数赋值,然后向后台发送Post就可以了。那么如何指定某一页呢,Asp.Net在后台是以Session方式保存当前页信息的,我们在Post得时候能够保证实在同一个会话中进行的就可以了。
如果想挖掘Javascript管理的内容该怎么办
主流网络爬虫并不代表一切,因为Javascript管理的内容仍然蕴藏很多价值点,例如,有人专门抓取/提取和统计广告和相关的信息,这类信息一般存放在HTML框架(FRAME/IFRAME)中,而且大量使用Javascript代码。有些专业的网络爬虫拥有完整的Javascript引擎和HTML页面展现引擎,因此,从理论上讲,凡是用户能够看到和操作的内容,这类网络爬虫都能够看到和提取。MetaSeeker工具包就具有这个能力,当然MetaSeeker工具包的功能远不止这个,是一整套Web信息提取、筛选和存储工具,也是Web元数据整理工具。[ 本帖最后由 faunus 于 2008-11-8 21:29 编辑 ]
Cross Site AJAX
一般情形下,为安全起见,浏览器不允许你在客户端通过XMLHttpRequest访问别的域(参考连接1,2),即使是同一域的子域也不行,譬如www.joycode.com 到blog.joycode.com。(你可以通过某些设置来访问子域,但因为这方法不是很通行,所有就不考虑了,但如果你感兴趣,参考连接2。)但很明显,在不少情形下,访问别的网站,获取别的网站的信息/服务是非常有用的,特别是在这个Web 2.0时代。
常用的跨站访问的方法有3种(参考连接3,4):
[*]在同一域的服务器端建立一个代理,浏览器向该代理网址发送请求,然后该代理向其他域的网址发请求,在获取回复后,或作处理或按原样发回到浏览器[*]使用按需(On-Demand) Javascript 脚本。在页面内动态生成新的<script>,将其src属性指向别的网站的网址,这个网址返回的内容必须是合法的Javascript脚本,常用的是JSON消息。[*]使用IFRAME。在页面内嵌或动态生成指向别的网站的IFRAME,然后这2个网页间可以通过改变对方的anchor hashfragment来传输消息。改变一个网页的anchor hashfragment并不会使浏览器重新装载网页,所以一个网页的状态得以保持,而网页本身则可以通过一个计时器(timer)来察觉自己anchorhash的变化,从而相应改变自己的状态(参考这个帖子中提及的Nikhil Kothari的历史控件中的方法)。 Julien Couvreur在他的《Cross-document messaging hack》里描述了一个更复杂的应用情形,
"....
Forexample, if you have page A containing an iframe B in a differentdomain,then B can create a new iframe and load it with a url in thesame domain as A. The url that is loaded doesn't generate a request tothe server if it is properly cached and only the fragment identifier isused to pass changing information. Page A can now get the DOM handle onthe new iframe and successfully retrieve the information transmitted inthe url by B...." (大体这样,网页A包含了一个IFRAME B,B的网页来自一个不同的域。然后B页可以生成一个IFRAMEC,把它指向与网页A同域的某个地址,因为是A与C同域,网页A可以访问C里的信息,反之亦然。)ASP.NET AJAX扩展(即Atlas)提供了一个桥(bridge)机制让你在服务器端配置来访问别的网站,并同时支持POX和SOAP这2种协议。想了解其中细节,请参考Atlas文档里的《Building Mash-ups with "Atlas"》。当然你完全可以自己建立一个web service,通过它来访问其他网站并返回信息。
据说,Atlas中的 IFrameExecutor 可以实现跨域的调用,我按照MSDN博客Federal Developer Weblog的这篇帖子《Calling web services hosted outside of your application with “Atlas”》上的步骤试了一下,但在Windows 2003 Server SP1上得到却是“Access is denied”的错误信息。然后我下载了该文中的项目,试验的结果仍旧是“Access is denied”。也许需要改动一些浏览器中的什么设置才能成功,但这不是我的目的,我需要一个在普通设置下都能成功的例子。
按需(On-Demand) Javascript脚本的实现是很简单的,譬如我有这样一个网页,(想测试的话,需要改动其中的网址)
<html>
<head>
<script language="javascript" type="text/javascript">
function loadContent()
{
var s=document.createElement('SCRIPT');
s.src='http://www.anotherdomain.com/TestCrossJS.aspx?f=setDivContent';
document.body.appendChild(s);
}
function setDivContent(v)
{
var dv = document.getElementById("dv");
dv.innerHTML = v;
}
</script>
</head>
<body>
<div id="dv"></div>
<input type="button" value="Click Me" >
</body>
</html>
其中的www.anotherdomain.com/TestCrossJS.aspx是这样的,
<script language="C#" runat="server">
void Page_Load(object sender, EventArgs e)
{
string f = Request.QueryString["f"];
Response.Clear();
Response.C;
Response.Write(String.Format(@"
{0}('{1}');",
f,
DateTime.Now));
Response.End();
}
</script>
点击“Click Me”按钮,生成一个新的script tag,下载对应的 Javascript 脚本,结束时回调其中的setDivContent(),从而更新网页上一个div的内容。
IFRAME的方法好像很流行,除了dojo工具包支持外,据微软的Dare Obasanjo说(参考连接9),Windows Live Contacts Gadget使用了这个方法来获取Hotmail的address book。最近,Plaxo公司的开发人员 Joseph Smarr在七月的OSCON 2006会议上作了一个题为《Cross-site Ajax: Challenges and Techniques for Building Rich Web 2.0 Mashups》的讲座[来源:Kevin Yank--OSCON 2006: Cross-site Ajax],他们将这个方法做成了一个平台,允许合作伙伴间合作,他们开发的方案叫“The JavaScript Wormhole(虫洞)”,据说准备将其推广为一个标准。他讲座的PPT可以在这里下载,里面对这个方案做了说明,非常值得看一下。
现在将IFRAME的方法简单示范如下:
1. http://domain1/TestCross.html:
<html>
<head>
<script language="javascript" type="text/javascript">
var url = "http://domain2/TestCross.html"
var oldHash = null;
var timer = null;
function getHash()
{
var hash = window.location.hash;
if ((hash.length >= 1) && (hash.charAt(0) == '#'))
{
hash = hash.substring(1);
}
return hash;
}
function sendRequest()
{
var d = document;
var t = d.getElementById('request');
var f = d.getElementById('alienFrame');
f.src = url + "#" + t.value + "<br/>" + new Date();
}
function setDivHtml(v)
{
var d = document;
var dv = d.getElementById('response');
dv.innerHTML = v;
}
function idle()
{
var newHash = getHash();
if (newHash != oldHash)
{
setDivHtml(newHash);
oldHash = newHash;
}
timer = window.setTimeout(idle, 100);
}
function window.onload()
{
timer = window.setTimeout(idle, 100);
}
</script>
</head>
<body>
请求:<input type="text" id="request"> <input type="button" value="发送"/><br/>
回复:<div id="response"></div>
<iframe id="alienFrame" src="http://domain2/TestCross.html"></iframe>
</body>
</html>
2. http://domain2/TestCross.html:
<html>
<head>
<script language="javascript" type="text/javascript">
var url = "http://domain1/TestCross.html"
var oldHash = null;
var timer = null;
function getHash()
{
var hash = window.location.hash;
if ((hash.length >= 1) && (hash.charAt(0) == '#'))
{
hash = hash.substring(1);
}
return hash;
}
function sendRequest()
{
var d = document;
var t = d.getElementById('request');
var f = parent;
//alert(f.document); //试着去掉这个注释,你会得到“Access is denied”
f.location.href = url + "#" + t.value + "<br/>" + new Date();
}
function setDivHtml(v)
{
var d = document;
var dv = d.getElementById('response');
dv.innerHTML = v;
}
function idle()
{
var newHash = getHash();
if (newHash != oldHash)
{
setDivHtml(newHash);
oldHash = newHash;
}
timer = window.setTimeout(idle, 100);
}
function window.onload()
{
timer = window.setTimeout(idle, 100);
}
</script>
</head>
<body>
请求:<input type="text" id="request"> <input type="button" value="发送"/><br/>
回复:<div id="response"></div>
</body>
</html>
两个网页基本相同,第一个网页内嵌一个IFRAME,在点击“发送”按钮后,会将文本框里的内容通过hashfragment传给IFRAME。点击IFRAME里的“发送”按钮后,它会将文本框里的内容通过hashfragment传给父窗口。因为是只改动了hashfragment,浏览器不会重新load网页内容,这里使用了一个计时器来检测URL变化,如果变化了,就更新其中一个div的内容 。
这个方法是不是个安全漏洞?考虑到微软的Windows Live都在使用这个方法,估计不是,http://blog.joycode.com/emoticons/emotion-1.gif。这个方法是不是很安全?考虑到这个方法只有在2个网站协作的情形才能成功,安全问题好像不是很大,除非其中涉及的网站本身有XSS的问题。
【参考连接】
1. Security Considerations: Dynamic HTML
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/sec_dhtml.asp
2. About Cross-Frame Scripting and Security
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/om/xframe_scripting_security.asp
3. Cross-Domain Proxy
http://ajaxpatterns.org/Cross-Domain_Proxy
4. Cross Domain XMLHttpRequest using an IFrame Proxy
http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book75
5. Back Button Support for Atlas UpdatePanels
http://www.nikhilk.net/BackButtonSupport.aspx
6. Cross-document messaging hack
http://blog.monstuff.com/archives/000304.html
7. Building Mash-ups with "Atlas"
http://atlas.asp.net/docs/Walkthroughs/DevScenarios/bridge.aspx
8. Calling web services hosted outside of your application with “Atlas”
http://blogs.msdn.com/federaldev/archive/2006/07/31/684229.aspx
http://www.federaldeveloper.com/Shared%20Documents/Presentations%20by%20Marc%20Schweigert/CallAtlasWebServiceInDifferentProject.zip
9. AJAX Tip: Passing Messages Between iframes
http://www.25hoursaday.com/weblog/PermaLink.aspx?guid=3b03cf9d-b589-4838-806e-64efcc0a1a15
10. OSCON Cross-site Ajax Slides
http://blog.plaxo.com/archives/2006/07/oscon_crosssite.html
http://www.plaxo.com/css/api/Joseph-Smarr-Plaxo-OSCON-2006.ppt
11. OSCON 2006: Cross-site Ajax
http://www.sitepoint.com/blogs/2006/07/28/oscon-2006-cross-site-ajax/ 好帖 好帖{:soso_e192:}{:soso_e195:} 和你们一块学习。。。
页:
[1]