在爬取网页的时候要经常对js进行debug分析,selenium只做为测试工作使用,但是耗费资源高。目前很多网站的页面和报文都是通过js加密或者特殊处理生成,有些网站防爬策略是获取分辨率来判断的,最典型的应该是百度的防刷排名策略,就是通过分别率去判断,python或java是无法修改分别率的,比如说window.screen.height;比如说js文件中有个闭包方法里面的代码:
window.href = url+window.screen.height;
java程序或者python程序无法通过修改window.screen.height来模拟参数,那么这就需要修改js文件window.href = url+1024;
我们要在浏览器对js进行debug并且修改,修改完并通过console.log类似的功能输出指定的数据,那么java程序如何修改js代码?或者获取这些指定的数据?可以使用giant-htmlunit。
java代码
package test;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;
import org.apache.commons.collections.map.HashedMap;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.fetch.FetchWebContext;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.vo.fetch.ReloadContextVo;
/**
* 自制giant-htmlunit可以处理webclient多线程抓取网页,以便htmlunit更好的支持代理ip,拨号ip。节省更多的硬件资源。
* 本用例用于测试 giant-htmlunit,处理js文件进行测试,(支持gzip流格式文件的修改)
* context.asynCloseWebAllWindows();支持主线程异步关闭浏览器开启的job线程,htmlunit默认的close,是会等待job执行完毕的,不能预期关闭webclient,这样会大量占用内存跟线程资源,容易oom,asynCloseWebAllWindows很好的解决了该问题。
* @author lyq
*/
public class TestGiantClient {
public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
// updateJs();
// setWait();
// replaceJsResoure();//如果修改原始js太麻烦了,可以把js下载回来修改,修改完替换整个js
skipUrl();
}
/**
* @throws IOException
* cacheTest1.html 引入js1.js文件,修改js1.js代码,并执行。
*
*/
public static void updateJs() throws IOException{
FetchWebContext context = new FetchWebContext();
ReloadContextVo contextVo = new ReloadContextVo();
Map<String, ReloadContextVo> map = new HashedMap();
map.put("/js/js", contextVo);//识别url,如果url改变了,这个标识不变的情况下会重新加载js,比如说js/js1.js改成js2.js,最后会重新加载js2.js;现在流行单页面程序,像vue发布时候会重新生成js,加上后缀,这里正确设置,会重新加载最新的js
context.getFetchWebClient().cacheFile("/js/js");
contextVo.setStatic(true);//如果只替换一次,那么设置成true;如果需要动态替换,设置成false
// contextVo.add(arg0, arg1);
contextVo.add("(func1\\(\\)[\\w\\W]+?return\\s+?\")[\\w\\W]+?(\")","$1方法func1被修改了。。。$2");//类似 string。replaceAll方法,替换js代码
context.getFetchWebClient().setRegexToValue(map);
try{
HtmlPage page = (HtmlPage)context.getFetchWebClient().getPage("http://127.0.0.1:8085/test1/cacheTest1.html");
// context.getFetchWebClient().set
Object result = context.getFetchWebClient().getJavaScriptEngine().execute(page,"func1()" , "injected script", 1);
System.out.println(result);//这里输出“方法func1被修改了”
}catch(Exception e){
context.asynCloseWebAllWindows();
}
}
/**
*
* @throws IOException
* testWait.html 引入js文件waitJs.js文件,主程序等待waitJs。js里面的代码执行完毕再继续跑。
* addFilter× 与 waitFilter× 配对方法; 等待浏览器执行完js指定输出后再继续跑主程序
*/
public static void setWait() throws IOException{
FetchWebContext context = new FetchWebContext();
try{
context.getFetchWebClient().addFilterConsoleForStop("wait log1");
HtmlPage html = (HtmlPage)context.getFetchWebClient().getPage("http://127.0.0.1:8085/test1/testWait.html");
// context.getFetchWebClient().set
Long start = System.currentTimeMillis();
//这里找不到waitJs.js输出日志 "wait log1",所以会等待十秒钟,执行失败
context.getFetchWebClient().waitFilterConsoleForStop("wait log1", 10000);
// String result = context.getFetchWebClient().getConsoleResult();
System.out.println(context.getFetchWebClient().getFilterUrlMap().size()+"花费时间:"+(System.currentTimeMillis()-start));
context.getFetchWebClient().addFilterConsoleForStop("wait log");
html = (HtmlPage)context.getFetchWebClient().getPage("http://127.0.0.1:8085/test1/testWait.html");
// context.getFetchWebClient().set
start = System.currentTimeMillis();
//这里找不到waitJs.js输出日志 "wait log1",所以会等待js输出 wait log,执行成功
context.getFetchWebClient().waitFilterConsoleForStop("wait log", 10000);
// String result = context.getFetchWebClient().getConsoleResult();
System.out.println(context.getFetchWebClient().getFilterUrlMap().size()+"花费时间:"+(System.currentTimeMillis()-start));
}catch(Exception e){
context.asynCloseWebAllWindows();
}
}
/**
* @throws IOException
*testWait.html 引入js文件js1.js文件;主程序获取js2.js代替js1.js内容;
*
*/
public static void replaceJsResoure() throws IOException{
FetchWebContext context = new FetchWebContext();
ReloadContextVo vo = new ReloadContextVo();
context.getFetchWebClient().cacheFile("js/js");
try{
context.url2url("http://127.0.0.1:8085/js/js1.js", "http://127.0.0.1:8085/js/js2.js");
context.getFetchWebClient().addFilterConsoleForResult("my result:");
HtmlPage html = (HtmlPage)context.getFetchWebClient().getPage("http://127.0.0.1:8085/test1/cacheTest1.html");
// context.getFetchWebClient().set
context.getFetchWebClient().waitFilterConsoleResult("my result:", 1000);
String result = context.getFetchWebClient().getConsoleResult();
System.out.println(result);//输出我是js2
}catch(Exception e){
context.asynCloseWebAllWindows();
}
}
/**
* @throws IOException
* 跳过指定路径不获取
*
*/
public static void skipUrl() throws IOException{
FetchWebContext context = new FetchWebContext();
ReloadContextVo vo = new ReloadContextVo();
try{
context.getSkipUrls().add("/js/js");
HtmlPage html = (HtmlPage)context.getFetchWebClient().getPage("http://127.0.0.1:8085/test1/cacheTest1.html");
/***
* 这里跳过了含/js/js了路径,也就是不会再获取js文件
*/
System.out.println(html);
}catch(Exception e){
e.printStackTrace();
context.asynCloseWebAllWindows();
}
}
}
通过maven导入该工具
<dependency>
<groupId>com.giant</groupId>
<artifactId>giant-htmlunit</artifactId>
<version>2.26.8</version>
<scope>compile</scope>
</dependency>
<!--如果raw.githubusercontent.com不能下载参照https://blog.csdn.net/Mirt_/article/details/106011435-->
<repository>
<id>framework</id>
<name>framework</name>
<url>https://raw.githubusercontent.com/jzft/framework/master/repository/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
准备访问的html
//cacheTest1.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>cacheTest1.html</title>
</head>
<body>
<script src="/js/js1.js"></script>
</body>
</html>
//cacheTest2.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>cacheTest2.html</title>
</head>
<body>
<script src="/js/js2.js"></script>
</body>
</html>
//testWait.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TestWait</title>
</head>
<body>
<script src="/js/waitJs.js"></script>
</body>
</html>
</html>
html引用的js
//js1.js代码
console.log("my result:我是js1")
function func1(){
return "func1 execute"
}
//js2.js代码
console.log("my result:我是js2")
//waitJs.js代码
setTimeout(function(){
console.log("wait log !");
},3000)
分享到:
相关推荐
Java网页爬虫是一种用于自动化地抓取互联网上信息的程序,尤其在大数据分析、...通过深入研究和修改这个"Robot"类,可以扩展其功能,比如添加多线程爬取、设置爬取深度、处理JavaScript动态内容或者实现反反爬虫策略。
下面我们将详细探讨Android网页爬虫的实现过程以及可能涉及的关键技术。 首先,Android应用程序与服务器通信主要通过HTTP或HTTPS协议,常用的方法有使用Java的HttpURLConnection类或者第三方库如OkHttp。开发者需要...
Python网络爬虫是一种用于自动化获取网页内容的程序,它能够帮助我们从互联网上抓取大量信息,例如新闻、数据、文章等。在这个过程中,我们主要会用到Python的一些库,如requests、BeautifulSoup和Scrapy等。下面...
3. **修改抓取规则**:尝试修改爬虫的抓取规则,比如改变URL,抓取特定标签内的信息,或者调整抓取深度。 4. **扩展功能**:学习如何处理JavaScript生成的内容,或者实现反爬策略,比如模拟登录、处理验证码等。 5...
1. **版权问题**:在使用网页爬虫时必须尊重网站的robots.txt文件,避免抓取禁止抓取的页面,尊重版权和隐私。 2. **服务器压力**:大量抓取可能导致服务器负载增加,因此合理设定爬虫速度和频率是必要的。 3. **...
“强行在线修改网页源码”涉及到网页的动态操作,这可能指的是使用浏览器的开发者工具或者注入JavaScript代码来实时修改网页元素。虽然这对于开发者调试和学习网页布局非常有用,但若被恶意利用,例如通过XSS(跨站...
3. Selenium WebDriver:对于需要模拟用户交互或者处理JavaScript动态加载内容的网页,Selenium是一个很好的工具。它支持多种浏览器,可以真实地模拟用户操作,如点击按钮、填写表单、滚动页面等。Selenium与...
网页爬虫是自动抓取网页内容的程序,它在搜索引擎的工作中扮演了关键角色,用于收集和更新网络上的信息。Python 是一种广泛用于爬虫开发的语言,因为它具有丰富的库和简洁的语法,使得爬虫的编写变得相对简单。...
4. **渲染和交互**:CEFSharp不仅能够加载和渲染网页,还能通过JavaScript API与页面进行交互,执行JavaScript代码,获取或修改DOM元素。 **XML配置**: XML文件在这里起到了配置爬虫规则的作用,它可以定义如何...
- `config`:配置文件,包含如API接口地址、爬虫设置等信息。 - `logs`:日志文件,记录爬虫运行状态和错误信息。 - `requirements.txt`:列出项目依赖的Python库及其版本。 在实际操作中,遵循道德和法律法规,...
Python爬虫资源文件是一系列用于数据抓取和处理的源代码集合,主要针对Python编程语言。这个压缩包可能包含了各种工具、库、示例代码和教程,旨在帮助开发者快速掌握和应用Python爬虫技术。PyCharm是一款强大的...
本压缩包文件包含的"搜索网页采集网络爬虫java源代码"为开发者提供了一个实现这一功能的实例。 首先,让我们深入了解一下Java网络爬虫的基础知识: 1. **HTTP协议**:网络爬虫的基础是HTTP(超文本传输协议),它...
供的接口,并通过配置文件注入的方式,基本上能实现对所有的网页都 正确的解析和抓取。 3、如何使用? a、配置 bin\snoics-configpath.xml 文件 将配置文件中的path节点的值改为conf文件夹在系统...
爬虫技术中,解析HTML文档通常是通过解析库,如Python的BeautifulSoup或JavaScript的jsdom,它们能帮助我们方便地查找、提取和修改DOM树中的信息。通过学习和熟练掌握这些工具,我们可以高效地抓取和处理网页数据。 ...
"Crawler通用爬虫.zip"是一个强大的自定义模板爬虫工具,适用于任何可以通过浏览器访问的网页,大大拓展了爬虫的应用范围。本文将深入探讨其核心功能和使用方法。 首先,通用爬虫的核心在于它的自定义模板能力。这...
Node.js 是一种基于 Chrome V8 引擎的 JavaScript 运行环境,它让开发者能够使用 JavaScript 来进行服务器端编程。在"Node.js-图灵社区样书爬虫"项目中,我们主要会探讨如何利用 Node.js 的能力来构建一个网络爬虫,...
一旦找到,可以进一步分析其来源,通常是在某个JavaScript文件中。 图片文件“2全局搜索找到生成参数pid的js.png”可能是展示了在开发者工具中全局搜索`pid`的过程,从而定位到生成它的JavaScript代码。 2. **pid...
本主题将深入探讨如何创建一个简单的网络爬虫,用于提取网页中的`a`标签内容,即链接地址。我们将从基本概念出发,逐步介绍网络爬虫的工作原理,解析HTML,以及如何针对特定网页进行定制化爬取。 首先,了解网络...