如何抓取js函数抓取js生成的数据网页内容

网页抓取之新方法 (在java程序中使用jQuery) - 探底 - ITeye技术网站
博客分类:
你想要的任何信息,基本上在互联网上存在了,问题是如何把它们整理成你所需要的,比如在某个行业网站上抓取所有相关公司的的名字,联系电话,Email等,然后存到Excel里面做分析。网页信息抓取变得原来越有用了。
一般传统的网页,web服务器直接返回Html,这类网页很好抓,不管是用何种方式,只要得到html页面,然后做Dom解析就可以了。但对于需要Javascript生成的网页,就不那么容易了。 目前也没有找到好办法解决此问题。各位有抓javascript网页经验的朋友,欢迎指点。
所以今天要谈的还是传统html网页的信息抓取。虽然前面说了,没有技术难度,但是是否能有相对更容易的方法呢? 用过jQuery等js框架的朋友,可能都会觉得javascript貌似抓取网页信息的天然助手,而且其出生就是为了网页解析而存在的。当然现在有更多的应用了,如Server端的javascript应用,NodeJs.
如果能在我们的应用程序,如java程序中,能使用jQuery去抓网页,绝对是件激动人心的事情 。确实有现成的解决方案,一个Javascript引擎,一个能支撑jQuery运行的环境就可以了。
工具 : java, Rhino, envJs. 其中 Rhino是Mozzila提供的开源Javascript引擎,envJs是一个模拟浏览器额环境,如Window等。 代码如下,
package stony.zhang.
import java.io.FileNotFoundE
import java.io.FileR
import java.io.IOE
import java.lang.reflect.InvocationTargetE
import org.mozilla.javascript.C
import org.mozilla.javascript.ContextF
import org.mozilla.javascript.S
import org.mozilla.javascript.ScriptableO
* @author MyBeautiful
* @date Mar 7, 2012
public class RhinoScaper {
private String jsF
public String getUrl() {
public String getJsFile() {
return jsF
public void setUrl(String url) {
this.url =
putObject("url", url);
public void setJsFile(String jsFile) {
this.jsFile = jsF
public void init() {
cx = ContextFactory.getGlobal().enterContext();
scope = cx.initStandardObjects(null);
cx.setOptimizationLevel(-1);
cx.setLanguageVersion(Context.VERSION_1_5);
String[] file = { "./lib/env.rhino.1.2.js", "./lib/jquery.js" };
for (String f : file) {
evaluateJs(f);
ScriptableObject.defineClass(scope, ExtendUtil.class);
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (InvocationTargetException e1) {
e1.printStackTrace();
ExtendUtil util = (ExtendUtil) cx.newObject(scope, "util");
scope.put("util", scope, util);
protected void evaluateJs(String f) {
FileReader in =
in = new FileReader(f);
cx.evaluateReader(scope, in, f, 1, null);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
public void putObject(String name, Object o) {
scope.put(name, scope, o);
public void run() {
evaluateJs(this.jsFile);
测试代码:
package stony.zhang.
import java.util.HashM
import java.util.M
import junit.framework.TestC
public class RhinoScaperTest extends TestCase {
public RhinoScaperTest(String name) {
super(name);
public void testRun() {
RhinoScaper rs = new RhinoScaper();
rs.init();
rs.setUrl("");
rs.setJsFile("test.js");
Map&String, String& o = new HashMap&String, String&();
rs.putObject("result", o);
System.out.println(o.get("imgurl"));
test.js文件,如下
context: document.body,
success: function(data){
util.log(data);
var result =parseHtml(data);
var $v= jQuery(result);
util.log(result);
$v.find('#u a').each(function(index) {
util.log(index + ': ' + $(this).attr("href"));
arr.add($(this).attr("href"));
function parseHtml(html) {
//Create an iFrame object that will be used to render the HTML in order to get the DOM objects
//created - this is a far quicker way of achieving the HTML to DOM conversion than trying
//to transform the HTML objects one-by-one
var oIframe = document.createElement('iframe');
//Hide the iFrame from view
oIframe.style.display = 'none';
if (document.body)
document.body.appendChild(oIframe);
document.documentElement.appendChild(oIframe);
//Open the iFrame DOM object and write in our HTML
oIframe.contentDocument.open();
oIframe.contentDocument.write(html);
oIframe.contentDocument.close();
//Return the document body object containing the HTML that was just
//added to the iFrame as DOM objects
var oBody = oIframe.contentDocument.
//TODO: Remove the iFrame object created to cleanup the DOM
我们执行Unit Test,将会在控制台打印从网页上抓取的三个baidu的连接,
0: /gaoji/preferences.html 1: /?login&tpl=mn 2: /?reg&tpl=mn
测试成功,故证明在java程序中用jQuery抓取网页是可行的.
----------------------------------------------------------------------
推荐阅读,
下载次数: 298
青峰大辉 写道你好,整个工程直接运行报错:Exception in thread "main" org.mozilla.javascript.EvaluatorException: uncaught JavaScript runtime exception: ReferenceError: "util" is not defined. (./js/pair.js#3)受累看下。同问,楼主我刚才测试了下,没有发现你们说的问题;附上我测试图片。我用的jdk1.7;不知是否有关。
你好,整个工程直接运行报错:Exception in thread "main" org.mozilla.javascript.EvaluatorException: uncaught JavaScript runtime exception: ReferenceError: "util" is not defined. (./js/pair.js#3)受累看下。同问,楼主
楼主可以提供一下源码吗 写道代码有错& ExtendUtil 这个类是在那里定义的呢?yxzkm 写道嗯,不错!不过,请看一下jsoup,似乎在服务端就能解决dom的遍历问题对不起没有及时回复,已经把整个项目附上了,大家试试看。
Mybeautiful
浏览: 214950 次
来自: 武汉
袁光平 写道您好我设置了html格式,但是邮件中的超链接还是不 ...
您好我设置了html格式,但是邮件中的超链接还是不能正常显示为 ...
java程序语言学习教程 地址http://www.zuida ...
我还是建议博主,要把知识面放宽一些, 各种语音 和框架都了解一 ...Google 爬虫如何抓取 JavaScript 的? - WEB前端 - 伯乐在线
& Google 爬虫如何抓取 JavaScript 的?
我们测试了谷歌爬虫是如何抓取 JavaScript,下面就是我们从中学习到的知识。
认为 Google 不能处理 JavaScript ?再想想吧。Audette Audette 分享了一系列测试结果,他和他同事测试了什么类型的 JavaScript 功能会被 Google 抓取和收录。
1. 我们进行了一系列测试,已证实 Google 能以多种方式执行和收录 JavaScript。我们也确认 Google 能渲染整个页面并读取 DOM,由此能收录动态生成的内容。
2. DOM 中的 SEO 信号(页面标题、meta 描述、canonical 标签、meta robots 标签等)都被关注到。动态插入 DOM 的内容都也能被抓取和收录。此外,在某些案例中,DOM 甚至可能比 HTML 源码语句更优先。虽然这需要做更多的工作,但这是我们好几个测试中的一个。
引言:Google 执行 JavaScript & 读取 DOM
早在 2008 年, Google 就 ,但很可能局限于某种方式。
而在今天,可以明确的是,Google 不仅能制定出他们抓取和收录的 JavaScript 类型,而且在渲染整个 web 页面上取得了显著进步(特别在最近的 12 到 18 个月)。
在 Merkle,我们的 SEO 技术团队想更好地理解谷歌爬虫能抓取和收录什么类型的 JavaSscript 事件。经过研究,我们发现令人瞠目的结果,并已证实 Google 不仅能执行各种 JavaScript 事件,而且能收录动态生成的内容。怎么样做到的?Google 能读取 DOM。
DOM 是什么?
很多搞 SEO 的都不理解什么是 (DOM)。
当浏览器请求页面时会发生什么,而 DOM 又是如何参与进来的。
当用于 web 浏览器,DOM 本质上是一个应用程序的接口,或 API,用于标记和构造数据(如 HTML 和 XML)。该接口允许 web 浏览器将它们进行组合而构成文档。
DOM 也定义了如何对结构进行获取和操作。虽然 DOM 是与语言无关的 API (不是捆绑在特定编程语言或库),但它普遍应用于 web 应用程序的 JavaScript 和 动态内容。
DOM 代表了接口,或“桥梁”,将 web 页面与编程语言连接起来。解析 HTML 和执行 JavaScript 的结果就是 DOM。web 页面的内容不(不仅)是源码,是 DOM。这使它变得非常重要。
JavaScript 是如何通过 DOM 接口工作的。
我们兴奋地发现 Google 能够读取 DOM,并能解析信号和动态插入的内容,例如 title 标签、页面文本、head 标签和 meta 注解(如:rel = canonical)。可阅读其中的完整细节。
这一系列测试和结果
因为想知道什么样的 JavaScript 功能会被抓取和收录,我们单独对 谷歌爬虫 创建一系列测试。通过创建控件,确保 URL 活动能被独立理解。下面,让我们详细划分出一些有趣的测试结果。它们被分为 5 类:
JavaScript 重定向
JavaScript 链接
动态插入内容
动态插入 Meta 数据 和页面元素
一个带有 rel = “nofollow” 的重要例子
例子:一个用来测试谷歌爬虫理解 JavaScript 能力的页面。
1. JavaScript 重定向
我们首先测试了常见的 JavaScript 重定向,用不同方式表示的 URL 会有什么样结果呢?我们选择了 window.location 对象进行两个测试:Test A 以绝对路径 URL 调用 window.location,而 Test B 使用相对路径。
结果:该重定向很快被 Google 跟踪。从收录来看,它们被解释为 301 – 最终状态的 URL 取代了 Google 收录里的重定向 URL。
在随后的测试中,我们在一个权威网页上,利用完全相同的内容,完成一次利用 JavaScript 重定向到同一个站点的新页面。而原始 URL 是排在 Google 热门查询的首页。
结果:果然,重定向被 Google 跟踪,而原始页面并没有被收录。而新 URL 被收录了,并立刻排在相同查询页面内的相同位置。这让我们很惊喜,以排名的角度上看,视乎表明了JavaScript 重定向行为(有时)很像永久性的 301 重定向。
下次,你的客户想要为他们的网站完成 JavaScript 重定向移动,你可能不需要回答,或回答:“请不要”。因为这似乎有一个转让排名信号的关系。支持这一结论是引用了 :
使用 JavaScript 为用户进行重定向,可能是一个合法的做法。例如,如果你将已登录用户重定向到一个内部页面,你可以使用 JavaScript 完成这一操作。当仔细检查 JavaScript 或其他重定向方法时,以确保你的站点遵循我们的指南,并考虑到其意图。记住 301 重定向跳转到你网站下是最好的,但如果你没有权限访问你网站服务器,你可以为此使用 JavaScript 重定向。
2. JavaScript 链接
我们用多种编码方式测试了不同类型的 JS 链接。
我们测试下拉菜单的链接。历史上的搜素引擎一直不能跟踪这类型的链接。我们想确定 onchange 事件处理器是否会被跟踪。重要的是,这只是执行特定的类型,而我们需要是:其它改动后的影响,而不像上面 JavaScript 重定向的强制操作。
例子: Google Work 页面的语言选择下拉菜单。
结果:链接被完整地抓取和跟踪。
我们也测试了常见的 JavaScript 链接。下面是最常见类型的 JavaScript 链接,而传统的 SEO 则推荐纯文本。这些测试包括 JavaScript 链接代码:
作用于外部 href
键-值对(AVP),但在一个标签内(“onClick”)
作用 href 内部 AVP(“javascript : window.location”)
作用于 a 标签外部,但在 href 内调用 AVP(“javascript : openlink()”)
结果:链接被完整抓取和跟踪。
我们下一个测试是更进一步地测试事件处理器,如上面测试的 onchange。具体地说,我们希望利用鼠标移动的事件处理器,然后隐藏 URL 变量 ,该变量只在事件处理函数(在该案例是 onmousedown 和 onmouseout)被触发时执行。
结果:链接被完整抓取和跟踪。
构造链接:我们知道 Google 能执行 JavaScript,但想确认它们是否能读取代码里的变量。所以在该测试中,我们连接能构造 URL 字符串的字符。
结果:链接被完整抓取和跟踪。
3. 动态插入内容
很明显,这些都是重点:动态插入文本、图像、链接和导航。优质的文本内容对搜索引擎理解网页主题和内容是至关重要的。在这个动态网站的时代,它的重要性是无需质疑的。
这些测试,设计出来是为了检查在两个不同场景下动态插入文本的结果。
1. 测试搜索引擎能否统计动态插入的文本,而文本是来自页面 HTML 源码内的。
2. 测试搜索引擎能否统计动态插入的文本,而文本是来自页面 HTML 源码外的(在一个外部 JavaScript 文件内)。
结果:在两个案例中,文本都能被抓取和收录,并且页面是根据该内容进行排名。爽!
为了了解更多相关信息,我们测试了一个通过 JavaScript 编写的客户端全局导航,而导航里的链接都是通过 document.writeIn 函数插入,并且确定它们能被完全抓取和跟踪。应该指出的是:Google 能解释使用 AngularJS 框架 和 HTML5 History API(pushState)构建的网站,能渲染和收录它,并能像传统静态网页一样排名。这就是 获取外部文件和 JavaScript 的重要性,而且这也许是 Google 正在从
中移除它的原因。当你能简单地渲染整个页面时候,谁还需要 HTML 快照呢?
经过测试后发现,不管什么类型的内容,都是同样的结果。例如,图像加载到 DOM 后会被抓取和收录。我们甚至做了这样的一个测试:通过动态生成 (面包屑导航),并将其插入 DOM。结果呢? 成功插入后的面包屑出现在搜索结果中了 (search engine results page)。
值得注意的是,Google 现在
形成结构化数据。我敢肯定将来会出现更多基于此的东西。
4. 动态插入 Meta 数据 & 页面元素
我们将各种对 SEO 至关重要的标签动态插入到 DOM:
Title 元素
Meta robots
Canonical tags
结果:在所有案例中,标签都能被抓取,其表现就像 HTML 源码里的元素一样。
一个有趣的补充实验帮助我们理解优先顺序。当存在冲突信号时,哪一个会胜出呢?如果源码里有 noindex、nofollow 标签,而 DOM 里有 noindex、follow 标签的话,将会发生什么呢?在这协议里,HTTP x-robots 响应头部的行为如何作为另一个变量?这将是未来综合测试的一部分。然而,我们的测试显示:当冲突时,Google 会无视源码里的标签,而支持
5. 一个带有 rel =“nofollow” 的重要例子
我们想测试 Google 如何应对出现在源码和 DOM 的链路级别的 nofollow 属性。我们也因此创建了一个没有应用 nofollow 的控件。
对于 nofollow ,我们分别单独测试源码 vs DOM 生成的注解。
源码里的 nofollow 正如我们所期待的那样运行(链接没被跟踪)。而 DOM 里的 nofollow 却失效(链接被跟踪,并且页面被收录)。为什么?因为在 DOM 里修改 href 元素的操作发生得太晚了:Google 在执行添加 rel=”nofollow” 的 JavaScript 函数前,已准备好抓取链接和队列等待着 URL。然而,如果将带有 href =”nofollow”的 a 元素插入到 DOM,nofollow 和链接因在同一时刻插入,所以会被跟踪。
从历史角度上看,各种 SEO 推荐是在任何可能的时候,要尽可能专注 ‘纯文本’ 内容。而动态生成内容、AJAX 和 JavaScript 链接会损害主流搜索引擎的 SEO。显然,这对 Google 不再是问题。 JavaScript 链接以类似普通的 HTML 链接方式运行(这只是表面,而我们不知道幕后程序进行了什么操作)。
JavaScript 重定向都会以类似于 301 重定向方式对待。
动态插入内容,甚至 meta 标签,如 rel canonical 注解,无论在 HTML 源码,还是在最初 HTML 被解析后触发 JavaScript 生成 DOM ,都以同等方式对待。
Google 视乎能完全渲染页面和理解 DOM ,而不仅是源码。实在是令人可不思议!(记得允许谷歌爬虫获取那些外部文件和 JavaScript。)
Google 已经在创新方面,以惊人的速度将其它搜索引擎甩在身后。我们希望看到其它搜索引擎能有同样类型的创新。如果他们要保持竞争力,并在 web 新时代取得实质性进展,这意味着它们要更好地支持 HTML5、JavaScript 和 动态网站。
对于 SEO,那些没有理解上述基本概念和 Google 技术的人,应该好好研究和学习,以赶上当前技术。如果你不把 DOM 考虑在内,您可能会丢失一半份额。
本文所表达观点不全是由 Search Engine Land (一家搜索引擎网站)提供,部分观点是由客座作者提供。。
打赏支持我翻译更多好文章,谢谢!
打赏支持我翻译更多好文章,谢谢!
任选一种支付方式
关于作者:
可能感兴趣的话题
学习了,之前一直以为凡是js生成的数据,搜索引擎一律不抓取的,现在看来这个老观念应该被抛弃了,起码在某种程度上被抛弃
o 179 回复
关于伯乐前端
伯乐前端分享Web前端开发,包括JavaScript,CSS和HTML5开发技术,前端相关的行业动态。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2016 伯乐在线jQuery获取动态生成的元素
需求描述:页面上可以动态添加数据,比如table,点击按钮可以动态添加行。又或页面加载时table数据是通过ajax从后台获取的。而这时我们想要获取其中的某个值,又该如何获取呢?如果是要通过某个事件来获取的比如click,mouver等等,则可以使用live()方法$(".button").live("click",function(){
($("#mytd").html());
}) live()的详细说明参考http://blog.csdn.net/itmyhome1990/article/details/而如果不是通过某个事件,当页面加载的时候我们就要获取值或进行其他操作live()方法就不行了,因为我们无法传入一个事件。比如以下代码:
&script type="text/javascript"&
$(function() {
$.post("admin/UserForumthemeBabygrowupFrontList.do",{},function(data){
(data.table);
$("#tab").append(data.table);
alert($("#mytd").html()); //获取值
&/script&以上代码很简单,就是通过post从后台返回的值添加到中后台返回数据为 北京深圳而我们要在post之后获取id为mytd的值,此时是获取不到的,我们从中就可以观察出问题:从以上可以看出在alert的时候 数据并还没有加载出来 控制台也并没有打印出信息,所以此时是取不到数据的。使用ajaxComplete()方法可以在请求完成时运行要执行的代码,我们修改为如下:vcD48cD48L3A+PHByZSBjbGFzcz0="brush:">$(function() {
$.post("admin/UserForumthemeBabygrowupFrontList.do",{},function(data){
(data.table);
$("#tab").append(data.table);
$("#tab").ajaxComplete(function(){
//待请求完成时 执行
alert($("#mytd").html());
});此时再获取的时候页面已加载完数据。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'查看: 14828|回复: 29
怎么获取js执行过的网页源码
阅读权限50
在线时间 小时
结帖率: (44/87)
表示一些网站的内容,不在源码当中,虽然js执行后可以看到.但是在源代码当中也是看不到的.
表示请请教一下,如何获取js执行后的源码内容呢?
表示我想问的不是和get,而是能不能使用调用 Ie 内核的方式去获取js调用后的网页源码.
回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至
可获得加分喔。友情提醒:本版被采纳的主题可在
帖子申请荣誉值,获得 1点 荣誉值,荣誉值可兑换终身vip用户组哦。快捷通道: →
阅读权限165
在线时间 小时
签到天数: 12 天
看看这样行不行,直接在超文本浏览框里面写上你要获取的地址就行了!
09:59 上传
点击文件名下载附件
41.4 KB, 下载次数: 776
您可以选择打赏方式支持他
阅读权限30
在线时间 小时
结帖率: (3/3)
用opera浏览器,js脚本都有显示,调试非常方便
您可以选择打赏方式支持他
阅读权限50
在线时间 小时
结帖率: (44/87)
砖缝里的小强 发表于
用opera浏览器,js脚本都有显示,调试非常方便
前辈,我是希望能够在程序当中获取到呐,
在程序当中是不能调用 opera 的内核的吧.求指点.
您可以选择打赏方式支持他
阅读权限50
在线时间 小时
结帖率: (44/87)
ljmst 发表于
看看这样行不行,直接在超文本浏览框里面写上你要获取的地址就行了!
感谢前辈,能不能再请教两个地方.
1 在超级文本浏览框里面 读取地址的时候,有一个延迟,就是说打开网址,执行里面的js成功.这个时间能够判断出来呢?不然抓取数据的时候,如果js没有执行完毕,肯定会抓取失败.
2 如果是使用一个超级文本浏览框的话,是不是无法使用多线程了.因为多线程共用的话,数据肯定会冲突吧? 想问问前辈有没有办法解决?
表示希望前辈能够回答一下.
您可以选择打赏方式支持他
阅读权限50
在线时间 小时
结帖率: (6/16)
可以试着抓包,即使他是js。也得有数据包。我以前也遇过这种需要js之后才有源码。通过抓包。可以找出真正地址。
您可以选择打赏方式支持他
阅读权限50
在线时间 小时
结帖率: (44/87)
<font color="#82139 发表于
可以试着抓包,即使他是js。也得有数据包。我以前也遇过这种需要js之后才有源码。通过抓包。可以找出真正地 ...
抓包?前辈不是太明白你的意思.是指post和get吗?
表示不太懂,请前辈们指点一下.
您可以选择打赏方式支持他
阅读权限50
在线时间 小时
结帖率: (6/16)
<font color="#33789 发表于
抓包?前辈不是太明白你的意思.是指post和get吗?
表示不太懂,请前辈们指点一下.
把地址放出来。我写个例程
您可以选择打赏方式支持他
阅读权限50
在线时间 小时
结帖率: (44/87)
<font color="#82139 发表于
把地址放出来。我写个例程
/?host=bbs.125.la
表示就是这样的.
求前辈指点.
您可以选择打赏方式支持他
阅读权限50
在线时间 小时
结帖率: (6/16)
抓包后发现。他的结果是gzip的。要进gzip解压。精易模块有。
您可以选择打赏方式支持他
精易论坛 - 有你更精彩 /1
定制区已重新开放。
易友的力量和智慧是无穷大的,为了论坛更好地持续发展,给大家提供更好的服务,诚邀大家共同出谋划策,请在遵守国家法律法规以及良好的用户体验、能够满足大家需求的基础下,大胆想象,给论坛和软件定制版块提建议/整改方案
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
揭阳精易科技有限公司申明:我公司所有的培训课程版权归精易所有,任何人以任何方式翻录、盗版、破解本站培训课程,我们必将通过法律途径解决!
公司简介:揭阳市揭东区精易科技有限公司致力于易语言教学培训/易语言学习交流社区的建设与软件开发,多年来为中小企业编写过许许多多各式软件,并把多年积累的开发经验逐步录制成视频课程供学员学习,让学员全面系统化学习易语言编程,少走弯路,减少对相关技术的研究与摸索时间,从而加快了学习进度!
防范网络诈骗,远离网络犯罪
违法和不良信息举报电话,企业QQ: ,邮箱:
Powered by

我要回帖

更多关于 php 抓取网页生成图片 的文章

 

随机推荐