
htmlunit抓取动态网页
htmlunit抓取动态网页(南京凯壹良seo怎么看来百度对于动态网页的抓取都不尽如人意)
网站优化 • 优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2022-02-22 04:22
无论网站写什么语言的seo,总会涉及到两个概念,动态的和静态的。百度官方发布了关于动态页面和静态页面的说明,称对动态网站和静态网站一视同仁,没有区别对待爬取,因此成功误导了一批网站优化人员。
南京凯易良seo看来百度对动态网页的抓取并不理想,尤其是网站收录方面。Kai Yiliang seo 已经玩wordpress 个人博客一年半了,明显感觉wordpress 博客的收录 很差。百度本身不适合博客类网站收录,你可以看看有多少收录自己的新浪博客和网易博客。这和博客本身的属性有关,体现在博客的使用上。插件、下载的模板、网址设置等。要知道wordpress是美国技术人员开发的程序,比较适合谷歌的算法。百度和谷歌是不同的,所以SEO不应该被百度误导。使用 wordpress 构建个人博客是可以的。
另一个凯一亮seo接触到的动态页面是用asp写的,这种老语言有它的优势,但是收录和wordpress一样难过。老asp站点的收录还是不错的,这关系到域名的长期优势,但是新的asp网站收录实在是让SEO们头疼,也没有时间研究技术代码。事物。
所以建议seos在开网站前一定要考虑网站用什么语言,这对后期的优化影响很大,体现在优化的难度和时间上。如果你有足够的经验,就不用担心这些问题,因为它们在技术上是可以克服的。
本文章“百度从互联网的采集整理上区分动态网页和静态网页,如有版权问题,请联系本网站删除!” 当前文章地址:更多相关南京seo网站优化文章请阅读查看! 查看全部
htmlunit抓取动态网页(南京凯壹良seo怎么看来百度对于动态网页的抓取都不尽如人意)
无论网站写什么语言的seo,总会涉及到两个概念,动态的和静态的。百度官方发布了关于动态页面和静态页面的说明,称对动态网站和静态网站一视同仁,没有区别对待爬取,因此成功误导了一批网站优化人员。
南京凯易良seo看来百度对动态网页的抓取并不理想,尤其是网站收录方面。Kai Yiliang seo 已经玩wordpress 个人博客一年半了,明显感觉wordpress 博客的收录 很差。百度本身不适合博客类网站收录,你可以看看有多少收录自己的新浪博客和网易博客。这和博客本身的属性有关,体现在博客的使用上。插件、下载的模板、网址设置等。要知道wordpress是美国技术人员开发的程序,比较适合谷歌的算法。百度和谷歌是不同的,所以SEO不应该被百度误导。使用 wordpress 构建个人博客是可以的。
另一个凯一亮seo接触到的动态页面是用asp写的,这种老语言有它的优势,但是收录和wordpress一样难过。老asp站点的收录还是不错的,这关系到域名的长期优势,但是新的asp网站收录实在是让SEO们头疼,也没有时间研究技术代码。事物。
所以建议seos在开网站前一定要考虑网站用什么语言,这对后期的优化影响很大,体现在优化的难度和时间上。如果你有足够的经验,就不用担心这些问题,因为它们在技术上是可以克服的。
本文章“百度从互联网的采集整理上区分动态网页和静态网页,如有版权问题,请联系本网站删除!” 当前文章地址:更多相关南京seo网站优化文章请阅读查看!
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2022-02-19 04:00
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论! 查看全部
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论!
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2022-02-19 03:29
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论! 查看全部
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论!
htmlunit抓取动态网页( 开发爬虫项目有通用性吗?如何构建基于配置化的分布式爬虫应用?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 141 次浏览 • 2022-02-18 20:10
开发爬虫项目有通用性吗?如何构建基于配置化的分布式爬虫应用?)
一起
在我工作的很多公司里,有很多领域,比如房地产、电商、广告等领域。虽然业务差别很大,但都涉及到爬虫领域。开发了更多爬虫项目后,自然会面临一个问题——
l 这些开发的爬虫项目通用吗?
l 是否可以以更低的成本完成一个新的爬虫需求?
l 在维护和运行过程中,是否可以工具化构建基于配置的分布式爬虫应用?
这就是我们今天要讨论的内容。
二 项目要求
在项目开始时,我们尝试从使用的脚提出一些要求。
1. 分布式爬取
由于爬取的量可能非常大,一台机器不足以处理超过一百万的爬取任务,所以分布式爬虫应用是第一个要面对和解决的问题。
2. 模块化、轻量级
我们将爬虫应用分为四个角色:“应用层、服务层、业务处理层、调度层”。
3. 可管理、可监控
管理监控是一个系统,即配置可以管理,运行可以实时监控。当系统正常运行时,可以更改爬虫的配置。一旦实时监控爬虫出现异常,可以实时修正配置进行干预。一切都可以通过UI界面进行操作。
4. 通用的,可扩展的。
爬虫业务往往是多变的,不同领域的爬取需求是不一样的。例如,房源采集包括图像采集、社区信息采集、房源去重等模块。新闻抓取包括内容抓取、文本提取、信息摘要等。
因此,系统需要能够支持业务扩展需求,能够支持不同业务使用相同的框架进行应用开发。
三模块分解
针对业务需求,我们将系统分解为多个应用模块。
应用层
应用层适用于管理员和系统维护人员。主要分为两个模块,系统配置模块和运行管理模块。
l 系统配置模块:系统配置模块包括抓取网站管理配置、在线测试等功能。
l 运营管理模块:运营管理模块包括实时抓拍量统计、分析、准确率等,甚至包括故障原因、故障数量。
系统操作人员可以根据操作模块得到实时反馈,并使用系统配置模块进行配置修正。在线测试无误后,配置生效,然后实时监控新配置的效果。
服务层
服务层是整个系统传输的中心,相当于整个分布式集中式系统总线和数据总线。服务层提供http/thrift接口,读取数据库,输出配置信息。
一种。提供网站爬虫配置界面。实时从数据库中读取配置信息,响应业务层的配置请求。
湾。提供业务层的输出写入接口。实时接收业务层爬取的信息汇总,包括正确数据量、错误数据量、错误原因等。
C。提供实时报表统计分析。响应应用层的运营管理模块,查询数据库,实时提供数据分析报告。
业务处理层
业务处理层是整个爬虫系统的核心,可以划分为多个应用服务器进行处理。业务处理层主要包括解决两件事。
l 如何获取网址
l 获取到url后如何处理
(一) 如何获取 url
对于爬虫来说,如何获取 url 非常重要。我们将此过程定义为发现系统。对于发现系统来说,目标是如何发现要爬取的网站的详细URL列表,并尽可能的发现。
假设场景 A
我们来看一个电商网站:打开首页--打开分类页面--可能有多个分类页面--逐层点击--直到最小的分类页面。
当你打开这个分类页面时,你会发现分类页面下的所有分页页面。如果一次向下滚动一页,则可以获取类别页面中的所有产品。
假设情景 B
我们去买车吧网站:打开首页——找到品牌页——然后找到车系——最后找到车型页。
通过以上场景分析,我们可以得出一个结论,人们可以非常智能的找到所有需要爬取的详细页面,即电商产品和车型页面。那么,是否可以通过配置来模拟这个过程呢?
请看下图:
备注如下:
1. 根信息:
定义发现模块的入口页面,就像人们打开公交车站的网页一样,后续的发现都是从这些入口页面开始的。
这里给出的例子是汽车网络的品牌列表页面,根据“模板化”应用变量的配置,总共有100个入口页面。
2. 步骤:
依次遍历这100个入口页面,分别执行steps中定义的步骤。查看和浏览机器模拟人类的方式。
每一步都使用“link_module”定义的类进行逻辑处理。
一种。读取入口页面的html,结合“sub_prefix”、“sub_suffix”和“select”定义的内容,获取页面子区域的html。
湾。使用“link_match_method”方法(包括前缀收录、匹配等)提取子区域的链接。
C。每个链接都匹配“link_pattern”,匹配成功的url进入下一步。
d。每一步得到的url都会自动转发到下一步处理。处理逻辑对上述ac递归,直到“last_step”为真。
这里,“last_step”为真时找到的url就是发现系统最终需要获取的url列表。发现系统总结,通过配置方法,结合人类的浏览习惯,经过数步迭代,最终得到网站的详细页面url列表。
由于每个步骤的提取链接规则和步骤数据都是手动定义的,因此可以适应网站的大部分发现系统。当然,越复杂的网站发现配置可能会越来越复杂,但同样如此。
(二)获取到url后如何处理
前提当然是每个业务的处理都不一样,包括提取页面属性、文本提取、图片获取,甚至与当前系统对接的功能。
由于业务处理不一致,自然会想到通过配置来定义责任链系统,就像著名框架Netty中的Pipeline设计一样。在处理的过程中,定义了一个Context上下文处理类,所有的中间结果都挂在这个Context中。
描述比较空洞,但还是以实际案例为准。
备注如下:
获取 url 后,读取配置并在 url 匹配“site”时应用当前的“site”规则。
1. pipeline 定义了责任链的处理
这里的定义是“爬取模块、Javascript处理模块、通用解析模块”。对应的处理如下:
先执行爬取模块获取html。然后执行Javascript处理模块,输入为html,解析html。这可能是评论或价格。简单来说就是先处理动态加载项目,再处理“通用解析模块”。
2. "parser_rules" 定义解析模块
最终的输出是kv,在java中是map,在python中是dict。即从上一步的html中,找到每个推荐的“sizzle”,执行“prefix”、“suffix”去掉前缀和后缀(过滤为“price:xxx元,前缀“price:”,后缀为元)。
顺便说一句,sizzle 也是一种开源技术。据说大名鼎鼎的Jquery也是一个“咝咝”的引擎。Java可以使用Jsoup解析处理。
你怎么知道要获取什么“嘶嘶作响”的内容?具体可以结合firebug插件,选择即可获得。选择后,可以结合应用层的管理工具进行测试。
3. “需要”
可以看到,配置项中有“isrequire”,表示是否需要这个内容。如果在实际处理中需要而无法获取,则在爬取过程中会记录错误,而错误的原因自然是“$key is null”。另外,每个模块都可能出错,一旦出错,以后就不需要再执行了。
因此,在爬取过程中,业务处理层从服务层获取一批url(默认为100个)后,处理完这100个url后,会上报给服务层,上报内容为:
当前任务处理机在什么时间处理100页。不同的网站有多少成功,有多少失败,有多少模块失败,解析模块中有多少字段失败。
所有这些信息都是实时统计的,并在运行监控系统中以图形方式绘制。必要时可发出警报,维修人员可实时介入。
Q:问个问题,如果我加了一个网站怎么办?
A:其实很简单,再增加一个配置就行了。业务定义管道。如果有解析需求,填写对应的解析项。
以上两个系统,发现系统和处理系统,在我们的实际生产中经过以下步骤运行。
一种。发现系统会累积发现要爬取的详细页面网站,因为它是一个累积和持续的过程。因此,您可以确保继续无限接近 网站 的 100% 页面。
湾。处理系统通过服务层获取配置信息(可能由维护人员实时修正)和待抓取列表进行处理。
待抓取的列表根据业务的优先级分为普通队列和优先级队列,通过任务调度系统统一管理和配置。
调度层
l 调度层主要是业务系统。
l 添加任务调度器网站
l 网站 发现频率,包括增量发现频率和完全发现频率
l 网站抢优先级被推入队列
l 断点续传管理
我...
四系统架构设计
l 从业务模块来看
应用层、服务层、业务处理层、调度层
l 从功能系统来看
发现系统、抓取系统、配置系统、监控系统
l 从可扩展性的角度
自定义责任链,自定义属性抽取
l 从实时角度
实时捕捉,实时配置有效,实时监控,实时测试
l 从系统架构来看
分布式架构,服务层主从切换设计,轻量级(只依赖队列、数据库、java)
五个传说
①
②
③
爬虫模块ui二(1.6任务配置):
定义每个爬虫任务的处理和执行责任链。不同的爬虫任务可以有不同的处理链。对于系统来说,处理每一个待爬取的url都会按照责任链的顺序执行。后处理类是在一批任务执行后(比如上面的100个url)进行批量提交的方法。比如文件登陆、存储、推送到线上系统等。通过定义任务处理,可以自定义各种场景的爬虫业务,增加系统的灵活性,无需编码。
④
属性配置:
如图,如果维护者添加了测试的url,定义了要提取的属性,就可以在线定义页面对应的属性输出,查看即可。在增加便利性和可测试性的基础上,可以灵活选择页面的任意属性。值得一提的是,sizzle的配置可以通过firefox插件获取。
⑤
1.9查看详情:
在爬虫系统运行过程中,几乎可以实时监控任务。由于爬虫任务将爬取状态实时写入数据库,因此可以通过ui界面进行管理和监控。1. 监控:监控当前时间爬虫任务成功数、错误数、什么模块出错,甚至是属性提取错误。2.管理:维护人员观察监控效果后,可以实时编辑管理(见上图),满足不同网站修改的需要。所有编辑实时生效。编辑后无需重启服务,可实时监控爬虫任务的最新效果。
高级建筑师
十余年数据研发经验,擅长数据处理,如爬虫、搜索引擎、大数据应用的高并发。历任架构师、研发经理等职务。曾主导开发大型爬虫、搜索引擎和大数据广告DMP系统。目前负责奇安科技数据平台的开发建设。 查看全部
htmlunit抓取动态网页(
开发爬虫项目有通用性吗?如何构建基于配置化的分布式爬虫应用?)

一起
在我工作的很多公司里,有很多领域,比如房地产、电商、广告等领域。虽然业务差别很大,但都涉及到爬虫领域。开发了更多爬虫项目后,自然会面临一个问题——
l 这些开发的爬虫项目通用吗?
l 是否可以以更低的成本完成一个新的爬虫需求?
l 在维护和运行过程中,是否可以工具化构建基于配置的分布式爬虫应用?
这就是我们今天要讨论的内容。
二 项目要求
在项目开始时,我们尝试从使用的脚提出一些要求。
1. 分布式爬取
由于爬取的量可能非常大,一台机器不足以处理超过一百万的爬取任务,所以分布式爬虫应用是第一个要面对和解决的问题。
2. 模块化、轻量级
我们将爬虫应用分为四个角色:“应用层、服务层、业务处理层、调度层”。
3. 可管理、可监控
管理监控是一个系统,即配置可以管理,运行可以实时监控。当系统正常运行时,可以更改爬虫的配置。一旦实时监控爬虫出现异常,可以实时修正配置进行干预。一切都可以通过UI界面进行操作。
4. 通用的,可扩展的。
爬虫业务往往是多变的,不同领域的爬取需求是不一样的。例如,房源采集包括图像采集、社区信息采集、房源去重等模块。新闻抓取包括内容抓取、文本提取、信息摘要等。
因此,系统需要能够支持业务扩展需求,能够支持不同业务使用相同的框架进行应用开发。
三模块分解
针对业务需求,我们将系统分解为多个应用模块。
应用层
应用层适用于管理员和系统维护人员。主要分为两个模块,系统配置模块和运行管理模块。
l 系统配置模块:系统配置模块包括抓取网站管理配置、在线测试等功能。
l 运营管理模块:运营管理模块包括实时抓拍量统计、分析、准确率等,甚至包括故障原因、故障数量。
系统操作人员可以根据操作模块得到实时反馈,并使用系统配置模块进行配置修正。在线测试无误后,配置生效,然后实时监控新配置的效果。
服务层
服务层是整个系统传输的中心,相当于整个分布式集中式系统总线和数据总线。服务层提供http/thrift接口,读取数据库,输出配置信息。
一种。提供网站爬虫配置界面。实时从数据库中读取配置信息,响应业务层的配置请求。
湾。提供业务层的输出写入接口。实时接收业务层爬取的信息汇总,包括正确数据量、错误数据量、错误原因等。
C。提供实时报表统计分析。响应应用层的运营管理模块,查询数据库,实时提供数据分析报告。
业务处理层
业务处理层是整个爬虫系统的核心,可以划分为多个应用服务器进行处理。业务处理层主要包括解决两件事。
l 如何获取网址
l 获取到url后如何处理
(一) 如何获取 url
对于爬虫来说,如何获取 url 非常重要。我们将此过程定义为发现系统。对于发现系统来说,目标是如何发现要爬取的网站的详细URL列表,并尽可能的发现。
假设场景 A
我们来看一个电商网站:打开首页--打开分类页面--可能有多个分类页面--逐层点击--直到最小的分类页面。
当你打开这个分类页面时,你会发现分类页面下的所有分页页面。如果一次向下滚动一页,则可以获取类别页面中的所有产品。
假设情景 B
我们去买车吧网站:打开首页——找到品牌页——然后找到车系——最后找到车型页。
通过以上场景分析,我们可以得出一个结论,人们可以非常智能的找到所有需要爬取的详细页面,即电商产品和车型页面。那么,是否可以通过配置来模拟这个过程呢?
请看下图:

备注如下:
1. 根信息:
定义发现模块的入口页面,就像人们打开公交车站的网页一样,后续的发现都是从这些入口页面开始的。
这里给出的例子是汽车网络的品牌列表页面,根据“模板化”应用变量的配置,总共有100个入口页面。
2. 步骤:
依次遍历这100个入口页面,分别执行steps中定义的步骤。查看和浏览机器模拟人类的方式。
每一步都使用“link_module”定义的类进行逻辑处理。
一种。读取入口页面的html,结合“sub_prefix”、“sub_suffix”和“select”定义的内容,获取页面子区域的html。
湾。使用“link_match_method”方法(包括前缀收录、匹配等)提取子区域的链接。
C。每个链接都匹配“link_pattern”,匹配成功的url进入下一步。
d。每一步得到的url都会自动转发到下一步处理。处理逻辑对上述ac递归,直到“last_step”为真。
这里,“last_step”为真时找到的url就是发现系统最终需要获取的url列表。发现系统总结,通过配置方法,结合人类的浏览习惯,经过数步迭代,最终得到网站的详细页面url列表。
由于每个步骤的提取链接规则和步骤数据都是手动定义的,因此可以适应网站的大部分发现系统。当然,越复杂的网站发现配置可能会越来越复杂,但同样如此。
(二)获取到url后如何处理
前提当然是每个业务的处理都不一样,包括提取页面属性、文本提取、图片获取,甚至与当前系统对接的功能。
由于业务处理不一致,自然会想到通过配置来定义责任链系统,就像著名框架Netty中的Pipeline设计一样。在处理的过程中,定义了一个Context上下文处理类,所有的中间结果都挂在这个Context中。
描述比较空洞,但还是以实际案例为准。

备注如下:
获取 url 后,读取配置并在 url 匹配“site”时应用当前的“site”规则。
1. pipeline 定义了责任链的处理
这里的定义是“爬取模块、Javascript处理模块、通用解析模块”。对应的处理如下:
先执行爬取模块获取html。然后执行Javascript处理模块,输入为html,解析html。这可能是评论或价格。简单来说就是先处理动态加载项目,再处理“通用解析模块”。
2. "parser_rules" 定义解析模块
最终的输出是kv,在java中是map,在python中是dict。即从上一步的html中,找到每个推荐的“sizzle”,执行“prefix”、“suffix”去掉前缀和后缀(过滤为“price:xxx元,前缀“price:”,后缀为元)。
顺便说一句,sizzle 也是一种开源技术。据说大名鼎鼎的Jquery也是一个“咝咝”的引擎。Java可以使用Jsoup解析处理。
你怎么知道要获取什么“嘶嘶作响”的内容?具体可以结合firebug插件,选择即可获得。选择后,可以结合应用层的管理工具进行测试。
3. “需要”
可以看到,配置项中有“isrequire”,表示是否需要这个内容。如果在实际处理中需要而无法获取,则在爬取过程中会记录错误,而错误的原因自然是“$key is null”。另外,每个模块都可能出错,一旦出错,以后就不需要再执行了。
因此,在爬取过程中,业务处理层从服务层获取一批url(默认为100个)后,处理完这100个url后,会上报给服务层,上报内容为:
当前任务处理机在什么时间处理100页。不同的网站有多少成功,有多少失败,有多少模块失败,解析模块中有多少字段失败。
所有这些信息都是实时统计的,并在运行监控系统中以图形方式绘制。必要时可发出警报,维修人员可实时介入。
Q:问个问题,如果我加了一个网站怎么办?
A:其实很简单,再增加一个配置就行了。业务定义管道。如果有解析需求,填写对应的解析项。
以上两个系统,发现系统和处理系统,在我们的实际生产中经过以下步骤运行。
一种。发现系统会累积发现要爬取的详细页面网站,因为它是一个累积和持续的过程。因此,您可以确保继续无限接近 网站 的 100% 页面。
湾。处理系统通过服务层获取配置信息(可能由维护人员实时修正)和待抓取列表进行处理。
待抓取的列表根据业务的优先级分为普通队列和优先级队列,通过任务调度系统统一管理和配置。
调度层
l 调度层主要是业务系统。
l 添加任务调度器网站
l 网站 发现频率,包括增量发现频率和完全发现频率
l 网站抢优先级被推入队列
l 断点续传管理
我...
四系统架构设计
l 从业务模块来看
应用层、服务层、业务处理层、调度层
l 从功能系统来看
发现系统、抓取系统、配置系统、监控系统
l 从可扩展性的角度
自定义责任链,自定义属性抽取
l 从实时角度
实时捕捉,实时配置有效,实时监控,实时测试
l 从系统架构来看
分布式架构,服务层主从切换设计,轻量级(只依赖队列、数据库、java)
五个传说
①

②

③

爬虫模块ui二(1.6任务配置):
定义每个爬虫任务的处理和执行责任链。不同的爬虫任务可以有不同的处理链。对于系统来说,处理每一个待爬取的url都会按照责任链的顺序执行。后处理类是在一批任务执行后(比如上面的100个url)进行批量提交的方法。比如文件登陆、存储、推送到线上系统等。通过定义任务处理,可以自定义各种场景的爬虫业务,增加系统的灵活性,无需编码。
④

属性配置:
如图,如果维护者添加了测试的url,定义了要提取的属性,就可以在线定义页面对应的属性输出,查看即可。在增加便利性和可测试性的基础上,可以灵活选择页面的任意属性。值得一提的是,sizzle的配置可以通过firefox插件获取。
⑤

1.9查看详情:
在爬虫系统运行过程中,几乎可以实时监控任务。由于爬虫任务将爬取状态实时写入数据库,因此可以通过ui界面进行管理和监控。1. 监控:监控当前时间爬虫任务成功数、错误数、什么模块出错,甚至是属性提取错误。2.管理:维护人员观察监控效果后,可以实时编辑管理(见上图),满足不同网站修改的需要。所有编辑实时生效。编辑后无需重启服务,可实时监控爬虫任务的最新效果。
高级建筑师
十余年数据研发经验,擅长数据处理,如爬虫、搜索引擎、大数据应用的高并发。历任架构师、研发经理等职务。曾主导开发大型爬虫、搜索引擎和大数据广告DMP系统。目前负责奇安科技数据平台的开发建设。
htmlunit抓取动态网页(模拟运行1.HTMLUNIT的基本功能分析工具展示 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2022-02-18 07:15
)
HTML单元
htmlunit 是一个开源的java页面分析工具。阅读完页面后,可以有效地使用htmlunit分析页面上的内容。该项目可以模拟浏览器的操作,称为java浏览器的开源实现。它是一个没有快速运行界面的浏览器。它是junit的扩展之一,使用Rhinojs引擎。模拟js运行
1. HTMLUNIT的基本功能展示
首先我们新建一个Maven普通客户端项目,然后打开pom.xml
引入 htmlunit 支持:
1
2 net.sourceforge.htmlunit
3 htmlunit
4 2.26
5
6
7
然后我们写一个测试类来解析获取网页html和网页文本,和httpClient类似,但是底层执行过程默认是js执行过程(当然htmlunit提供了关闭js解析的设置);
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
5import com.gargoylesoftware.htmlunit.WebClient;
6import com.gargoylesoftware.htmlunit.html.HtmlPage;
7
8public class HtmlUnitTest {
9
10 public static void main(String[] args) {
11 WebClient webClient=new WebClient(); // 实例化Web客户端
12 try {
13 HtmlPage page=webClient.getPage("http://www.baidu.com"); // 解析获取页面
14 System.out.println("网页html:"+page.asXml()); // 获取Html
15 System.out.println("====================");
16 System.out.println("网页文本:"+page.asText()); // 获取文本
17 } catch (FailingHttpStatusCodeException e) {
18 // TODO Auto-generated catch block
19 e.printStackTrace();
20 } catch (MalformedURLException e) {
21 // TODO Auto-generated catch block
22 e.printStackTrace();
23 } catch (IOException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }finally{
27 webClient.close(); // 关闭客户端,释放内存
28 }
29 }
30}
31
32
我们之前的测试代码是直接请求,有的网站服务器防火墙会直接拒绝访问。
我们现在使用htmlunit来模拟浏览器请求;主要是添加一些头信息;
这是我们用火狐调试工具看到的请求头中的属性,当然上面还有返回的头信息;
我们使用htmlunit来模拟浏览器执行,内置可以模拟IE、Firefox、Google;
WebClient构造函数中有一个重载方法,可以添加指定的版本属性;
完整代码:
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.HtmlPage;
8
9public class HtmlUnitTest {
10
11 public static void main(String[] args) {
12 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
13 try {
14 HtmlPage page=webClient.getPage("http://www.java1234.com"); // 解析获取页面
15 System.out.println("网页html:"+page.asXml()); // 获取Html
16 System.out.println("====================");
17 System.out.println("网页文本:"+page.asText()); // 获取文本
18 } catch (FailingHttpStatusCodeException e) {
19 // TODO Auto-generated catch block
20 e.printStackTrace();
21 } catch (MalformedURLException e) {
22 // TODO Auto-generated catch block
23 e.printStackTrace();
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }finally{
28 webClient.close(); // 关闭客户端,释放内存
29 }
30 }
31}
32
33
htmlunit提供了丰富的api来获取指定元素jsoup,有些htmlunit也有;
这里我们举一个例子:
<p>1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.DomElement;
8import com.gargoylesoftware.htmlunit.html.DomNodeList;
9import com.gargoylesoftware.htmlunit.html.HtmlDivision;
10import com.gargoylesoftware.htmlunit.html.HtmlListItem;
11import com.gargoylesoftware.htmlunit.html.HtmlPage;
12
13public class HtmlUnitTest2 {
14
15 public static void main(String[] args) {
16 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
17 try {
18 HtmlPage page=webClient.getPage("http://www.baidu.com");
19 HtmlDivision div=page.getHtmlElementById("navMenu"); // 查找指定id的html dom元素
20 System.out.println(div.asXml());
21 System.out.println("======================");
22 DomNodeList aList=page.getElementsByTagName("a"); // 根据tag名称查询所有tag
23 for(int i=0;i 查看全部
htmlunit抓取动态网页(模拟运行1.HTMLUNIT的基本功能分析工具展示
)
HTML单元
htmlunit 是一个开源的java页面分析工具。阅读完页面后,可以有效地使用htmlunit分析页面上的内容。该项目可以模拟浏览器的操作,称为java浏览器的开源实现。它是一个没有快速运行界面的浏览器。它是junit的扩展之一,使用Rhinojs引擎。模拟js运行
1. HTMLUNIT的基本功能展示
首先我们新建一个Maven普通客户端项目,然后打开pom.xml
引入 htmlunit 支持:
1
2 net.sourceforge.htmlunit
3 htmlunit
4 2.26
5
6
7
然后我们写一个测试类来解析获取网页html和网页文本,和httpClient类似,但是底层执行过程默认是js执行过程(当然htmlunit提供了关闭js解析的设置);
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
5import com.gargoylesoftware.htmlunit.WebClient;
6import com.gargoylesoftware.htmlunit.html.HtmlPage;
7
8public class HtmlUnitTest {
9
10 public static void main(String[] args) {
11 WebClient webClient=new WebClient(); // 实例化Web客户端
12 try {
13 HtmlPage page=webClient.getPage("http://www.baidu.com"); // 解析获取页面
14 System.out.println("网页html:"+page.asXml()); // 获取Html
15 System.out.println("====================");
16 System.out.println("网页文本:"+page.asText()); // 获取文本
17 } catch (FailingHttpStatusCodeException e) {
18 // TODO Auto-generated catch block
19 e.printStackTrace();
20 } catch (MalformedURLException e) {
21 // TODO Auto-generated catch block
22 e.printStackTrace();
23 } catch (IOException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }finally{
27 webClient.close(); // 关闭客户端,释放内存
28 }
29 }
30}
31
32
我们之前的测试代码是直接请求,有的网站服务器防火墙会直接拒绝访问。
我们现在使用htmlunit来模拟浏览器请求;主要是添加一些头信息;
这是我们用火狐调试工具看到的请求头中的属性,当然上面还有返回的头信息;
我们使用htmlunit来模拟浏览器执行,内置可以模拟IE、Firefox、Google;
WebClient构造函数中有一个重载方法,可以添加指定的版本属性;
完整代码:
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.HtmlPage;
8
9public class HtmlUnitTest {
10
11 public static void main(String[] args) {
12 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
13 try {
14 HtmlPage page=webClient.getPage("http://www.java1234.com"); // 解析获取页面
15 System.out.println("网页html:"+page.asXml()); // 获取Html
16 System.out.println("====================");
17 System.out.println("网页文本:"+page.asText()); // 获取文本
18 } catch (FailingHttpStatusCodeException e) {
19 // TODO Auto-generated catch block
20 e.printStackTrace();
21 } catch (MalformedURLException e) {
22 // TODO Auto-generated catch block
23 e.printStackTrace();
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }finally{
28 webClient.close(); // 关闭客户端,释放内存
29 }
30 }
31}
32
33
htmlunit提供了丰富的api来获取指定元素jsoup,有些htmlunit也有;
这里我们举一个例子:
<p>1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.DomElement;
8import com.gargoylesoftware.htmlunit.html.DomNodeList;
9import com.gargoylesoftware.htmlunit.html.HtmlDivision;
10import com.gargoylesoftware.htmlunit.html.HtmlListItem;
11import com.gargoylesoftware.htmlunit.html.HtmlPage;
12
13public class HtmlUnitTest2 {
14
15 public static void main(String[] args) {
16 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
17 try {
18 HtmlPage page=webClient.getPage("http://www.baidu.com");
19 HtmlDivision div=page.getHtmlElementById("navMenu"); // 查找指定id的html dom元素
20 System.out.println(div.asXml());
21 System.out.println("======================");
22 DomNodeList aList=page.getElementsByTagName("a"); // 根据tag名称查询所有tag
23 for(int i=0;i
htmlunit抓取动态网页(1.HtmlUnit中文文档获取页面中特定的元素tips:1.)
网站优化 • 优采云 发表了文章 • 0 个评论 • 117 次浏览 • 2022-02-18 07:14
1.HtmlUnit 简介
HtmlUnit 是一个 java 无界面浏览器库。它模拟 HTML 文档并提供相应的 API,允许您调用页面、填写表单、单击链接等,就像您在“普通”浏览器中所做的一样。它有相当不错的 JavaScript 支持(仍在改进),甚至能够处理相当复杂的 AJAX 库,根据使用的配置模拟 Chrome、Firefox 或 Internet Explorer。它通常用于测试目的或从 网站 检索信息。
HtmlUnit 不是一个通用的单元测试框架。它是一种模拟浏览器以进行测试的方法,旨在用于其他测试框架,例如 JUnit 或 TestNG。有关介绍,请参见文档“HtmlUnit 入门”。HtmlUnit 用作不同的开源工具,如 Canoo WebTest、JWebUnit、WebDriver、JSFUnit、WETATOR、Celerity、Spring MVC Test HtmlUnit 作为底层“浏览器”。
HtmlUnit 最初由 Gargoyle Software 的 Mike Bowler 编写,并在 Apache 2 许可下发布。从那时起,它收到了许多其他开发者的贡献,今天将得到他们的帮助。
几年前,我在为购物网站 做数据采集工作时偶然发现了HtmlUnit。记得当时页面上的价格数据是抓不到的,httpfox也无法追踪到价格数据的url。在我不知所措的时候,HtmlUnit出现了,帮我解决了问题。所以今天我要说声谢谢并向大家推荐HtmlUnit。
2.htmlUnit 中文文档
3.1 获取页面的TITLE、XML代码、文本
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//创建一个webclient
WebClient webClient = new WebClient();
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
//获取页面
HtmlPage page = webClient.getPage("http://www.baidu.com/");
//获取页面的TITLE
str = page.getTitleText();
System.out.println(str);
//获取页面的XML代码
str = page.asXml();
System.out.println(str);
//获取页面的文本
str = page.asText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}
3.2 用不同版本的浏览器打开
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//使用FireFox读取网页
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = webClient.getPage("http://www.baidu.com/");
str = page.getTitleText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}
3.3 在页面中查找特定元素
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//通过id获得"百度一下"按钮
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
System.out.println(btn.getDefaultValue());
//关闭webclient
webClient.closeAllWindows();
}
}
提示:有些元素没有 id 和 name 或其他节点。您可以通过查找其子节点和父节点之间的规律性来获取该元素。具体方法请参考:
它的核心代码是:
final HtmlPage nextPage = ((DomElement)(htmlpage.getElementByName("key").getParentNode().getParentNode())).getLastElementChild().click();
3.4 元素检索
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//查找所有div
List hbList = page.getByXPath("//div");
HtmlDivision hb = (HtmlDivision)hbList.get(0);
System.out.println(hb.toString());
//查找并获取特定input
List inputList = page.getByXPath("//input[@id='su']");
HtmlInput input = (HtmlInput)inputList.get(0);
System.out.println(input.toString());
//关闭webclient
webClient.closeAllWindows();
}
}
3.5 提交搜索
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//获取搜索输入框并提交搜索内容
HtmlInput input = (HtmlInput)page.getHtmlElementById("kw");
System.out.println(input.toString());
input.setValueAttribute("ymd");
System.out.println(input.toString());
//获取搜索按钮并点击
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
HtmlPage page2 = btn.click();
//输出新页面的文本
System.out.println(page2.asText());
}
}
3.htmlUnit方法介绍
一、环境介绍
因为我是在自己的spring boot项目中引入的,所以只需要在pom文件中添加依赖即可
net.sourceforge.htmlunit
htmlunit
2.41.0
如果只是爬一点js 网站 建议改一下下面的依赖
net.sourceforge.htmlunit
htmlunit
2.23
两者的区别将在后面讨论。当然,如果你用的不是maven项目(没有pom),可以去官网下载源码库
二、使用
HtmlUnit 使用起来非常简单。使用的时候可以去官网手册查看语法。其实说明书只是介绍,下面听我说就够了;
1、创建客户端并配置客户端
final String url ="https:****";//大家这可以填自己爬虫的地址
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_68);//创建火狐浏览器 2.23版本是FIREFOX_45 new不写参数是默认浏览器
webClient.getOptions().setCssEnabled(false);//(屏蔽)css 因为css并不影响我们抓取数据 反而影响网页渲染效率
webClient.getOptions().setThrowExceptionOnScriptError(false);//(屏蔽)异常
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//(屏蔽)日志
webClient.getOptions().setJavaScriptEnabled(true);//加载js脚本
webClient.getOptions().setTimeout(50000);//设置超时时间
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置ajax
HtmlPage htmlPage = webClient.getPage(url);//将客户端获取的树形结构转化为HtmlPage
Thread.sleep(10000);//主线程休眠10秒 让客户端有时间执行js代码 也可以写成webClient.waitForBackgroundJavaScript(1000)
有一个等待js执行,2.41.0非常兼容很多js,但是2.3总是有问题不能刷新网页,2. 41.0 打印也很详细,执行过程比较慢,可能是慢而细致。
远程地址页差不多就到这里了。我们现在要做的就是解析dom节点并填写数据来模拟点击等事件。如果要打印出来 htmlPage.asText() 输出 htmlPage 节点的文本 htmlPage.asXml() 输出 htmlPage 节点的 xml 代码
2、节点获取
在这个链接中,建议准备一点前端知识
HtmlUnit 提供了两种获取节点的方法
XPath 查询:
更详细的xpath解释:
final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net");
//get list of all divs
final List divs = htmlPage .getByXPath("//div");
//get div which has a 'name' attribute of 'John'
final HtmlDivision div = (HtmlDivision) htmlPage .getByXPath("//div[@name='John']").get(0);
css 选择器:(我更喜欢它)
final DomNodeList divs = htmlPage .querySelectorAll("div");
for (DomNode div : divs) {
....
}
//get div which has the id 'breadcrumbs'
final DomNode div = htmlPage .querySelector("div#breadcrumbs");
css给出了一个集合查询querySelectorAll和一个单一查询querySelector,如果你没有基础,我给你下面的例子来理解:
htmlPage.querySelectorAll("div") 返回 htmlPage 下面的 div 标签集合
htmlPage.querySelector("div:nth-child(1)") 返回htmlPage下面的div的第一个div
htmlPage .querySelector(".submit") 返回htmlPage下的第一个class=submit标签
htmlPage .querySelector("#submit") 返回htmlPage下id=submit的第一个标签
htmlPage.querySelector("div.submit") 返回htmlPage下第一个带有submit类的div标签
htmlPage.querySelector("div[id='submit']") 返回 htmlPage 下面的第一个 div 标签,id 为 submit
上面的枚举方式相信就够了,如果还不够,可以参考css选择器
下面列出了常见的html标签和HtmlUnit类的对应关系
div -> HtmlDivision
div集合 -> DomNodeList
fieldSet -> HtmlFieldSet
form -> HtmlForm
button -> HtmlButton
a -> HtmlAnchor
-> HtmlXxxInput
( -> HtmlTextInput)
table -> HtmlTable
tr -> HtmlTableRow
td -> TableDataCell
节点的属性样式有一个setAttribute()方法,setNodeValue()设置节点值。你的英语突然提高了吗?几乎所有的标签都能找到对应的类。来看看我的实战:这是一个在线填写温度的excel文档。如果你访问并更改地址,他会提示登录页面上有一个登录按钮。如果已经登录,页面上没有登录按钮登录按钮,我们现在模拟打开自动登录框:
//这段代码是为了让网页的的某个按钮加载出来之后再执行下面的代码
while (htmlPage.querySelector("#header-login-btn")==null) {
synchronized (htmlPage) {
htmlPage.wait(1000);
}
}
HtmlButton login = htmlPage.querySelector("#header-login-btn");//获取到登陆按钮
if (login!=null){//如果网页上没这个按钮你还要去获取他只会得到一个空对象,所以我们用空的方式可以判断网页上是否有这个按钮
System.out.println("-----未登录测试-----");
htmlPage=login.click();//模拟按钮点击后要将网页返回回来方便动态更新数据
System.out.println(htmlPage.asText());
HtmlAnchor switcher_plogin = htmlPage.querySelector("a[id='switcher_plogin']");
if (switcher_plogin!=null) {//帐号密码登录
System.out.println("-----点击了帐号密码登陆-----");
htmlPage = switcher_plogin.click();
System.out.println(htmlPage.asText());
}
}
System.out.println(htmlPage.asText());
webClient.close();
爬虫最重要的一步就是先调试网页,有哪些按钮,点击哪些,设置哪些值。毕竟,我们要用代码来调度代码。
**扩展:**如果要从网页中获取数据或下载文件,仅HtmlUnit解析是不够的。推荐使用Jsoup库,可以和HtmlUnit一起使用,比较好用,这里就不一一列举了。
三、实现一个小demo
注意:不是所有htmlunit引用的jar包都会报奇怪的错误
使用maven方法更方便
参考: 查看全部
htmlunit抓取动态网页(1.HtmlUnit中文文档获取页面中特定的元素tips:1.)
1.HtmlUnit 简介
HtmlUnit 是一个 java 无界面浏览器库。它模拟 HTML 文档并提供相应的 API,允许您调用页面、填写表单、单击链接等,就像您在“普通”浏览器中所做的一样。它有相当不错的 JavaScript 支持(仍在改进),甚至能够处理相当复杂的 AJAX 库,根据使用的配置模拟 Chrome、Firefox 或 Internet Explorer。它通常用于测试目的或从 网站 检索信息。
HtmlUnit 不是一个通用的单元测试框架。它是一种模拟浏览器以进行测试的方法,旨在用于其他测试框架,例如 JUnit 或 TestNG。有关介绍,请参见文档“HtmlUnit 入门”。HtmlUnit 用作不同的开源工具,如 Canoo WebTest、JWebUnit、WebDriver、JSFUnit、WETATOR、Celerity、Spring MVC Test HtmlUnit 作为底层“浏览器”。
HtmlUnit 最初由 Gargoyle Software 的 Mike Bowler 编写,并在 Apache 2 许可下发布。从那时起,它收到了许多其他开发者的贡献,今天将得到他们的帮助。
几年前,我在为购物网站 做数据采集工作时偶然发现了HtmlUnit。记得当时页面上的价格数据是抓不到的,httpfox也无法追踪到价格数据的url。在我不知所措的时候,HtmlUnit出现了,帮我解决了问题。所以今天我要说声谢谢并向大家推荐HtmlUnit。
2.htmlUnit 中文文档
3.1 获取页面的TITLE、XML代码、文本

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//创建一个webclient
WebClient webClient = new WebClient();
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
//获取页面
HtmlPage page = webClient.getPage("http://www.baidu.com/");
//获取页面的TITLE
str = page.getTitleText();
System.out.println(str);
//获取页面的XML代码
str = page.asXml();
System.out.println(str);
//获取页面的文本
str = page.asText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}

3.2 用不同版本的浏览器打开

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//使用FireFox读取网页
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = webClient.getPage("http://www.baidu.com/");
str = page.getTitleText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}

3.3 在页面中查找特定元素
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//通过id获得"百度一下"按钮
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
System.out.println(btn.getDefaultValue());
//关闭webclient
webClient.closeAllWindows();
}
}
提示:有些元素没有 id 和 name 或其他节点。您可以通过查找其子节点和父节点之间的规律性来获取该元素。具体方法请参考:
它的核心代码是:
final HtmlPage nextPage = ((DomElement)(htmlpage.getElementByName("key").getParentNode().getParentNode())).getLastElementChild().click();
3.4 元素检索

public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//查找所有div
List hbList = page.getByXPath("//div");
HtmlDivision hb = (HtmlDivision)hbList.get(0);
System.out.println(hb.toString());
//查找并获取特定input
List inputList = page.getByXPath("//input[@id='su']");
HtmlInput input = (HtmlInput)inputList.get(0);
System.out.println(input.toString());
//关闭webclient
webClient.closeAllWindows();
}
}

3.5 提交搜索

public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//获取搜索输入框并提交搜索内容
HtmlInput input = (HtmlInput)page.getHtmlElementById("kw");
System.out.println(input.toString());
input.setValueAttribute("ymd");
System.out.println(input.toString());
//获取搜索按钮并点击
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
HtmlPage page2 = btn.click();
//输出新页面的文本
System.out.println(page2.asText());
}
}

3.htmlUnit方法介绍
一、环境介绍
因为我是在自己的spring boot项目中引入的,所以只需要在pom文件中添加依赖即可
net.sourceforge.htmlunit
htmlunit
2.41.0
如果只是爬一点js 网站 建议改一下下面的依赖
net.sourceforge.htmlunit
htmlunit
2.23
两者的区别将在后面讨论。当然,如果你用的不是maven项目(没有pom),可以去官网下载源码库
二、使用
HtmlUnit 使用起来非常简单。使用的时候可以去官网手册查看语法。其实说明书只是介绍,下面听我说就够了;
1、创建客户端并配置客户端
final String url ="https:****";//大家这可以填自己爬虫的地址
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_68);//创建火狐浏览器 2.23版本是FIREFOX_45 new不写参数是默认浏览器
webClient.getOptions().setCssEnabled(false);//(屏蔽)css 因为css并不影响我们抓取数据 反而影响网页渲染效率
webClient.getOptions().setThrowExceptionOnScriptError(false);//(屏蔽)异常
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//(屏蔽)日志
webClient.getOptions().setJavaScriptEnabled(true);//加载js脚本
webClient.getOptions().setTimeout(50000);//设置超时时间
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置ajax
HtmlPage htmlPage = webClient.getPage(url);//将客户端获取的树形结构转化为HtmlPage
Thread.sleep(10000);//主线程休眠10秒 让客户端有时间执行js代码 也可以写成webClient.waitForBackgroundJavaScript(1000)
有一个等待js执行,2.41.0非常兼容很多js,但是2.3总是有问题不能刷新网页,2. 41.0 打印也很详细,执行过程比较慢,可能是慢而细致。
远程地址页差不多就到这里了。我们现在要做的就是解析dom节点并填写数据来模拟点击等事件。如果要打印出来 htmlPage.asText() 输出 htmlPage 节点的文本 htmlPage.asXml() 输出 htmlPage 节点的 xml 代码
2、节点获取
在这个链接中,建议准备一点前端知识
HtmlUnit 提供了两种获取节点的方法
XPath 查询:
更详细的xpath解释:
final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net");
//get list of all divs
final List divs = htmlPage .getByXPath("//div");
//get div which has a 'name' attribute of 'John'
final HtmlDivision div = (HtmlDivision) htmlPage .getByXPath("//div[@name='John']").get(0);
css 选择器:(我更喜欢它)
final DomNodeList divs = htmlPage .querySelectorAll("div");
for (DomNode div : divs) {
....
}
//get div which has the id 'breadcrumbs'
final DomNode div = htmlPage .querySelector("div#breadcrumbs");
css给出了一个集合查询querySelectorAll和一个单一查询querySelector,如果你没有基础,我给你下面的例子来理解:
htmlPage.querySelectorAll("div") 返回 htmlPage 下面的 div 标签集合
htmlPage.querySelector("div:nth-child(1)") 返回htmlPage下面的div的第一个div
htmlPage .querySelector(".submit") 返回htmlPage下的第一个class=submit标签
htmlPage .querySelector("#submit") 返回htmlPage下id=submit的第一个标签
htmlPage.querySelector("div.submit") 返回htmlPage下第一个带有submit类的div标签
htmlPage.querySelector("div[id='submit']") 返回 htmlPage 下面的第一个 div 标签,id 为 submit
上面的枚举方式相信就够了,如果还不够,可以参考css选择器
下面列出了常见的html标签和HtmlUnit类的对应关系
div -> HtmlDivision
div集合 -> DomNodeList
fieldSet -> HtmlFieldSet
form -> HtmlForm
button -> HtmlButton
a -> HtmlAnchor
-> HtmlXxxInput
( -> HtmlTextInput)
table -> HtmlTable
tr -> HtmlTableRow
td -> TableDataCell
节点的属性样式有一个setAttribute()方法,setNodeValue()设置节点值。你的英语突然提高了吗?几乎所有的标签都能找到对应的类。来看看我的实战:这是一个在线填写温度的excel文档。如果你访问并更改地址,他会提示登录页面上有一个登录按钮。如果已经登录,页面上没有登录按钮登录按钮,我们现在模拟打开自动登录框:
//这段代码是为了让网页的的某个按钮加载出来之后再执行下面的代码
while (htmlPage.querySelector("#header-login-btn")==null) {
synchronized (htmlPage) {
htmlPage.wait(1000);
}
}
HtmlButton login = htmlPage.querySelector("#header-login-btn");//获取到登陆按钮
if (login!=null){//如果网页上没这个按钮你还要去获取他只会得到一个空对象,所以我们用空的方式可以判断网页上是否有这个按钮
System.out.println("-----未登录测试-----");
htmlPage=login.click();//模拟按钮点击后要将网页返回回来方便动态更新数据
System.out.println(htmlPage.asText());
HtmlAnchor switcher_plogin = htmlPage.querySelector("a[id='switcher_plogin']");
if (switcher_plogin!=null) {//帐号密码登录
System.out.println("-----点击了帐号密码登陆-----");
htmlPage = switcher_plogin.click();
System.out.println(htmlPage.asText());
}
}
System.out.println(htmlPage.asText());
webClient.close();
爬虫最重要的一步就是先调试网页,有哪些按钮,点击哪些,设置哪些值。毕竟,我们要用代码来调度代码。
**扩展:**如果要从网页中获取数据或下载文件,仅HtmlUnit解析是不够的。推荐使用Jsoup库,可以和HtmlUnit一起使用,比较好用,这里就不一一列举了。
三、实现一个小demo
注意:不是所有htmlunit引用的jar包都会报奇怪的错误
使用maven方法更方便
参考:
htmlunit抓取动态网页(爬取一个动态网页刷新问题,解决方案如下思路使用 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 114 次浏览 • 2022-02-18 07:01
)
更新。. . . . 这个动态网页其实可以直接抓取ajax请求。这很简单。之前觉得很复杂 虽然也实现了,效率极低,不过没关系。这是对 Selenium 的学习。
1.我最近在爬动态网页。为了更新页面,需要选择不同的选项,即处理下拉框。这里的下拉框是一个假的通过输入实现的下拉框,但是他还有一个隐藏的选择,我原本以为隐藏的选择会用js脚本修改变为可见,然后点击等操作,但是使用网上的方法后,发现选择可见可见,但是点击后没有效果,各方搜索无果,最后决定自己解决这个问题,解决方法如下
想法用selenium完全模拟人类操作,一步一步点击可见按钮
, 1、找到下拉框按钮,点击,
二、点击下拉框按钮后,会出现一个列表,在列表中定位一个元素,点击。注意这一步必须在下拉框按钮被点击后进行(使用time.sleep()等待几秒,否则会提示点击的内容不存在)
通过这两步,我们可以改变动态网页的信息,代码如下
def getButton(browser):
# 获取下拉框按钮
Button = browser.find_elements_by_class_name("textbox-icon") # 定位哪一栋楼按钮
buildButton = Button[0]
floorButton = Button[1]
buildingsAndFloors = browser.find_elements_by_class_name("combobox-item") # 楼选项
floors = buildingsAndFloors[30:]
buildings = buildingsAndFloors[:30]
info = dict()
info['floors'] = floors
info['buildings'] = buildings
info['buildButton'] = buildButton
info['floorButton'] = floorButton
return info
2.另外,在爬取的时候,经常会提示点击按钮或者不存在的东西,所以一定要设置延迟。
3.某些动态网页的源代码与您在使用 f12 的网页上看到的不同。我的解决方法是先对网页进行操作,然后获取源码,就正常了
4.动态网页存在不断刷新的问题,但是每次刷新后都会提示旧元素不能使用,所以必须重新获取不能使用的信息,如下,getButton( )函数获取Button信息,每次页面刷新后需要点击按钮时再次获取。
# 获取某一栋楼某一层的信息所对应页面的源代码
def getSoup(buildNumber, floor):
info = getButton(browser)
info['buildButton'].click() # 点击指定楼
info['buildings'][buildNumber].click()
time.sleep(1)
info = getButton(browser) # 重新获取信息
time.sleep(1)
info['floorButton'].click() # 点击指定楼层
info['floors'][floor].click()
soup = BeautifulSoup(browser.page_source, 'html.parser')
return soup 查看全部
htmlunit抓取动态网页(爬取一个动态网页刷新问题,解决方案如下思路使用
)
更新。. . . . 这个动态网页其实可以直接抓取ajax请求。这很简单。之前觉得很复杂 虽然也实现了,效率极低,不过没关系。这是对 Selenium 的学习。
1.我最近在爬动态网页。为了更新页面,需要选择不同的选项,即处理下拉框。这里的下拉框是一个假的通过输入实现的下拉框,但是他还有一个隐藏的选择,我原本以为隐藏的选择会用js脚本修改变为可见,然后点击等操作,但是使用网上的方法后,发现选择可见可见,但是点击后没有效果,各方搜索无果,最后决定自己解决这个问题,解决方法如下
想法用selenium完全模拟人类操作,一步一步点击可见按钮
, 1、找到下拉框按钮,点击,
二、点击下拉框按钮后,会出现一个列表,在列表中定位一个元素,点击。注意这一步必须在下拉框按钮被点击后进行(使用time.sleep()等待几秒,否则会提示点击的内容不存在)
通过这两步,我们可以改变动态网页的信息,代码如下
def getButton(browser):
# 获取下拉框按钮
Button = browser.find_elements_by_class_name("textbox-icon") # 定位哪一栋楼按钮
buildButton = Button[0]
floorButton = Button[1]
buildingsAndFloors = browser.find_elements_by_class_name("combobox-item") # 楼选项
floors = buildingsAndFloors[30:]
buildings = buildingsAndFloors[:30]
info = dict()
info['floors'] = floors
info['buildings'] = buildings
info['buildButton'] = buildButton
info['floorButton'] = floorButton
return info

2.另外,在爬取的时候,经常会提示点击按钮或者不存在的东西,所以一定要设置延迟。
3.某些动态网页的源代码与您在使用 f12 的网页上看到的不同。我的解决方法是先对网页进行操作,然后获取源码,就正常了
4.动态网页存在不断刷新的问题,但是每次刷新后都会提示旧元素不能使用,所以必须重新获取不能使用的信息,如下,getButton( )函数获取Button信息,每次页面刷新后需要点击按钮时再次获取。
# 获取某一栋楼某一层的信息所对应页面的源代码
def getSoup(buildNumber, floor):
info = getButton(browser)
info['buildButton'].click() # 点击指定楼
info['buildings'][buildNumber].click()
time.sleep(1)
info = getButton(browser) # 重新获取信息
time.sleep(1)
info['floorButton'].click() # 点击指定楼层
info['floors'][floor].click()
soup = BeautifulSoup(browser.page_source, 'html.parser')
return soup
htmlunit抓取动态网页(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
网站优化 • 优采云 发表了文章 • 0 个评论 • 74 次浏览 • 2022-02-15 21:20
由于其他项目组都在做舆情预测项目,我只是手头没有项目,突然心血来潮想研究一个简单的爬虫原型和分析。网上这方面的资料很多,看得我眼花缭乱。对于我这样的新手,想做一个简单的爬虫程序,所以HttpClient + jsoup是个不错的选择。前者是用来管理请求的,后者是用来解析页面的,主要是后者的select语法和jquery很像,对我这个用js的人来说太方便了。
昨天和他们聊天时,他们使用了几个知名的开源框架。聊了几句,他们发现自己根本无法爬取动态网页,尤其是一些重要的数字,比如评论数和回复数。等等我有一个大致的了解。比如TRS的爬虫需要为js调用编写js脚本,但分析量巨大。他们的技术人员告诉我们,如果他们匹配这样的模板,他们每天只能匹配2到3个。,更何况我们这些中途修士。碰巧是一个相当大的挑战,所以我昨天答应他们,看看他们是否能找到一个相对简单的解决方案,当然,不管效率如何。
举个简单的例子,如下图
“我有话要说”后面的1307是后载的,但这些数字往往对舆情分析更重要。
对需求有了大致的了解后,我们来分析如何解决它们。通常我们得到的一个请求的响应收录js代码和html元素,所以像jsoup这样的html解析器很难在这里利用,因为它所能得到的html,1307还没有生成。这时候就需要一个可以运行js的平台,运行js代码后的页面会被html解析,这样才能正确得到结果。
因为懒,一开始写脚本的方式被我抛弃了,因为分析一个页面太痛苦了,代码乱成一锅粥。看的太累了。所以我的首要任务是,为什么我不能让这个地址在某个浏览器中运行,然后将运行结果交给html解析器解析,那么整个问题就解决了。这样,我的临时解决方案是在爬虫服务器上打开一个后台浏览器,或者是有浏览器内核的程序,把url地址交给它去请求,然后从浏览器中取出页面的元素给它到 html 解析器进行解析以获取您想要的信息。
没错,最后我还是用 Selenium 来实现我在上一篇文章中提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果我还是可以接受的。
继续昨天的话题,既然我们要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的首选是htmlunit,先简单介绍一下htmlunit。以下段落摘自互联网。
htmlunit 是一个开源的java页面分析工具。启动htmlunit后,会在底层启动一个非界面浏览器。用户可以指定浏览器类型:firefox、ie等,不指定则默认使用INTERNET_EXPLORER_7:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
只需调用:
HtmlPage 页面 = webClient.getPage(url);
可以获取页面的 HtmlPage 表示,然后通过:
InputStream 是 = targetPage.getWebResponse().getContentAsStream()
可以获取页面的输入流,从而获取页面的源代码,对于网络爬虫项目非常有用。
当然,你也可以从page中获取更多的页面元素。
重要的是,HtmlUnit 提供对执行 javascript 的支持:
page.executeJavaScript(javascript)
执行js后,返回一个ScriptResult对象,通过该对象可以获取执行js后的页面等信息。默认情况下,执行完js后,内部浏览器会进行页面跳转,跳转到执行完js后生成的新页面。如果js执行失败,则不会执行页面跳转。
最后可以通过page.executeJavaScript(javascript).getNewPage()获取执行的页面。也就是说,这里需要人为地执行javascript,这显然不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻的页面时总是出错。根据网络上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数顺序或者编码问题,请求失败,报错。关键是,运行它后我没有得到我需要的结果。
然后我寻找另一种解决方案。这时,我找到了 SeleniumWebDriver,这是我需要的解决方案。
参考资料和例子,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn");
11 list.add("http://www.sohu.com");
12 list.add("http://www.163.com");
13 list.add("http://www.qq.com");
14
15 long start,end;
16
17 for(int i=0;i 查看全部
htmlunit抓取动态网页(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
由于其他项目组都在做舆情预测项目,我只是手头没有项目,突然心血来潮想研究一个简单的爬虫原型和分析。网上这方面的资料很多,看得我眼花缭乱。对于我这样的新手,想做一个简单的爬虫程序,所以HttpClient + jsoup是个不错的选择。前者是用来管理请求的,后者是用来解析页面的,主要是后者的select语法和jquery很像,对我这个用js的人来说太方便了。
昨天和他们聊天时,他们使用了几个知名的开源框架。聊了几句,他们发现自己根本无法爬取动态网页,尤其是一些重要的数字,比如评论数和回复数。等等我有一个大致的了解。比如TRS的爬虫需要为js调用编写js脚本,但分析量巨大。他们的技术人员告诉我们,如果他们匹配这样的模板,他们每天只能匹配2到3个。,更何况我们这些中途修士。碰巧是一个相当大的挑战,所以我昨天答应他们,看看他们是否能找到一个相对简单的解决方案,当然,不管效率如何。
举个简单的例子,如下图
“我有话要说”后面的1307是后载的,但这些数字往往对舆情分析更重要。
对需求有了大致的了解后,我们来分析如何解决它们。通常我们得到的一个请求的响应收录js代码和html元素,所以像jsoup这样的html解析器很难在这里利用,因为它所能得到的html,1307还没有生成。这时候就需要一个可以运行js的平台,运行js代码后的页面会被html解析,这样才能正确得到结果。
因为懒,一开始写脚本的方式被我抛弃了,因为分析一个页面太痛苦了,代码乱成一锅粥。看的太累了。所以我的首要任务是,为什么我不能让这个地址在某个浏览器中运行,然后将运行结果交给html解析器解析,那么整个问题就解决了。这样,我的临时解决方案是在爬虫服务器上打开一个后台浏览器,或者是有浏览器内核的程序,把url地址交给它去请求,然后从浏览器中取出页面的元素给它到 html 解析器进行解析以获取您想要的信息。
没错,最后我还是用 Selenium 来实现我在上一篇文章中提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果我还是可以接受的。
继续昨天的话题,既然我们要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的首选是htmlunit,先简单介绍一下htmlunit。以下段落摘自互联网。
htmlunit 是一个开源的java页面分析工具。启动htmlunit后,会在底层启动一个非界面浏览器。用户可以指定浏览器类型:firefox、ie等,不指定则默认使用INTERNET_EXPLORER_7:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
只需调用:
HtmlPage 页面 = webClient.getPage(url);
可以获取页面的 HtmlPage 表示,然后通过:
InputStream 是 = targetPage.getWebResponse().getContentAsStream()
可以获取页面的输入流,从而获取页面的源代码,对于网络爬虫项目非常有用。
当然,你也可以从page中获取更多的页面元素。
重要的是,HtmlUnit 提供对执行 javascript 的支持:
page.executeJavaScript(javascript)
执行js后,返回一个ScriptResult对象,通过该对象可以获取执行js后的页面等信息。默认情况下,执行完js后,内部浏览器会进行页面跳转,跳转到执行完js后生成的新页面。如果js执行失败,则不会执行页面跳转。
最后可以通过page.executeJavaScript(javascript).getNewPage()获取执行的页面。也就是说,这里需要人为地执行javascript,这显然不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻的页面时总是出错。根据网络上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数顺序或者编码问题,请求失败,报错。关键是,运行它后我没有得到我需要的结果。
然后我寻找另一种解决方案。这时,我找到了 SeleniumWebDriver,这是我需要的解决方案。
参考资料和例子,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn");
11 list.add("http://www.sohu.com");
12 list.add("http://www.163.com");
13 list.add("http://www.qq.com");
14
15 long start,end;
16
17 for(int i=0;i
htmlunit抓取动态网页(分享一种解决方案,代码以及部分截图不方便贴出,请谅解!)
网站优化 • 优采云 发表了文章 • 0 个评论 • 88 次浏览 • 2022-02-15 06:15
说明:只是分享一个解决方案,代码和部分截图不便贴,请谅解!
前段时间,我一直在研究爬虫来爬取网络上的特定数据。如果只是一个静态网页,那就很简单了。直接使用Jsoup:
Document doc = Jsoup.connect(url).timeout(2000).get();
获取Document然后为所欲为,但是一旦遇到一些动态生成的网站就不行了,因为数据是页面加载完成后执行js代码加载的,或者是用户滑动触发的浏览js加载数据,这样的网页使用Jsoup显然无法获取到想要的数据。
后来用Selenium获取动态网页的数据,可以成功获取到数据(实现方法),程序打包在一台机器上运行,开始测试,然后结果不太理想,并且经常出现内存溢出,或者浏览器升级导致驱动和浏览器版本不匹配等一系列问题。今天早上来到公司,发现程序又被炸了。半夜没人动机器,鼠标键盘都失灵了,只好重启,不说是什么问题,所以测试修改测试太麻烦,所以决定放弃用Selenium,稳定性太差,我考虑用htmlunit等但是那些工具效果不是很好,
首先,动态网页,既然是动态的,肯定是在浏览器加载网页后,向服务器发送了网络请求。如果我得到网络请求的url,模拟参数,自己发送请求,解析数据是不是更好,然后开始工作:
抓包工具:fiddle
不懂fiddle的,建议百度学习一下
安装好后打开fiddle,打开浏览器,打开目标url,然后就可以看到fiddle中打开这个网页的所有网络请求了:
我不会在这里发图片,我怕人家惹我。. . .
然后就是一一查看网络请求:
先看左边的图标,直接略过图,显然我们需要的是数据,重点关注文本格式的请求,然后右键copy->just url 把url复制到浏览器看看可以get,最后找到18行的request就是数据接口,可以直接获取数据,而且是json格式!!!!!!!!
真的很爽,直接json就行了,剩下的就简单了,解析数据。. . . . . . . 略略。. . . . . 话不多说,继续敲代码,这里只是分享一个解析动态网页的方法,欢迎在此发表评论,一起讨论,寻找更好的解决问题的方法!
2016-11-07
迦南香 查看全部
htmlunit抓取动态网页(分享一种解决方案,代码以及部分截图不方便贴出,请谅解!)
说明:只是分享一个解决方案,代码和部分截图不便贴,请谅解!
前段时间,我一直在研究爬虫来爬取网络上的特定数据。如果只是一个静态网页,那就很简单了。直接使用Jsoup:
Document doc = Jsoup.connect(url).timeout(2000).get();
获取Document然后为所欲为,但是一旦遇到一些动态生成的网站就不行了,因为数据是页面加载完成后执行js代码加载的,或者是用户滑动触发的浏览js加载数据,这样的网页使用Jsoup显然无法获取到想要的数据。
后来用Selenium获取动态网页的数据,可以成功获取到数据(实现方法),程序打包在一台机器上运行,开始测试,然后结果不太理想,并且经常出现内存溢出,或者浏览器升级导致驱动和浏览器版本不匹配等一系列问题。今天早上来到公司,发现程序又被炸了。半夜没人动机器,鼠标键盘都失灵了,只好重启,不说是什么问题,所以测试修改测试太麻烦,所以决定放弃用Selenium,稳定性太差,我考虑用htmlunit等但是那些工具效果不是很好,
首先,动态网页,既然是动态的,肯定是在浏览器加载网页后,向服务器发送了网络请求。如果我得到网络请求的url,模拟参数,自己发送请求,解析数据是不是更好,然后开始工作:
抓包工具:fiddle
不懂fiddle的,建议百度学习一下
安装好后打开fiddle,打开浏览器,打开目标url,然后就可以看到fiddle中打开这个网页的所有网络请求了:
我不会在这里发图片,我怕人家惹我。. . .
然后就是一一查看网络请求:
先看左边的图标,直接略过图,显然我们需要的是数据,重点关注文本格式的请求,然后右键copy->just url 把url复制到浏览器看看可以get,最后找到18行的request就是数据接口,可以直接获取数据,而且是json格式!!!!!!!!
真的很爽,直接json就行了,剩下的就简单了,解析数据。. . . . . . . 略略。. . . . . 话不多说,继续敲代码,这里只是分享一个解析动态网页的方法,欢迎在此发表评论,一起讨论,寻找更好的解决问题的方法!
2016-11-07
迦南香
htmlunit抓取动态网页(Web网络爬虫系统的原理及应用)
网站优化 • 优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-02-15 06:12
1、爬虫技术概述
网络爬虫是根据一定的规则自动从万维网上爬取信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,它可以自动采集它可以访问的所有页面获取或更新这些网站的内容和检索方法。从功能上来说,爬虫一般分为数据采集、处理、存储三部分。传统爬虫从一个或多个初始网页的URL开始,获取初始网页上的URL。在抓取网页的过程中,它不断地从当前页面中提取新的 URL 并放入队列中,直到满足系统的某些停止条件。焦点爬虫的工作流程比较复杂。它需要按照一定的网页分析算法过滤掉与主题无关的链接,保留有用的链接,并放入等待抓取的URL队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。
与通用网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
(1) 获取目标的描述或定义;
(2) 网页或数据的分析和过滤;
(3) URL 的搜索策略。
2、爬虫原理
2.1 网络爬虫原理
网络爬虫系统的功能是下载网页数据,为搜索引擎系统提供数据源。许多大型网络搜索引擎系统被称为基于Web数据的搜索引擎系统采集,如Google、百度等。这显示了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文字信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程像爬虫或者蜘蛛一样在网络上漫游,所以才叫做网络爬虫系统或者网络蜘蛛系统,英文叫Spider或者Crawler。
2.2 网络爬虫系统的工作原理
在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多个线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页和处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等。爬虫的基本工作是由解析器完成的。资源库用于存储下载的网络资源。通常使用大型数据库,例如 Oracle 数据库来存储和索引它。
控制器
控制器是网络爬虫的中央控制器。主要负责根据系统发送的URL链接分配一个线程,然后启动线程调用爬虫爬取网页。
解析器
解析器负责网络爬虫的主要部分。它的主要任务是:下载网页的功能,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
资源库
它主要是一个容器,用于存储从网页下载的数据记录,并为索引生成提供目标源。大中型数据库产品包括:Oracle、Sql Server等。
网络爬虫系统一般会选择一些比较重要的出度(网页中超链接数)网站较大的URL作为种子URL集。网络爬虫系统使用这些种子集作为初始 URL 来开始数据爬取。因为网页中收录链接信息,所以会通过已有网页的URL获取一些新的URL。网页之间的指向结构可以看作是一片森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能导致爬虫系统陷入网站内部,不利于搜索距离网站首页比较近的网页信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。
网络爬虫的基本工作流程如下:
1.首先选择一个精心挑选的种子 URL 的子集;
2.将这些网址放入待抓取的网址队列中;
3. 从待爬取URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页,存入下载的网页库中。此外,将这些 URL 放入 Crawl URL 队列。
4.分析已经爬取的URL队列中的URL,分析其中的其他URL,将这些URL放入待爬取的URL队列,从而进入下一个循环。
2.3 爬取策略
在爬虫系统中,待爬取的 URL 队列是一个重要的部分。待爬取的URL队列中的URL的排列顺序也是一个重要的问题,因为它涉及到先爬到哪个页面,再爬到哪个页面。确定这些 URL 排列顺序的方法称为爬取策略。下面重点介绍几种常见的爬取策略:
2.3.1 深度优先遍历策略
深度优先遍历策略是指网络爬虫会从起始页开始,每次一个链接跟踪每个链接,处理完该行后移动到下一个起始页,并继续跟踪该链接。我们以下图为例:
遍历的路径:AFG EHI BCD
2.3.2 广度优先遍历策略
广度优先遍历的基本思想是将新下载的网页中找到的链接直接插入待爬取URL队列的末尾。也就是说,网络爬虫会先爬取起始网页链接的所有网页,然后选择其中一个链接的网页,继续爬取该网页链接的所有网页。或者以上图为例:
遍历路径:ABCDEF GHI
2.3.3 反向链接策略
反向链接数是指从其他网页指向一个网页的链接数。反向链接的数量表示网页内容被他人推荐的程度。因此,在很多情况下,搜索引擎的爬取系统会使用这个指标来评估网页的重要性,从而确定不同网页的爬取顺序。
在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量并不能完全等同于他人的重要性。因此,搜索引擎倾向于考虑一些可靠的反向链接计数。
2.3.4部分PageRank策略
Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,与待爬取的URL队列中的URL一起形成一组网页,计算每个页面的PageRank值. URL 按 PageRank 值排序,并按该顺序抓取页面。
如果每次爬取一个页面都重新计算一次PageRank值,一个折中的方案是每次爬取K个页面都重新计算一次PageRank值。但是这种情况还是有一个问题:对于下载页面中分析的链接,也就是我们前面提到的那部分未知网页,暂时没有PageRank值。为了解决这个问题,给这些页面一个临时的PageRank值:把这个网页的所有传入链接传入的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排序. 以下示例说明:
2.3.5OPICStrategy
该算法实际上为页面分配了一个重要性分数。在算法开始之前,所有页面都会获得相同的初始现金。当某个页面P被下载时,P的现金分配给从P分析的所有链接,P的现金被清空。根据现金数量对待爬取URL队列中的所有页面进行排序。
2.3.六大网站优先策略
所有待爬取的URL队列中的网页都按照它们所属的网站进行分类。网站需要下载的页面较多,请先下载。这种策略也称为大站点优先策略。
3、爬虫分类
我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫类,基本上可以分为三类:
(1)分布式爬虫:Nutch
(2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
(3)非JAVA爬虫:scrapy(基于Python语言开发)
3.1 分布式爬虫
爬虫使用分布式,主要解决两个问题:
1)海量网址管理
2)网速
现在比较流行的分布式爬虫是Apache的Nutch。但是对于大多数用户来说,Nutch 是这些爬虫中最差的选择,原因如下:
1)Nutch 是为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的三分之二的流程是为搜索引擎设计的。提取意义不大。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发让Nutch适合提取业务,那你基本上会破坏Nutch的框架,把Nutch改得面目全非,而且有能力修改Nutch,还不如自己写一个新的。分布式爬虫框架。
2)Nutch 依赖hadoop 运行,hadoop 本身消耗大量时间。如果集群机器数量少,爬取速度不如单机爬虫快。
3)虽然Nutch有一套插件机制,但还是作为亮点来宣传的。可以看到一些开源的Nutch插件,提供精准提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多糟糕。使用反射机制加载和调用插件,使得程序的编写和调试变得异常困难,更不用说在其上开发复杂的提取系统了。并且 Nutch 没有提供对应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点都是给搜索引擎服务的,不提供细提取的挂载点。Nutch 的大部分精炼提取插件都挂载在“页面解析”(parser)挂载点上。这个挂载点其实是用来解析链接(为后续爬取提供URL)和提供一些搜索引擎的。易于提取的网页信息(元信息、网页文本)。
4)使用Nutch进行爬虫的二次开发,编写和调试爬虫所需的时间往往是单机爬虫所需时间的十倍以上。学习 Nutch 源码的成本非常高,更何况团队中的每个人都必须了解 Nutch 源码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
5)很多人说Nutch2有gora,可以把数据持久化到avro文件、hbase、mysql等,其实很多人都搞错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
6)Nutch2 的版本目前不适合开发。Nutch的官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果要使用hbase和nutch(大多数人使用nutch2是为了使用hbase),只能使用版本0.90左右的hbase,相应地,将hadoop版本降低到hadoop 0.左右@>2。而且nutch2的官方教程也颇具误导性。Nutch2的教程有两个,分别是Nutch1.x和Nutch2.x。Nutch2.x官网是为了支持hbase0.94而写的。但其实这个Nutch2.x是指Nutch2.3之前和Nutch2.2.1之后的一个版本,在官方SVN中不断更新。而且它'
所以,如果你不是搜索引擎,尽量不要选择 Nutch 作为爬虫。一些团队喜欢跟风。他们坚持选择Nutch来开发精制履带。其实是针对Nutch的名声(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目延期。
如果你在做搜索引擎,Nutch1.x 是一个非常不错的选择。Nutch1.x 和 solr 或 es 可以组成一个非常强大的搜索引擎。如果必须使用 Nutch2,建议等到 Nutch2.3 发布。当前的 Nutch2 是一个非常不稳定的版本。
分布式爬虫平台架构图
3.2 JAVA爬虫
在这里,将JAVA爬虫划分为一个单独的类别,因为JAVA在网络爬虫的生态系统中非常完善。相关资料也是最全的。这里可能有争议,我只是随便说说。
其实开源网络爬虫(框架)的开发很简单,难点和复杂的问题已经被前人解决了(比如DOM树解析定位、字符集检测、海量URL去重),可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历本机的文件以查找文件中的信息。没有任何困难。选择开源爬虫框架的原因是为了省事。比如爬虫的URL管理、线程池等模块,任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
对于爬虫的功能。用户比较关心的问题往往是:
1)爬虫是否支持多线程,爬虫是否可以使用代理,爬虫是否可以爬取重复数据,爬虫是否可以爬取JS生成的信息?
不支持多线程、不支持代理、不能过滤重复URL的不叫开源爬虫,叫循环执行http请求。
js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理一个页面。因此,一种策略是利用这些爬虫遍历网站,当遇到需要解析的页面时,将网页的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
2)爬虫可以抓取ajax信息吗?
网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax的http请求,自己生成ajax请求的url,获取返回的数据。如果你自己生成ajax请求,那么使用开源爬虫有什么意义呢?其实就是利用开源爬虫的线程池和URL管理功能(比如断点爬取)。
如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来爬取这些请求呢?
爬虫往往被设计成广度遍历或深度遍历的方式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫并不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历 网站。爬虫的第一轮爬取就是爬取种子集(seeds)中的所有url。简单来说就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫对这些种子进行深度为 1 的广度遍历(默认为广度遍历)。
3)爬虫如何爬取待登录的网站?
这些开源爬虫都支持在爬取时指定cookies,而模拟登录主要依赖cookies。至于如何获取cookies,就不是爬虫管理的问题了。您可以手动获取cookies,使用http请求模拟登录,或者使用模拟浏览器自动登录。
4)爬虫如何从网页中提取信息?
开源爬虫一般会集成网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,我这里就不评论了。
5)爬虫是如何保存网页信息的?
有一些爬虫带有一个负责持久性的模块。例如,webmagic 有一个名为 pipeline 的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等。还有一些爬虫不直接为用户提供数据持久化模块。比如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于用管道模块好不好,就类似于用ORM操作数据库好不好的问题,看你的业务。
6)爬虫被网站拦截了怎么办?
爬虫被网站阻塞,可以通过使用多个代理(随机代理)来解决。但是这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,并编写代码让代理随机获取(从数组中)。
7)网页可以调用爬虫吗?
爬虫的调用是在Web的服务器端调用的。您可以按照平时使用的方式使用它。可以使用这些爬虫。
8)爬虫速度怎么样?
单机开源爬虫的速度基本可以用到本地网速的极限。爬虫速度慢往往是因为用户减少了线程数,网速慢,或者数据持久化时与数据库的交互慢。而这些东西往往是由用户的机器和二次开发的代码决定的。这些开源爬虫的速度非常好。
9) 明明代码写对了,但是数据爬不出来。爬虫有问题吗?另一个爬虫可以解决吗?
如果代码写得正确,无法爬取数据,其他爬虫也将无法爬取。在这种情况下,要么是 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。如果无法爬取数据,则无法通过更改爬虫来解决。
10)哪个爬虫可以判断网站是否已经爬完,哪个爬虫可以根据主题爬取?
爬虫无法判断网站是否已经爬完,只能尽量覆盖。
至于根据主题爬,爬虫把内容爬下来后就知道主题是什么了。因此,通常是整体爬下来,然后对内容进行过滤。如果爬取的范围太广,可以通过限制 URL 正则化来缩小范围。
11)哪个爬虫的设计模式和架构比较好?
设计模式是胡说八道。都说软件设计模式不错,软件开发后总结了几种设计模式。设计模式对软件开发没有指导意义。使用设计模式设计爬虫只会让爬虫的设计更加臃肿。
至于架构,目前开源爬虫主要是设计详细的数据结构,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,用任何框架都谈不上。
所以对于 JAVA 开源爬虫,我认为,只要找到一个运行良好的。如果业务复杂,使用哪个爬虫,只能通过复杂的二次开发来满足需求。
3.3 非JAVA爬虫
在非JAVA语言编写的爬虫中,不乏优秀的爬虫。这里提取为一个类别,不是为了讨论爬虫本身的好坏,而是为了讨论larbin、scrapy等爬虫对开发成本的影响。
先说python爬虫,python用30行代码就可以完成JAVA 50行代码的任务。Python写代码确实很快,但是在调试代码阶段,调试python代码所消耗的时间往往比编码阶段节省的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务也不复杂,用scrapy还是不错的,可以轻松完成爬取任务。
上图是Scrapy的架构图。绿线是数据流。从初始 URL 开始,Scheduler 会将其交给 Downloader 进行下载。下载完成后交给 Spider 进行分析,将要保存的数据发送到 Item Pipeline ,也就是对数据进行后处理。此外,可以在数据流通道中安装各种中间件,进行必要的处理。因此,在开发爬虫时,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
对于C++爬虫来说,学习成本会比较大。而且不能只计算一个人的学习成本。如果软件需要一个团队来开发或者移交,那就是很多人的学习成本。软件调试不是那么容易。
还有一些ruby和php爬虫,这里就不多评价了。确实有一些非常小的data采集任务,在ruby或者php中都用得上。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能存在一些你找不到的bug(很少有人使用它们,而且信息也较少)
4、反爬虫技术
由于搜索引擎的普及,网络爬虫已经成为一种非常流行的网络技术。除了专注于搜索的谷歌、雅虎、微软和百度之外,几乎每个大型门户网站网站都有自己的搜索引擎,无论大小。可以叫的名字有几十种,不知道的种类有上万种。对于一个内容驱动的网站,难免会被网络爬虫光顾。
一些智能搜索引擎爬虫的爬取频率比较合理,资源消耗也比较小,但是很多不良网络爬虫对网页的爬取能力很差,经常循环重复上百个请求。拿,这种爬虫对中小型网站来说往往是毁灭性的打击,尤其是一些缺乏爬虫编写经验的程序员编写的爬虫,破坏性极大,导致网站访问压力会很大非常大,这将导致 网站 访问缓慢甚至无法访问。
一般网站反爬虫从三个方面:用户请求的头文件、用户行为、网站目录和数据加载方式。前两种比较容易遇到,从这些角度来看,大部分网站都是反爬虫。会使用第三种使用ajax的网站,增加了爬取的难度。
4.1 反爬虫通过Headers
反爬取用户请求的头部是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(有些资源的防盗链网站就是检测Referer)。如果遇到这种反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值改为目标网站域名【注释:往往容易被Ignore,通过对请求的抓包分析,确定referer,在模拟访问请求的header中添加】在节目中。对于检测Headers的反爬虫,在爬虫中修改或添加Headers可以很好的绕过。
4.2 基于用户行为的反爬虫
网站的另一部分是检测用户行为,比如同一个IP在短时间内多次访问同一个页面,或者同一个账号在短时间内多次执行相同的操作。【这个反爬需要有足够的ip来处理】
大多数网站都是前一种情况,使用IP代理就可以了。可以专门写一个爬虫来爬取网上公开的代理ip,检测到后全部保存。这样的代理ip爬虫经常使用,最好自己准备一个。有大量代理IP,可以每隔几次更换一个IP,这在requests或者urllib2中很容易做到,这样就可以轻松绕过第一个反爬虫。[评论:动态拨号也是一种解决方案]
对于第二种情况,下一个请求可以在每个请求之后以几秒的随机间隔发出。一些有逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求的方式绕过同一账号短时间内不能多次请求的限制。【点评:账号反爬限制一般比较难处理,随机几秒的请求可能经常被屏蔽。如果可以有多个账号,切换使用,效果会更好】
4.3 动态页面的反爬虫
以上情况大多出现在静态页面中,也有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。一、使用Firebug或者HttpFox分析网络请求【点评:我感觉Google和IE的网络请求分析和使用也很不错】。如果我们能找到ajax请求并分析出具体参数和响应的具体含义,我们可以使用上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
能够直接模拟ajax请求获取数据是很棒的,但是有的网站把ajax请求的所有参数都加密了。我们根本无法构造对我们需要的数据的请求。我这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,接口参数是加密的。遇到这样的网站,我们就不能使用上面的方法了。我使用selenium+phantomJS框架调用浏览器内核,使用phantomJS执行js模拟人类操作,触发页面中的js脚本。从填表到点击按钮再到页面滚动,都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。[评论:支持phantomJS]
使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面提到的添加header在一定程度上是冒充浏览器),它本身就是浏览器,而且phantomJS 是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别触摸类型(12306)或者滑动类型的验证码,页面表单的暴力破解等)。它还将在自动化渗透中发挥重要作用,并将在未来发挥作用。提到这一点。 查看全部
htmlunit抓取动态网页(Web网络爬虫系统的原理及应用)
1、爬虫技术概述
网络爬虫是根据一定的规则自动从万维网上爬取信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,它可以自动采集它可以访问的所有页面获取或更新这些网站的内容和检索方法。从功能上来说,爬虫一般分为数据采集、处理、存储三部分。传统爬虫从一个或多个初始网页的URL开始,获取初始网页上的URL。在抓取网页的过程中,它不断地从当前页面中提取新的 URL 并放入队列中,直到满足系统的某些停止条件。焦点爬虫的工作流程比较复杂。它需要按照一定的网页分析算法过滤掉与主题无关的链接,保留有用的链接,并放入等待抓取的URL队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。
与通用网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
(1) 获取目标的描述或定义;
(2) 网页或数据的分析和过滤;
(3) URL 的搜索策略。
2、爬虫原理
2.1 网络爬虫原理
网络爬虫系统的功能是下载网页数据,为搜索引擎系统提供数据源。许多大型网络搜索引擎系统被称为基于Web数据的搜索引擎系统采集,如Google、百度等。这显示了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文字信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程像爬虫或者蜘蛛一样在网络上漫游,所以才叫做网络爬虫系统或者网络蜘蛛系统,英文叫Spider或者Crawler。
2.2 网络爬虫系统的工作原理
在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多个线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页和处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等。爬虫的基本工作是由解析器完成的。资源库用于存储下载的网络资源。通常使用大型数据库,例如 Oracle 数据库来存储和索引它。
控制器
控制器是网络爬虫的中央控制器。主要负责根据系统发送的URL链接分配一个线程,然后启动线程调用爬虫爬取网页。
解析器
解析器负责网络爬虫的主要部分。它的主要任务是:下载网页的功能,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
资源库
它主要是一个容器,用于存储从网页下载的数据记录,并为索引生成提供目标源。大中型数据库产品包括:Oracle、Sql Server等。
网络爬虫系统一般会选择一些比较重要的出度(网页中超链接数)网站较大的URL作为种子URL集。网络爬虫系统使用这些种子集作为初始 URL 来开始数据爬取。因为网页中收录链接信息,所以会通过已有网页的URL获取一些新的URL。网页之间的指向结构可以看作是一片森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能导致爬虫系统陷入网站内部,不利于搜索距离网站首页比较近的网页信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。
网络爬虫的基本工作流程如下:
1.首先选择一个精心挑选的种子 URL 的子集;
2.将这些网址放入待抓取的网址队列中;
3. 从待爬取URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页,存入下载的网页库中。此外,将这些 URL 放入 Crawl URL 队列。
4.分析已经爬取的URL队列中的URL,分析其中的其他URL,将这些URL放入待爬取的URL队列,从而进入下一个循环。
2.3 爬取策略
在爬虫系统中,待爬取的 URL 队列是一个重要的部分。待爬取的URL队列中的URL的排列顺序也是一个重要的问题,因为它涉及到先爬到哪个页面,再爬到哪个页面。确定这些 URL 排列顺序的方法称为爬取策略。下面重点介绍几种常见的爬取策略:
2.3.1 深度优先遍历策略
深度优先遍历策略是指网络爬虫会从起始页开始,每次一个链接跟踪每个链接,处理完该行后移动到下一个起始页,并继续跟踪该链接。我们以下图为例:
遍历的路径:AFG EHI BCD
2.3.2 广度优先遍历策略
广度优先遍历的基本思想是将新下载的网页中找到的链接直接插入待爬取URL队列的末尾。也就是说,网络爬虫会先爬取起始网页链接的所有网页,然后选择其中一个链接的网页,继续爬取该网页链接的所有网页。或者以上图为例:
遍历路径:ABCDEF GHI
2.3.3 反向链接策略
反向链接数是指从其他网页指向一个网页的链接数。反向链接的数量表示网页内容被他人推荐的程度。因此,在很多情况下,搜索引擎的爬取系统会使用这个指标来评估网页的重要性,从而确定不同网页的爬取顺序。
在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量并不能完全等同于他人的重要性。因此,搜索引擎倾向于考虑一些可靠的反向链接计数。
2.3.4部分PageRank策略
Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,与待爬取的URL队列中的URL一起形成一组网页,计算每个页面的PageRank值. URL 按 PageRank 值排序,并按该顺序抓取页面。
如果每次爬取一个页面都重新计算一次PageRank值,一个折中的方案是每次爬取K个页面都重新计算一次PageRank值。但是这种情况还是有一个问题:对于下载页面中分析的链接,也就是我们前面提到的那部分未知网页,暂时没有PageRank值。为了解决这个问题,给这些页面一个临时的PageRank值:把这个网页的所有传入链接传入的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排序. 以下示例说明:
2.3.5OPICStrategy
该算法实际上为页面分配了一个重要性分数。在算法开始之前,所有页面都会获得相同的初始现金。当某个页面P被下载时,P的现金分配给从P分析的所有链接,P的现金被清空。根据现金数量对待爬取URL队列中的所有页面进行排序。
2.3.六大网站优先策略
所有待爬取的URL队列中的网页都按照它们所属的网站进行分类。网站需要下载的页面较多,请先下载。这种策略也称为大站点优先策略。
3、爬虫分类
我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫类,基本上可以分为三类:
(1)分布式爬虫:Nutch
(2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
(3)非JAVA爬虫:scrapy(基于Python语言开发)
3.1 分布式爬虫
爬虫使用分布式,主要解决两个问题:
1)海量网址管理
2)网速
现在比较流行的分布式爬虫是Apache的Nutch。但是对于大多数用户来说,Nutch 是这些爬虫中最差的选择,原因如下:
1)Nutch 是为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的三分之二的流程是为搜索引擎设计的。提取意义不大。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发让Nutch适合提取业务,那你基本上会破坏Nutch的框架,把Nutch改得面目全非,而且有能力修改Nutch,还不如自己写一个新的。分布式爬虫框架。
2)Nutch 依赖hadoop 运行,hadoop 本身消耗大量时间。如果集群机器数量少,爬取速度不如单机爬虫快。
3)虽然Nutch有一套插件机制,但还是作为亮点来宣传的。可以看到一些开源的Nutch插件,提供精准提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多糟糕。使用反射机制加载和调用插件,使得程序的编写和调试变得异常困难,更不用说在其上开发复杂的提取系统了。并且 Nutch 没有提供对应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点都是给搜索引擎服务的,不提供细提取的挂载点。Nutch 的大部分精炼提取插件都挂载在“页面解析”(parser)挂载点上。这个挂载点其实是用来解析链接(为后续爬取提供URL)和提供一些搜索引擎的。易于提取的网页信息(元信息、网页文本)。
4)使用Nutch进行爬虫的二次开发,编写和调试爬虫所需的时间往往是单机爬虫所需时间的十倍以上。学习 Nutch 源码的成本非常高,更何况团队中的每个人都必须了解 Nutch 源码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
5)很多人说Nutch2有gora,可以把数据持久化到avro文件、hbase、mysql等,其实很多人都搞错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
6)Nutch2 的版本目前不适合开发。Nutch的官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果要使用hbase和nutch(大多数人使用nutch2是为了使用hbase),只能使用版本0.90左右的hbase,相应地,将hadoop版本降低到hadoop 0.左右@>2。而且nutch2的官方教程也颇具误导性。Nutch2的教程有两个,分别是Nutch1.x和Nutch2.x。Nutch2.x官网是为了支持hbase0.94而写的。但其实这个Nutch2.x是指Nutch2.3之前和Nutch2.2.1之后的一个版本,在官方SVN中不断更新。而且它'
所以,如果你不是搜索引擎,尽量不要选择 Nutch 作为爬虫。一些团队喜欢跟风。他们坚持选择Nutch来开发精制履带。其实是针对Nutch的名声(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目延期。
如果你在做搜索引擎,Nutch1.x 是一个非常不错的选择。Nutch1.x 和 solr 或 es 可以组成一个非常强大的搜索引擎。如果必须使用 Nutch2,建议等到 Nutch2.3 发布。当前的 Nutch2 是一个非常不稳定的版本。
分布式爬虫平台架构图
3.2 JAVA爬虫
在这里,将JAVA爬虫划分为一个单独的类别,因为JAVA在网络爬虫的生态系统中非常完善。相关资料也是最全的。这里可能有争议,我只是随便说说。
其实开源网络爬虫(框架)的开发很简单,难点和复杂的问题已经被前人解决了(比如DOM树解析定位、字符集检测、海量URL去重),可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历本机的文件以查找文件中的信息。没有任何困难。选择开源爬虫框架的原因是为了省事。比如爬虫的URL管理、线程池等模块,任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
对于爬虫的功能。用户比较关心的问题往往是:
1)爬虫是否支持多线程,爬虫是否可以使用代理,爬虫是否可以爬取重复数据,爬虫是否可以爬取JS生成的信息?
不支持多线程、不支持代理、不能过滤重复URL的不叫开源爬虫,叫循环执行http请求。
js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理一个页面。因此,一种策略是利用这些爬虫遍历网站,当遇到需要解析的页面时,将网页的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
2)爬虫可以抓取ajax信息吗?
网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax的http请求,自己生成ajax请求的url,获取返回的数据。如果你自己生成ajax请求,那么使用开源爬虫有什么意义呢?其实就是利用开源爬虫的线程池和URL管理功能(比如断点爬取)。
如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来爬取这些请求呢?
爬虫往往被设计成广度遍历或深度遍历的方式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫并不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历 网站。爬虫的第一轮爬取就是爬取种子集(seeds)中的所有url。简单来说就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫对这些种子进行深度为 1 的广度遍历(默认为广度遍历)。
3)爬虫如何爬取待登录的网站?
这些开源爬虫都支持在爬取时指定cookies,而模拟登录主要依赖cookies。至于如何获取cookies,就不是爬虫管理的问题了。您可以手动获取cookies,使用http请求模拟登录,或者使用模拟浏览器自动登录。
4)爬虫如何从网页中提取信息?
开源爬虫一般会集成网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,我这里就不评论了。
5)爬虫是如何保存网页信息的?
有一些爬虫带有一个负责持久性的模块。例如,webmagic 有一个名为 pipeline 的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等。还有一些爬虫不直接为用户提供数据持久化模块。比如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于用管道模块好不好,就类似于用ORM操作数据库好不好的问题,看你的业务。
6)爬虫被网站拦截了怎么办?
爬虫被网站阻塞,可以通过使用多个代理(随机代理)来解决。但是这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,并编写代码让代理随机获取(从数组中)。
7)网页可以调用爬虫吗?
爬虫的调用是在Web的服务器端调用的。您可以按照平时使用的方式使用它。可以使用这些爬虫。
8)爬虫速度怎么样?
单机开源爬虫的速度基本可以用到本地网速的极限。爬虫速度慢往往是因为用户减少了线程数,网速慢,或者数据持久化时与数据库的交互慢。而这些东西往往是由用户的机器和二次开发的代码决定的。这些开源爬虫的速度非常好。
9) 明明代码写对了,但是数据爬不出来。爬虫有问题吗?另一个爬虫可以解决吗?
如果代码写得正确,无法爬取数据,其他爬虫也将无法爬取。在这种情况下,要么是 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。如果无法爬取数据,则无法通过更改爬虫来解决。
10)哪个爬虫可以判断网站是否已经爬完,哪个爬虫可以根据主题爬取?
爬虫无法判断网站是否已经爬完,只能尽量覆盖。
至于根据主题爬,爬虫把内容爬下来后就知道主题是什么了。因此,通常是整体爬下来,然后对内容进行过滤。如果爬取的范围太广,可以通过限制 URL 正则化来缩小范围。
11)哪个爬虫的设计模式和架构比较好?
设计模式是胡说八道。都说软件设计模式不错,软件开发后总结了几种设计模式。设计模式对软件开发没有指导意义。使用设计模式设计爬虫只会让爬虫的设计更加臃肿。
至于架构,目前开源爬虫主要是设计详细的数据结构,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,用任何框架都谈不上。
所以对于 JAVA 开源爬虫,我认为,只要找到一个运行良好的。如果业务复杂,使用哪个爬虫,只能通过复杂的二次开发来满足需求。
3.3 非JAVA爬虫
在非JAVA语言编写的爬虫中,不乏优秀的爬虫。这里提取为一个类别,不是为了讨论爬虫本身的好坏,而是为了讨论larbin、scrapy等爬虫对开发成本的影响。
先说python爬虫,python用30行代码就可以完成JAVA 50行代码的任务。Python写代码确实很快,但是在调试代码阶段,调试python代码所消耗的时间往往比编码阶段节省的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务也不复杂,用scrapy还是不错的,可以轻松完成爬取任务。
上图是Scrapy的架构图。绿线是数据流。从初始 URL 开始,Scheduler 会将其交给 Downloader 进行下载。下载完成后交给 Spider 进行分析,将要保存的数据发送到 Item Pipeline ,也就是对数据进行后处理。此外,可以在数据流通道中安装各种中间件,进行必要的处理。因此,在开发爬虫时,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
对于C++爬虫来说,学习成本会比较大。而且不能只计算一个人的学习成本。如果软件需要一个团队来开发或者移交,那就是很多人的学习成本。软件调试不是那么容易。
还有一些ruby和php爬虫,这里就不多评价了。确实有一些非常小的data采集任务,在ruby或者php中都用得上。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能存在一些你找不到的bug(很少有人使用它们,而且信息也较少)
4、反爬虫技术
由于搜索引擎的普及,网络爬虫已经成为一种非常流行的网络技术。除了专注于搜索的谷歌、雅虎、微软和百度之外,几乎每个大型门户网站网站都有自己的搜索引擎,无论大小。可以叫的名字有几十种,不知道的种类有上万种。对于一个内容驱动的网站,难免会被网络爬虫光顾。
一些智能搜索引擎爬虫的爬取频率比较合理,资源消耗也比较小,但是很多不良网络爬虫对网页的爬取能力很差,经常循环重复上百个请求。拿,这种爬虫对中小型网站来说往往是毁灭性的打击,尤其是一些缺乏爬虫编写经验的程序员编写的爬虫,破坏性极大,导致网站访问压力会很大非常大,这将导致 网站 访问缓慢甚至无法访问。
一般网站反爬虫从三个方面:用户请求的头文件、用户行为、网站目录和数据加载方式。前两种比较容易遇到,从这些角度来看,大部分网站都是反爬虫。会使用第三种使用ajax的网站,增加了爬取的难度。
4.1 反爬虫通过Headers
反爬取用户请求的头部是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(有些资源的防盗链网站就是检测Referer)。如果遇到这种反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值改为目标网站域名【注释:往往容易被Ignore,通过对请求的抓包分析,确定referer,在模拟访问请求的header中添加】在节目中。对于检测Headers的反爬虫,在爬虫中修改或添加Headers可以很好的绕过。
4.2 基于用户行为的反爬虫
网站的另一部分是检测用户行为,比如同一个IP在短时间内多次访问同一个页面,或者同一个账号在短时间内多次执行相同的操作。【这个反爬需要有足够的ip来处理】
大多数网站都是前一种情况,使用IP代理就可以了。可以专门写一个爬虫来爬取网上公开的代理ip,检测到后全部保存。这样的代理ip爬虫经常使用,最好自己准备一个。有大量代理IP,可以每隔几次更换一个IP,这在requests或者urllib2中很容易做到,这样就可以轻松绕过第一个反爬虫。[评论:动态拨号也是一种解决方案]
对于第二种情况,下一个请求可以在每个请求之后以几秒的随机间隔发出。一些有逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求的方式绕过同一账号短时间内不能多次请求的限制。【点评:账号反爬限制一般比较难处理,随机几秒的请求可能经常被屏蔽。如果可以有多个账号,切换使用,效果会更好】
4.3 动态页面的反爬虫
以上情况大多出现在静态页面中,也有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。一、使用Firebug或者HttpFox分析网络请求【点评:我感觉Google和IE的网络请求分析和使用也很不错】。如果我们能找到ajax请求并分析出具体参数和响应的具体含义,我们可以使用上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
能够直接模拟ajax请求获取数据是很棒的,但是有的网站把ajax请求的所有参数都加密了。我们根本无法构造对我们需要的数据的请求。我这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,接口参数是加密的。遇到这样的网站,我们就不能使用上面的方法了。我使用selenium+phantomJS框架调用浏览器内核,使用phantomJS执行js模拟人类操作,触发页面中的js脚本。从填表到点击按钮再到页面滚动,都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。[评论:支持phantomJS]
使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面提到的添加header在一定程度上是冒充浏览器),它本身就是浏览器,而且phantomJS 是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别触摸类型(12306)或者滑动类型的验证码,页面表单的暴力破解等)。它还将在自动化渗透中发挥重要作用,并将在未来发挥作用。提到这一点。
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 61 次浏览 • 2022-02-14 18:06
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键—— > 点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。
使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ
欢迎补充:) 查看全部
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键—— > 点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。

使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ

欢迎补充:)
htmlunit抓取动态网页(让我们一起出发探索未知的奥秘吧!(组图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 81 次浏览 • 2022-02-12 05:25
下面就给大家介绍一下如何通过html+css+mysql+php快速创建动态网页,让我们一起来探索未知的奥秘吧!!!
一、搭建开发环境
(1)apache+php+mysql环境搭建
因为使用apache作为服务器,使用mysql作为数据库存储数据,使用php编写代码实现网页与数据库的交互数据,需要下载以上软件,但是安装以上软件的环境和配置都很麻烦,所以这里我们使用一个强大的建站集成软件包---XAMPP,
(2)数据库客户端软件导航
直接在cmd命令控制台中操作数据库不方便,不够直观。当然也可以直接用phpmyadmin操作(上面的xampp包安装好后,在浏览器输入127.0.0.1/phpmyadmin可以打开),但是phpmyadmin操作不方便,这里我们使用Navicat制作的数据库客户端
点击connect,输入连接名称,(这里我直接取IP地址的名称127.0.0.1),主机名和端口号不需要要更改的,这里的用户名和密码,如果你使用的是xampp,用户名是root,密码为空;如果不是xampp安装的,可以根据你设置的用户名和密码登录。填写完后点击连接测试,没有问题直接确认连接数据库。
另外,如果你想掌握数据库,简单来说,你想对数据库进行任何操作都必须操作sql语句。一般来说,它分为四种操作:添加、删除、修改和查询。
①添加:将数据写入数据库
语句:插入用户(`username`,`password`)值('name','passwd')
(ps新手一定要注意用户数据表后面的``符号是tab键上面的引号,值后面的值是单引号)
②删除:删除已有数据
声明:从用户中删除 WHERE id='3'
③Change:修改数据
语句:update set users username='new value', password='new value' WHERE id=3
④检查:从数据库中读取数据
语句:select * from users where id>1 order by id desc limit 0,2
(3)html网页创作工具sublime text
Sublime Text 是一个代码编辑器(Sublime Text 2 是付费软件,但可以无限期试用)和一个用于 HTML 和散文的高级文本编辑器。Sublime text 拥有漂亮的用户界面和强大的功能,非常适合写代码的程序员。
使用sublime text写网页代码,可以掌握这么一个小技巧,先新建一个文件,保存格式为html网页格式,然后用sublime text打开,输入html:4s然后按tab键生成一个通用框架。当然,如果要使用这个快捷键,必须按照我上面给出的链接,按照步骤安装好Emmet插件,才能使用。
(4)网站域名配置
一般来说,当你在浏览器中打开URL 127.0.0.1 时,会跳转到apache默认目录下的一个URL。这里我修改一下,修改为我的项目目录,E:PHPxamppapacheconf,打开httpd.conf文件,修改里面的路径为你存放网站的目录,这里我的修改是
DocumentRoot "E:/php/xampp/workplace"
这里要注意根据自己下载的路径修改自己的目录。其次,我也再次修改了URL 127.0.0.1,使其虚拟域名为,,修改后重启后,在浏览器中输入,会出现如下场景:
这里发现我修改的DNS配置,不知道什么时候在前面加了注释,所以打不开。大家也应该注意按照我给的连接配置。如果无法打开,请检查配置文件。错误。
总之,配置环境和工具基本搭建成功,接下来就开始讲解本篇博客的项目。
二、写博客网站写作
1.整体框架
首先介绍一下我的整体框架,解释一下,让大家先熟悉一下。
blog为项目名称,admin文件夹存放后台登录文件,core文件夹存放核心文件,theme文件夹存放网页样式文件,upfiles文件夹存放从本地上传到的图片信息服务器,然后 config.php 文件是整个博客的配置文件网站,header.inc.php是加载了一个页面样式信息,index.php文件是网站的首页@>,read.php 文件是 网站 文章 特定链接的主页。
这里给出数据库表的设计,供大家参考学习。这里我主要建三张表,admin用来存放后台管理员的注册登录数据,也就是账号和密码:
页表主要用于存放博客信息,这里也给出图片方便安装图建表:
最后给出设置表,主要用于存放博客的系统设置:
2.网站后台管理员写作
(1)登录界面(login.php)
关于这个页面,我会在这里给出源代码。登录页面实际上是一个从数据库中读取的过程。这个登录页面的设计主要是使用bootstrap来设计的。
在里面,它收录了各种样式、组件和 JavaScript 插件,可以说是非常好用。
我这里使用的方式是下载bootstrap,然后加压文件,复制到主题文件夹。调用方法见下方源码。我在源代码中给出了详细的解释。
源代码:
管理员登录界面
<p class="container">
<p class="row" style="margin-top:200px;">
管理员登录
导航.inc.php
<p class="container-fluid">
<p class="navbar-header">
Toggle navigation
ADMIN
博客管理 (current)
管理员管理
系统管理
退出
</p>
</p>
(4) 博客管理界面(blog.php)
这里一共有三个功能,修改、删除、添加博客界面。下面我将分别列出添加博客接口。
(5)添加博客接口(blog_add.php)
这里,如果编辑器需要图片上传功能,需要在文件中设置。此文件设置为 (blog_uopload.php)
blog_add.php 源代码
<p>
添加博客
<p class="container">
博客管理 返回
<p class="rows"> 查看全部
htmlunit抓取动态网页(让我们一起出发探索未知的奥秘吧!(组图))
下面就给大家介绍一下如何通过html+css+mysql+php快速创建动态网页,让我们一起来探索未知的奥秘吧!!!

一、搭建开发环境
(1)apache+php+mysql环境搭建
因为使用apache作为服务器,使用mysql作为数据库存储数据,使用php编写代码实现网页与数据库的交互数据,需要下载以上软件,但是安装以上软件的环境和配置都很麻烦,所以这里我们使用一个强大的建站集成软件包---XAMPP,

(2)数据库客户端软件导航
直接在cmd命令控制台中操作数据库不方便,不够直观。当然也可以直接用phpmyadmin操作(上面的xampp包安装好后,在浏览器输入127.0.0.1/phpmyadmin可以打开),但是phpmyadmin操作不方便,这里我们使用Navicat制作的数据库客户端

点击connect,输入连接名称,(这里我直接取IP地址的名称127.0.0.1),主机名和端口号不需要要更改的,这里的用户名和密码,如果你使用的是xampp,用户名是root,密码为空;如果不是xampp安装的,可以根据你设置的用户名和密码登录。填写完后点击连接测试,没有问题直接确认连接数据库。

另外,如果你想掌握数据库,简单来说,你想对数据库进行任何操作都必须操作sql语句。一般来说,它分为四种操作:添加、删除、修改和查询。
①添加:将数据写入数据库
语句:插入用户(`username`,`password`)值('name','passwd')
(ps新手一定要注意用户数据表后面的``符号是tab键上面的引号,值后面的值是单引号)
②删除:删除已有数据
声明:从用户中删除 WHERE id='3'
③Change:修改数据
语句:update set users username='new value', password='new value' WHERE id=3
④检查:从数据库中读取数据
语句:select * from users where id>1 order by id desc limit 0,2
(3)html网页创作工具sublime text
Sublime Text 是一个代码编辑器(Sublime Text 2 是付费软件,但可以无限期试用)和一个用于 HTML 和散文的高级文本编辑器。Sublime text 拥有漂亮的用户界面和强大的功能,非常适合写代码的程序员。

使用sublime text写网页代码,可以掌握这么一个小技巧,先新建一个文件,保存格式为html网页格式,然后用sublime text打开,输入html:4s然后按tab键生成一个通用框架。当然,如果要使用这个快捷键,必须按照我上面给出的链接,按照步骤安装好Emmet插件,才能使用。
(4)网站域名配置
一般来说,当你在浏览器中打开URL 127.0.0.1 时,会跳转到apache默认目录下的一个URL。这里我修改一下,修改为我的项目目录,E:PHPxamppapacheconf,打开httpd.conf文件,修改里面的路径为你存放网站的目录,这里我的修改是
DocumentRoot "E:/php/xampp/workplace"
这里要注意根据自己下载的路径修改自己的目录。其次,我也再次修改了URL 127.0.0.1,使其虚拟域名为,,修改后重启后,在浏览器中输入,会出现如下场景:

这里发现我修改的DNS配置,不知道什么时候在前面加了注释,所以打不开。大家也应该注意按照我给的连接配置。如果无法打开,请检查配置文件。错误。
总之,配置环境和工具基本搭建成功,接下来就开始讲解本篇博客的项目。
二、写博客网站写作
1.整体框架
首先介绍一下我的整体框架,解释一下,让大家先熟悉一下。

blog为项目名称,admin文件夹存放后台登录文件,core文件夹存放核心文件,theme文件夹存放网页样式文件,upfiles文件夹存放从本地上传到的图片信息服务器,然后 config.php 文件是整个博客的配置文件网站,header.inc.php是加载了一个页面样式信息,index.php文件是网站的首页@>,read.php 文件是 网站 文章 特定链接的主页。

这里给出数据库表的设计,供大家参考学习。这里我主要建三张表,admin用来存放后台管理员的注册登录数据,也就是账号和密码:

页表主要用于存放博客信息,这里也给出图片方便安装图建表:

最后给出设置表,主要用于存放博客的系统设置:

2.网站后台管理员写作
(1)登录界面(login.php)

关于这个页面,我会在这里给出源代码。登录页面实际上是一个从数据库中读取的过程。这个登录页面的设计主要是使用bootstrap来设计的。

在里面,它收录了各种样式、组件和 JavaScript 插件,可以说是非常好用。

我这里使用的方式是下载bootstrap,然后加压文件,复制到主题文件夹。调用方法见下方源码。我在源代码中给出了详细的解释。
源代码:
管理员登录界面
<p class="container">
<p class="row" style="margin-top:200px;">
管理员登录
导航.inc.php
<p class="container-fluid">
<p class="navbar-header">
Toggle navigation
ADMIN
博客管理 (current)
管理员管理
系统管理
退出
</p>
</p>
(4) 博客管理界面(blog.php)
这里一共有三个功能,修改、删除、添加博客界面。下面我将分别列出添加博客接口。

(5)添加博客接口(blog_add.php)
这里,如果编辑器需要图片上传功能,需要在文件中设置。此文件设置为 (blog_uopload.php)
blog_add.php 源代码
<p>
添加博客
<p class="container">
博客管理 返回
<p class="rows">
htmlunit抓取动态网页(selenium模块为第三方模块需要安装的操作软件操作原理)
网站优化 • 优采云 发表了文章 • 0 个评论 • 59 次浏览 • 2022-02-09 14:04
【百度云搜索,搜索各种素材:】【搜索网盘,搜索各种素材:】
硒模块
selenium 模块是需要安装的第三方模块。 selenium模块是一个api接口模块,操作各种浏览器对应的软件
selenium模块是api接口模块,操作各种浏览器对应的软件,所以需要下载浏览器对应的操作软件
工作原理是:selenium模块操作浏览器操作软件,浏览器操作软件操作浏览器
Selenium 2.0 用于以下浏览器
谷歌浏览器
Internet Explorer 7、8、9、10、11
火狐
Safari
歌剧
HtmlUnit
幻影
安卓
iOS
Selenium的核心是用js控制浏览器
下载相应的浏览器操作软件
铬:
边缘:
火狐:
Safari:
我们这里使用 Firefox 作为一栏
首先将火狐浏览器的操作软件geckodriver.exe文件放入爬虫目录
selenium 模块可以模拟用户行为来操作各种版本的浏览器
webdriver.Firefox('操作浏览器软件路径') 实例化Firefox浏览器对象
get('url') 访问网站
find_element_by_xpath('xpath expression') 通过xpath表达式找到对应的元素
clear() 清除输入框内容
send_keys('content')将内容写入输入框
click()点击事件
get_screenshot_as_file('截屏保存路径名') 将网页截图保存到该目录
page_source 获取网页 htnl 源代码
browser.close() 关闭浏览器
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.tmall.com/?spm=a220o.1000855.a2226mz.1.5c90c3484bZCx6')
# 模拟用户操作
browser.find_element_by_xpath('//input[@id="mq"]').clear() # 通过xpath表达式找到输入框,clear()清空输入框里的内容
browser.find_element_by_xpath('//input[@id="mq"]').send_keys('连衣裙') # 通过xpath表达式找到输入框,send_keys()将内容写入输入框
browser.find_element_by_xpath('//button[@type="submit"]').click() # 通过xpath表达式找到搜索按钮,click()点击事件
time.sleep(3) # 等待3秒
browser.get_screenshot_as_file('H:/py/17/img/123.jpg') # 将网页截图,保存到此目录
neir = browser.page_source # 获取网页内容
print(neir)
browser.close() # 关闭浏览器
使用 scrapy 的 Selector 方法。过滤所选数据
Selector()方法,过滤选中的数据,参数为获取的字符串html源码
Selenium 操作浏览器滚动条
execute_script(js)方法,执行原生态js脚本
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
from scrapy.selector import Selector
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.oschina.net/blog')
time.sleep(3) # 等待3秒
for i in range(3): # 滚动3次滚动条
js = 'window.scrollTo(0,document.body.scrollHeight); var lenofpage=document.body.scrollHeight; return lenofpage'
browser.execute_script(js) # 执行js语言滚动滚动条
time.sleep(3)
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
设置请求页面不加载图片,提高请求效率
ChromeOptions() 方法,创建谷歌浏览器设置对象
Chrome() 方法,创建谷歌浏览器对象
谷歌浏览器在下面列出
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
from scrapy.selector import Selector
#设置请求网页不加载图片,提高请求效率
chrome_options = webdriver.ChromeOptions() #创建谷歌浏览器设置对象
prefs = {"profile.managed_default_content_settings.images": 2} #设置谷歌浏览器不加载图片
chrome_options.add_experimental_option('prefs', prefs) #将不加载图片添加到浏览器
browser = webdriver.Chrome(executable_path='H:/py/16/adc/adc/Firefox/chromedriver.exe', chrome_options=chrome_options)
# browser.set_page_load_timeout(40) #设置页面最长加载时间为40s
browser.get('https://www.taobao.com/')
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
selenium 模块也可以操作 PhantomJS 浏览器。 PhantomJS是无界面浏览器,比较清爽,但是多线程会降低性能
重要提示:我们建议使用 chromedriver.exe、谷歌浏览器 查看全部
htmlunit抓取动态网页(selenium模块为第三方模块需要安装的操作软件操作原理)
【百度云搜索,搜索各种素材:】【搜索网盘,搜索各种素材:】
硒模块
selenium 模块是需要安装的第三方模块。 selenium模块是一个api接口模块,操作各种浏览器对应的软件
selenium模块是api接口模块,操作各种浏览器对应的软件,所以需要下载浏览器对应的操作软件
工作原理是:selenium模块操作浏览器操作软件,浏览器操作软件操作浏览器
Selenium 2.0 用于以下浏览器
谷歌浏览器
Internet Explorer 7、8、9、10、11
火狐
Safari
歌剧
HtmlUnit
幻影
安卓
iOS

Selenium的核心是用js控制浏览器
下载相应的浏览器操作软件
铬:
边缘:
火狐:
Safari:
我们这里使用 Firefox 作为一栏
首先将火狐浏览器的操作软件geckodriver.exe文件放入爬虫目录
selenium 模块可以模拟用户行为来操作各种版本的浏览器
webdriver.Firefox('操作浏览器软件路径') 实例化Firefox浏览器对象
get('url') 访问网站
find_element_by_xpath('xpath expression') 通过xpath表达式找到对应的元素
clear() 清除输入框内容
send_keys('content')将内容写入输入框
click()点击事件
get_screenshot_as_file('截屏保存路径名') 将网页截图保存到该目录
page_source 获取网页 htnl 源代码
browser.close() 关闭浏览器
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.tmall.com/?spm=a220o.1000855.a2226mz.1.5c90c3484bZCx6')
# 模拟用户操作
browser.find_element_by_xpath('//input[@id="mq"]').clear() # 通过xpath表达式找到输入框,clear()清空输入框里的内容
browser.find_element_by_xpath('//input[@id="mq"]').send_keys('连衣裙') # 通过xpath表达式找到输入框,send_keys()将内容写入输入框
browser.find_element_by_xpath('//button[@type="submit"]').click() # 通过xpath表达式找到搜索按钮,click()点击事件
time.sleep(3) # 等待3秒
browser.get_screenshot_as_file('H:/py/17/img/123.jpg') # 将网页截图,保存到此目录
neir = browser.page_source # 获取网页内容
print(neir)
browser.close() # 关闭浏览器
使用 scrapy 的 Selector 方法。过滤所选数据
Selector()方法,过滤选中的数据,参数为获取的字符串html源码
Selenium 操作浏览器滚动条
execute_script(js)方法,执行原生态js脚本
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
from scrapy.selector import Selector
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.oschina.net/blog')
time.sleep(3) # 等待3秒
for i in range(3): # 滚动3次滚动条
js = 'window.scrollTo(0,document.body.scrollHeight); var lenofpage=document.body.scrollHeight; return lenofpage'
browser.execute_script(js) # 执行js语言滚动滚动条
time.sleep(3)
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
设置请求页面不加载图片,提高请求效率
ChromeOptions() 方法,创建谷歌浏览器设置对象
Chrome() 方法,创建谷歌浏览器对象
谷歌浏览器在下面列出
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
from scrapy.selector import Selector
#设置请求网页不加载图片,提高请求效率
chrome_options = webdriver.ChromeOptions() #创建谷歌浏览器设置对象
prefs = {"profile.managed_default_content_settings.images": 2} #设置谷歌浏览器不加载图片
chrome_options.add_experimental_option('prefs', prefs) #将不加载图片添加到浏览器
browser = webdriver.Chrome(executable_path='H:/py/16/adc/adc/Firefox/chromedriver.exe', chrome_options=chrome_options)
# browser.set_page_load_timeout(40) #设置页面最长加载时间为40s
browser.get('https://www.taobao.com/')
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
selenium 模块也可以操作 PhantomJS 浏览器。 PhantomJS是无界面浏览器,比较清爽,但是多线程会降低性能
重要提示:我们建议使用 chromedriver.exe、谷歌浏览器
htmlunit抓取动态网页(使用本文中推荐的开源工具——HtmlUnit,一款能够模拟浏览器的抓包神器!)
网站优化 • 优采云 发表了文章 • 0 个评论 • 52 次浏览 • 2022-02-06 04:23
之前,一峰写过一篇关于使用Jsoup爬取网页内容的文章文章:
[Jsoup] HTML解析器,轻松获取网页内容
Jsoup提供的api非常方便,完全类似于JQuery操作,轻松抓取网页数据。但是像Jsoup这样的普通爬虫工具的缺点是不能处理js生成的内容。
做过Html开发的都知道现在很多网站都是用ajax和JavaScript来获取和处理数据,普通爬虫工具已经无法处理js中的内容了。
比如我们在本地新建一个测试web文件text.html,源码如下:
main.html
a {
line-height: 30px;
margin: 20px;
}
var datas = [ {
href : "http://www.jianshu.com/p/8d8edf25850d",
title : "推荐一款编程字体,让代码看着更美"
}, {
href : "http://www.jianshu.com/p/153d9f31288d",
title : "Android 利用Camera实现中轴3D卡牌翻转效果"
}, {
href : "http://www.jianshu.com/p/d6fb0c9c9c26",
title : "【Eclipse】挖掘专属最有用的快捷键组合"
}, {
href : "http://www.jianshu.com/p/72d69b49d135",
title : "【IIS】Windows下利用IIS建立网站并实现局域网共享"
} ];
window.onload = function() {
var infos = document.getElementById("infos");
for( var i = 0 ; i < datas.length ; i++)
{
var a = document.createElement("a");
a.href = datas[i].href ;
a.innerText = datas[i].title;
infos.appendChild(a);
infos.appendChild(document.createElement("br"))
}
}
HtmlUnit 测试网页内容!
通过IIS发布本地网站(参考之前逸峰写的文章:
【IIS】在Windows下使用IIS建立网站,实现局域网共享),
网页在浏览器中显示的效果如下:
网页显示效果.jpg
虽然通过网页检查元素,可以看到body中收录了网页显示的文字内容:
网络评论元素.jpg
但是,它根本无法通过 Jsoup 工具获得!从网页的源码可以看出,我们需要爬取的内容是在页面显示出来后通过ajax和JavaScript加载的。
那么该怎么办?使用本文推荐的开源工具——HtmlUnit,一个可以模拟浏览器的抓包神器!
在官网下载对应的jar包,添加到项目工程的lib中。简单的测试代码如下:
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.ParseException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
/**
* @author 亦枫
* @created_time 2016年1月12日
* @file_user_todo Java测试类
* @blog http://www.jianshu.com/users/1 ... icles
*/
public class JavaTest {
/**
* 入口函数
* @param args
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
try {
WebClient webClient = new WebClient(BrowserVersion.CHROME);
HtmlPage htmlPage = (HtmlPage) webClient.getPage("http://localhost/test.html");
DomNodeList domNodeList = htmlPage.getElementsByTagName("a");
for (int i = 0; i < domNodeList.size(); i++) {
DomElement domElement = (DomElement) domNodeList.get(i);
System.out.println(domElement.asText());
}
webClient.close();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行后,控制台打印出结果:
HtmlUnit测试结果.jpg
可以看出,HtmlUnit 能够抓取 AJAX 和 JavaScript 加载的内容。
HtmlUnit的介绍在官网上很详细。以下内容为易峰翻译的部分内容,供大家参考:
HtmlUnit 是一个基于 Java 的浏览器程序,没有图形界面。它可以调用 HTML 文档并提供 API,让开发人员可以像在普通浏览器上一样获取 Web 内容、填写表单、单击超链接等。
它对 JavaScript 的支持非常好并且还在改进中,可以解析非常复杂的 AJAX 库,模拟不同配置下的 Chrome、Firefox 和 IE 浏览器。
HtmlUnit 通常用于测试目的和检索 网站 信息。
HtmlUnit 提供了许多测试网络请求和爬取网页内容的功能。可以去官网或者其他网站学习使用。 查看全部
htmlunit抓取动态网页(使用本文中推荐的开源工具——HtmlUnit,一款能够模拟浏览器的抓包神器!)
之前,一峰写过一篇关于使用Jsoup爬取网页内容的文章文章:
[Jsoup] HTML解析器,轻松获取网页内容
Jsoup提供的api非常方便,完全类似于JQuery操作,轻松抓取网页数据。但是像Jsoup这样的普通爬虫工具的缺点是不能处理js生成的内容。
做过Html开发的都知道现在很多网站都是用ajax和JavaScript来获取和处理数据,普通爬虫工具已经无法处理js中的内容了。
比如我们在本地新建一个测试web文件text.html,源码如下:
main.html
a {
line-height: 30px;
margin: 20px;
}
var datas = [ {
href : "http://www.jianshu.com/p/8d8edf25850d",
title : "推荐一款编程字体,让代码看着更美"
}, {
href : "http://www.jianshu.com/p/153d9f31288d",
title : "Android 利用Camera实现中轴3D卡牌翻转效果"
}, {
href : "http://www.jianshu.com/p/d6fb0c9c9c26",
title : "【Eclipse】挖掘专属最有用的快捷键组合"
}, {
href : "http://www.jianshu.com/p/72d69b49d135",
title : "【IIS】Windows下利用IIS建立网站并实现局域网共享"
} ];
window.onload = function() {
var infos = document.getElementById("infos");
for( var i = 0 ; i < datas.length ; i++)
{
var a = document.createElement("a");
a.href = datas[i].href ;
a.innerText = datas[i].title;
infos.appendChild(a);
infos.appendChild(document.createElement("br"))
}
}
HtmlUnit 测试网页内容!
通过IIS发布本地网站(参考之前逸峰写的文章:
【IIS】在Windows下使用IIS建立网站,实现局域网共享),
网页在浏览器中显示的效果如下:
网页显示效果.jpg
虽然通过网页检查元素,可以看到body中收录了网页显示的文字内容:
网络评论元素.jpg
但是,它根本无法通过 Jsoup 工具获得!从网页的源码可以看出,我们需要爬取的内容是在页面显示出来后通过ajax和JavaScript加载的。
那么该怎么办?使用本文推荐的开源工具——HtmlUnit,一个可以模拟浏览器的抓包神器!
在官网下载对应的jar包,添加到项目工程的lib中。简单的测试代码如下:
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.ParseException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
/**
* @author 亦枫
* @created_time 2016年1月12日
* @file_user_todo Java测试类
* @blog http://www.jianshu.com/users/1 ... icles
*/
public class JavaTest {
/**
* 入口函数
* @param args
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
try {
WebClient webClient = new WebClient(BrowserVersion.CHROME);
HtmlPage htmlPage = (HtmlPage) webClient.getPage("http://localhost/test.html");
DomNodeList domNodeList = htmlPage.getElementsByTagName("a");
for (int i = 0; i < domNodeList.size(); i++) {
DomElement domElement = (DomElement) domNodeList.get(i);
System.out.println(domElement.asText());
}
webClient.close();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行后,控制台打印出结果:
HtmlUnit测试结果.jpg
可以看出,HtmlUnit 能够抓取 AJAX 和 JavaScript 加载的内容。
HtmlUnit的介绍在官网上很详细。以下内容为易峰翻译的部分内容,供大家参考:
HtmlUnit 是一个基于 Java 的浏览器程序,没有图形界面。它可以调用 HTML 文档并提供 API,让开发人员可以像在普通浏览器上一样获取 Web 内容、填写表单、单击超链接等。
它对 JavaScript 的支持非常好并且还在改进中,可以解析非常复杂的 AJAX 库,模拟不同配置下的 Chrome、Firefox 和 IE 浏览器。
HtmlUnit 通常用于测试目的和检索 网站 信息。
HtmlUnit 提供了许多测试网络请求和爬取网页内容的功能。可以去官网或者其他网站学习使用。
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 100 次浏览 • 2022-02-04 06:12
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键->点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。
使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但是我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ
欢迎补充:)
转载于: 查看全部
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键->点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。

使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但是我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ

欢迎补充:)
转载于:
htmlunit抓取动态网页( 所有无需环境下的浏览器开源项目,你知道几个?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2022-02-02 21:14
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个开源项目,用于面向 .net 的 Web 自动化测试。它为 Web 元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇 查看全部
htmlunit抓取动态网页(
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个开源项目,用于面向 .net 的 Web 自动化测试。它为 Web 元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇
htmlunit抓取动态网页(网络爬虫软件从指定网页获取特定内容的几种解决方案)
网站优化 • 优采云 发表了文章 • 0 个评论 • 40 次浏览 • 2022-02-02 10:14
摘要:对于程序员或开发者来说,拥有编程能力可以让他们轻松、有趣地构建一个网络数据抓取程序。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。
网页数据抓取是指从网站中提取特定内容,而不需要请求网站的API接口来获取内容。“网页数据” 作为网站 用户体验的一部分,例如网页上的文本、图像、声音、视频和动画,它们都是网页数据。
对于程序员或开发人员来说,拥有编程技能使得构建 Web 数据抓取程序变得非常容易和有趣。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。以下是一些使用 优采云采集器 抓取 Web 数据的解决方案:
1、从动态网页中提取内容
网页可以是静态的或动态的。通常,您要提取的网页内容会随着您访问 网站 的时间而改变。通常,这个 网站 是一个动态的网站,它使用 AJAX 技术或其他技术来使 Web 内容保持最新。AJAX 是一种延迟加载和异步更新的脚本技术。通过在后台与服务器交换少量数据,可以在不重新加载整个网页的情况下更新网页的某一部分。
性能特点是当点击网页中的某个选项时,网站的大部分URL不会改变;网页没有完全加载,而只是部分加载了数据,这些数据会发生变化。这时候可以在优采云的“高级选项”元素的“Ajax加载”中设置,就可以抓取Ajax加载的网页数据了。
优采云 中的 AJAX 设置
2、从网页中抓取隐藏的内容
你有没有想过从 网站 获取特定的数据,但是当你触发链接或鼠标悬停在某处时,内容就会出现?例如下图中的网站,需要将鼠标移到选中的彩票上,才能显示类别。对于此功能,您可以设置“鼠标悬停在此链接上”功能,以捕获网页中的隐藏内容。.
将鼠标移到链接上的 content采集 方法
3、从无限滚动的网页中提取内容
滚动到页面底部后,有些网站只有你要提取的一部分数据。例如,在今日头条首页,你需要一直滚动到页面底部才能加载更多的文章内容。无限滚动 网站 通常使用 AJAX 或 JavaScript 向 网站 内容请求附加内容。在这种情况下,您可以设置 AJAX 超时设置并选择滚动方式和滚动时间以从网页中提取内容。
4、 从网络上抓取所有链接
一个普通的网站会收录至少一个超链接,如果你想从一个网页中提取所有的链接,你可以使用优采云来获取网页上发布的所有超链接。
5、从网页中抓取所有文本
有时您需要提取 HTML 文档中的所有文本,即放置在 HTML 标记中,例如
标签或标签)。优采云使您能够提取网页源代码中的所有或特定文本。
6、从网上抓取所有图片
有的朋友有采集网页图片的需求。优采云可以下载网页中图片的URL采集,然后使用优采云专用图片批量下载工具下载我们采集@的图片URL中的图片> 到。下载并保存到本地计算机。 查看全部
htmlunit抓取动态网页(网络爬虫软件从指定网页获取特定内容的几种解决方案)
摘要:对于程序员或开发者来说,拥有编程能力可以让他们轻松、有趣地构建一个网络数据抓取程序。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。
网页数据抓取是指从网站中提取特定内容,而不需要请求网站的API接口来获取内容。“网页数据” 作为网站 用户体验的一部分,例如网页上的文本、图像、声音、视频和动画,它们都是网页数据。
对于程序员或开发人员来说,拥有编程技能使得构建 Web 数据抓取程序变得非常容易和有趣。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。以下是一些使用 优采云采集器 抓取 Web 数据的解决方案:
1、从动态网页中提取内容
网页可以是静态的或动态的。通常,您要提取的网页内容会随着您访问 网站 的时间而改变。通常,这个 网站 是一个动态的网站,它使用 AJAX 技术或其他技术来使 Web 内容保持最新。AJAX 是一种延迟加载和异步更新的脚本技术。通过在后台与服务器交换少量数据,可以在不重新加载整个网页的情况下更新网页的某一部分。
性能特点是当点击网页中的某个选项时,网站的大部分URL不会改变;网页没有完全加载,而只是部分加载了数据,这些数据会发生变化。这时候可以在优采云的“高级选项”元素的“Ajax加载”中设置,就可以抓取Ajax加载的网页数据了。

优采云 中的 AJAX 设置
2、从网页中抓取隐藏的内容
你有没有想过从 网站 获取特定的数据,但是当你触发链接或鼠标悬停在某处时,内容就会出现?例如下图中的网站,需要将鼠标移到选中的彩票上,才能显示类别。对于此功能,您可以设置“鼠标悬停在此链接上”功能,以捕获网页中的隐藏内容。.

将鼠标移到链接上的 content采集 方法
3、从无限滚动的网页中提取内容
滚动到页面底部后,有些网站只有你要提取的一部分数据。例如,在今日头条首页,你需要一直滚动到页面底部才能加载更多的文章内容。无限滚动 网站 通常使用 AJAX 或 JavaScript 向 网站 内容请求附加内容。在这种情况下,您可以设置 AJAX 超时设置并选择滚动方式和滚动时间以从网页中提取内容。

4、 从网络上抓取所有链接
一个普通的网站会收录至少一个超链接,如果你想从一个网页中提取所有的链接,你可以使用优采云来获取网页上发布的所有超链接。
5、从网页中抓取所有文本
有时您需要提取 HTML 文档中的所有文本,即放置在 HTML 标记中,例如
标签或标签)。优采云使您能够提取网页源代码中的所有或特定文本。
6、从网上抓取所有图片
有的朋友有采集网页图片的需求。优采云可以下载网页中图片的URL采集,然后使用优采云专用图片批量下载工具下载我们采集@的图片URL中的图片> 到。下载并保存到本地计算机。
htmlunit抓取动态网页(网站静态页面和动态页面有什么区别,他们的优缺点汇总)
网站优化 • 优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2022-02-02 10:11
网站静态页面和动态页面有什么区别,它们的优缺点是什么?似乎很多 网站 用户对他们了解不多。在这里,我们重点介绍一下外贸网站建设的神灯资讯。总结一下各自的优缺点,仅供参考。
先说静态页面,它是真实存在的,不需要服务器编译,直接加载到客户端的浏览器中显示出来。静态页面需要占用一定的服务器空间,不能独立管理和发布更新的页面。如果要更新网页内容,必须通过FTP软件下载文件,并用网页制作软件进行修改(通过fso等技术除外)。网站的后缀为:htm、html、shtml、xml等常见的静态网页形式。
动态页面是指相对于静态网页的一种网页编程技术。虽然动态页面的页面代码不会改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。不要将动态网页与页面内容是否是动态的混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果没有直接关系。动态网页也可以是纯文本内容或收录各种动画内容。这些只是特定于网页。内容的呈现形式,无论网页是否具有动态效果,只要是通过动态网站技术生成的,都可以称为动态网页。
那么在了解了它们的定义之后,我们再来看看它们的优缺点。
1、静态页面加载速度快。加载静态页面时,无需搜索数据库。动态页面比较麻烦。网页接收到用户指令后,将指令带到数据库中,找到指令对应的数据,然后传递给服务器,通过服务器的编译,将动态页面编译成标准的HTML代码,传递给用户的浏览器,以便用户可以看到网页。结果,加载时间变长,用户不愿意再次访问您的页面。
2、静态页面的内容比较稳定,容易被搜索引擎搜索到收录,动态页面是用户输入指令后形成的页面,没有这样的页面,搜索引擎会只抓取现成的页面,不自行进入。虽然现在大部分搜索引擎都支持动态页面的爬取,但毕竟还不够完善。
3、静态网页没有数据库的支持,网站制作和维护的工作量比较大。因此,在网站信息量很大的情况下,很难完全依赖静态网页制作方式。动态网页一般基于数据库技术,可以大大减少网站维护的工作量。
4、静态网页交互性较差,功能有限。网站 使用动态网页技术可以实现更多功能,如用户注册、用户登录、在线调查、用户管理、订单管理等。
一般来说,网站构造的基础是静态网页,静态网页和动态网页并非互不兼容。为了提高网站中的搜索速度,使用了动态网页技术。网站,它还可以将网页内容转成静态网页运行,将网页转成静态是网站开发的一个很好的方法,可以提高网页打开速度. 查看全部
htmlunit抓取动态网页(网站静态页面和动态页面有什么区别,他们的优缺点汇总)
网站静态页面和动态页面有什么区别,它们的优缺点是什么?似乎很多 网站 用户对他们了解不多。在这里,我们重点介绍一下外贸网站建设的神灯资讯。总结一下各自的优缺点,仅供参考。
先说静态页面,它是真实存在的,不需要服务器编译,直接加载到客户端的浏览器中显示出来。静态页面需要占用一定的服务器空间,不能独立管理和发布更新的页面。如果要更新网页内容,必须通过FTP软件下载文件,并用网页制作软件进行修改(通过fso等技术除外)。网站的后缀为:htm、html、shtml、xml等常见的静态网页形式。
动态页面是指相对于静态网页的一种网页编程技术。虽然动态页面的页面代码不会改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。不要将动态网页与页面内容是否是动态的混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果没有直接关系。动态网页也可以是纯文本内容或收录各种动画内容。这些只是特定于网页。内容的呈现形式,无论网页是否具有动态效果,只要是通过动态网站技术生成的,都可以称为动态网页。
那么在了解了它们的定义之后,我们再来看看它们的优缺点。
1、静态页面加载速度快。加载静态页面时,无需搜索数据库。动态页面比较麻烦。网页接收到用户指令后,将指令带到数据库中,找到指令对应的数据,然后传递给服务器,通过服务器的编译,将动态页面编译成标准的HTML代码,传递给用户的浏览器,以便用户可以看到网页。结果,加载时间变长,用户不愿意再次访问您的页面。
2、静态页面的内容比较稳定,容易被搜索引擎搜索到收录,动态页面是用户输入指令后形成的页面,没有这样的页面,搜索引擎会只抓取现成的页面,不自行进入。虽然现在大部分搜索引擎都支持动态页面的爬取,但毕竟还不够完善。
3、静态网页没有数据库的支持,网站制作和维护的工作量比较大。因此,在网站信息量很大的情况下,很难完全依赖静态网页制作方式。动态网页一般基于数据库技术,可以大大减少网站维护的工作量。
4、静态网页交互性较差,功能有限。网站 使用动态网页技术可以实现更多功能,如用户注册、用户登录、在线调查、用户管理、订单管理等。
一般来说,网站构造的基础是静态网页,静态网页和动态网页并非互不兼容。为了提高网站中的搜索速度,使用了动态网页技术。网站,它还可以将网页内容转成静态网页运行,将网页转成静态是网站开发的一个很好的方法,可以提高网页打开速度.
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
网站优化 • 优采云 发表了文章 • 0 个评论 • 45 次浏览 • 2022-02-01 18:04
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,是指通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
所以将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而通过java代码实现页面的动态变化。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论! 查看全部
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,是指通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
所以将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而通过java代码实现页面的动态变化。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论!
htmlunit抓取动态网页( 所有无需环境下的浏览器开源项目,你知道几个?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 57 次浏览 • 2022-02-01 17:16
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个面向 .net 的网络自动化测试的开源项目。它为网页元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇 查看全部
htmlunit抓取动态网页(
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个面向 .net 的网络自动化测试的开源项目。它为网页元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇
htmlunit抓取动态网页(南京凯壹良seo怎么看来百度对于动态网页的抓取都不尽如人意)
网站优化 • 优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2022-02-22 04:22
无论网站写什么语言的seo,总会涉及到两个概念,动态的和静态的。百度官方发布了关于动态页面和静态页面的说明,称对动态网站和静态网站一视同仁,没有区别对待爬取,因此成功误导了一批网站优化人员。
南京凯易良seo看来百度对动态网页的抓取并不理想,尤其是网站收录方面。Kai Yiliang seo 已经玩wordpress 个人博客一年半了,明显感觉wordpress 博客的收录 很差。百度本身不适合博客类网站收录,你可以看看有多少收录自己的新浪博客和网易博客。这和博客本身的属性有关,体现在博客的使用上。插件、下载的模板、网址设置等。要知道wordpress是美国技术人员开发的程序,比较适合谷歌的算法。百度和谷歌是不同的,所以SEO不应该被百度误导。使用 wordpress 构建个人博客是可以的。
另一个凯一亮seo接触到的动态页面是用asp写的,这种老语言有它的优势,但是收录和wordpress一样难过。老asp站点的收录还是不错的,这关系到域名的长期优势,但是新的asp网站收录实在是让SEO们头疼,也没有时间研究技术代码。事物。
所以建议seos在开网站前一定要考虑网站用什么语言,这对后期的优化影响很大,体现在优化的难度和时间上。如果你有足够的经验,就不用担心这些问题,因为它们在技术上是可以克服的。
本文章“百度从互联网的采集整理上区分动态网页和静态网页,如有版权问题,请联系本网站删除!” 当前文章地址:更多相关南京seo网站优化文章请阅读查看! 查看全部
htmlunit抓取动态网页(南京凯壹良seo怎么看来百度对于动态网页的抓取都不尽如人意)
无论网站写什么语言的seo,总会涉及到两个概念,动态的和静态的。百度官方发布了关于动态页面和静态页面的说明,称对动态网站和静态网站一视同仁,没有区别对待爬取,因此成功误导了一批网站优化人员。
南京凯易良seo看来百度对动态网页的抓取并不理想,尤其是网站收录方面。Kai Yiliang seo 已经玩wordpress 个人博客一年半了,明显感觉wordpress 博客的收录 很差。百度本身不适合博客类网站收录,你可以看看有多少收录自己的新浪博客和网易博客。这和博客本身的属性有关,体现在博客的使用上。插件、下载的模板、网址设置等。要知道wordpress是美国技术人员开发的程序,比较适合谷歌的算法。百度和谷歌是不同的,所以SEO不应该被百度误导。使用 wordpress 构建个人博客是可以的。
另一个凯一亮seo接触到的动态页面是用asp写的,这种老语言有它的优势,但是收录和wordpress一样难过。老asp站点的收录还是不错的,这关系到域名的长期优势,但是新的asp网站收录实在是让SEO们头疼,也没有时间研究技术代码。事物。
所以建议seos在开网站前一定要考虑网站用什么语言,这对后期的优化影响很大,体现在优化的难度和时间上。如果你有足够的经验,就不用担心这些问题,因为它们在技术上是可以克服的。
本文章“百度从互联网的采集整理上区分动态网页和静态网页,如有版权问题,请联系本网站删除!” 当前文章地址:更多相关南京seo网站优化文章请阅读查看!
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2022-02-19 04:00
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论! 查看全部
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论!
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2022-02-19 03:29
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论! 查看全部
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,就是通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
因此,将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而可以通过java代码动态改变页面。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论!
htmlunit抓取动态网页( 开发爬虫项目有通用性吗?如何构建基于配置化的分布式爬虫应用?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 141 次浏览 • 2022-02-18 20:10
开发爬虫项目有通用性吗?如何构建基于配置化的分布式爬虫应用?)
一起
在我工作的很多公司里,有很多领域,比如房地产、电商、广告等领域。虽然业务差别很大,但都涉及到爬虫领域。开发了更多爬虫项目后,自然会面临一个问题——
l 这些开发的爬虫项目通用吗?
l 是否可以以更低的成本完成一个新的爬虫需求?
l 在维护和运行过程中,是否可以工具化构建基于配置的分布式爬虫应用?
这就是我们今天要讨论的内容。
二 项目要求
在项目开始时,我们尝试从使用的脚提出一些要求。
1. 分布式爬取
由于爬取的量可能非常大,一台机器不足以处理超过一百万的爬取任务,所以分布式爬虫应用是第一个要面对和解决的问题。
2. 模块化、轻量级
我们将爬虫应用分为四个角色:“应用层、服务层、业务处理层、调度层”。
3. 可管理、可监控
管理监控是一个系统,即配置可以管理,运行可以实时监控。当系统正常运行时,可以更改爬虫的配置。一旦实时监控爬虫出现异常,可以实时修正配置进行干预。一切都可以通过UI界面进行操作。
4. 通用的,可扩展的。
爬虫业务往往是多变的,不同领域的爬取需求是不一样的。例如,房源采集包括图像采集、社区信息采集、房源去重等模块。新闻抓取包括内容抓取、文本提取、信息摘要等。
因此,系统需要能够支持业务扩展需求,能够支持不同业务使用相同的框架进行应用开发。
三模块分解
针对业务需求,我们将系统分解为多个应用模块。
应用层
应用层适用于管理员和系统维护人员。主要分为两个模块,系统配置模块和运行管理模块。
l 系统配置模块:系统配置模块包括抓取网站管理配置、在线测试等功能。
l 运营管理模块:运营管理模块包括实时抓拍量统计、分析、准确率等,甚至包括故障原因、故障数量。
系统操作人员可以根据操作模块得到实时反馈,并使用系统配置模块进行配置修正。在线测试无误后,配置生效,然后实时监控新配置的效果。
服务层
服务层是整个系统传输的中心,相当于整个分布式集中式系统总线和数据总线。服务层提供http/thrift接口,读取数据库,输出配置信息。
一种。提供网站爬虫配置界面。实时从数据库中读取配置信息,响应业务层的配置请求。
湾。提供业务层的输出写入接口。实时接收业务层爬取的信息汇总,包括正确数据量、错误数据量、错误原因等。
C。提供实时报表统计分析。响应应用层的运营管理模块,查询数据库,实时提供数据分析报告。
业务处理层
业务处理层是整个爬虫系统的核心,可以划分为多个应用服务器进行处理。业务处理层主要包括解决两件事。
l 如何获取网址
l 获取到url后如何处理
(一) 如何获取 url
对于爬虫来说,如何获取 url 非常重要。我们将此过程定义为发现系统。对于发现系统来说,目标是如何发现要爬取的网站的详细URL列表,并尽可能的发现。
假设场景 A
我们来看一个电商网站:打开首页--打开分类页面--可能有多个分类页面--逐层点击--直到最小的分类页面。
当你打开这个分类页面时,你会发现分类页面下的所有分页页面。如果一次向下滚动一页,则可以获取类别页面中的所有产品。
假设情景 B
我们去买车吧网站:打开首页——找到品牌页——然后找到车系——最后找到车型页。
通过以上场景分析,我们可以得出一个结论,人们可以非常智能的找到所有需要爬取的详细页面,即电商产品和车型页面。那么,是否可以通过配置来模拟这个过程呢?
请看下图:
备注如下:
1. 根信息:
定义发现模块的入口页面,就像人们打开公交车站的网页一样,后续的发现都是从这些入口页面开始的。
这里给出的例子是汽车网络的品牌列表页面,根据“模板化”应用变量的配置,总共有100个入口页面。
2. 步骤:
依次遍历这100个入口页面,分别执行steps中定义的步骤。查看和浏览机器模拟人类的方式。
每一步都使用“link_module”定义的类进行逻辑处理。
一种。读取入口页面的html,结合“sub_prefix”、“sub_suffix”和“select”定义的内容,获取页面子区域的html。
湾。使用“link_match_method”方法(包括前缀收录、匹配等)提取子区域的链接。
C。每个链接都匹配“link_pattern”,匹配成功的url进入下一步。
d。每一步得到的url都会自动转发到下一步处理。处理逻辑对上述ac递归,直到“last_step”为真。
这里,“last_step”为真时找到的url就是发现系统最终需要获取的url列表。发现系统总结,通过配置方法,结合人类的浏览习惯,经过数步迭代,最终得到网站的详细页面url列表。
由于每个步骤的提取链接规则和步骤数据都是手动定义的,因此可以适应网站的大部分发现系统。当然,越复杂的网站发现配置可能会越来越复杂,但同样如此。
(二)获取到url后如何处理
前提当然是每个业务的处理都不一样,包括提取页面属性、文本提取、图片获取,甚至与当前系统对接的功能。
由于业务处理不一致,自然会想到通过配置来定义责任链系统,就像著名框架Netty中的Pipeline设计一样。在处理的过程中,定义了一个Context上下文处理类,所有的中间结果都挂在这个Context中。
描述比较空洞,但还是以实际案例为准。
备注如下:
获取 url 后,读取配置并在 url 匹配“site”时应用当前的“site”规则。
1. pipeline 定义了责任链的处理
这里的定义是“爬取模块、Javascript处理模块、通用解析模块”。对应的处理如下:
先执行爬取模块获取html。然后执行Javascript处理模块,输入为html,解析html。这可能是评论或价格。简单来说就是先处理动态加载项目,再处理“通用解析模块”。
2. "parser_rules" 定义解析模块
最终的输出是kv,在java中是map,在python中是dict。即从上一步的html中,找到每个推荐的“sizzle”,执行“prefix”、“suffix”去掉前缀和后缀(过滤为“price:xxx元,前缀“price:”,后缀为元)。
顺便说一句,sizzle 也是一种开源技术。据说大名鼎鼎的Jquery也是一个“咝咝”的引擎。Java可以使用Jsoup解析处理。
你怎么知道要获取什么“嘶嘶作响”的内容?具体可以结合firebug插件,选择即可获得。选择后,可以结合应用层的管理工具进行测试。
3. “需要”
可以看到,配置项中有“isrequire”,表示是否需要这个内容。如果在实际处理中需要而无法获取,则在爬取过程中会记录错误,而错误的原因自然是“$key is null”。另外,每个模块都可能出错,一旦出错,以后就不需要再执行了。
因此,在爬取过程中,业务处理层从服务层获取一批url(默认为100个)后,处理完这100个url后,会上报给服务层,上报内容为:
当前任务处理机在什么时间处理100页。不同的网站有多少成功,有多少失败,有多少模块失败,解析模块中有多少字段失败。
所有这些信息都是实时统计的,并在运行监控系统中以图形方式绘制。必要时可发出警报,维修人员可实时介入。
Q:问个问题,如果我加了一个网站怎么办?
A:其实很简单,再增加一个配置就行了。业务定义管道。如果有解析需求,填写对应的解析项。
以上两个系统,发现系统和处理系统,在我们的实际生产中经过以下步骤运行。
一种。发现系统会累积发现要爬取的详细页面网站,因为它是一个累积和持续的过程。因此,您可以确保继续无限接近 网站 的 100% 页面。
湾。处理系统通过服务层获取配置信息(可能由维护人员实时修正)和待抓取列表进行处理。
待抓取的列表根据业务的优先级分为普通队列和优先级队列,通过任务调度系统统一管理和配置。
调度层
l 调度层主要是业务系统。
l 添加任务调度器网站
l 网站 发现频率,包括增量发现频率和完全发现频率
l 网站抢优先级被推入队列
l 断点续传管理
我...
四系统架构设计
l 从业务模块来看
应用层、服务层、业务处理层、调度层
l 从功能系统来看
发现系统、抓取系统、配置系统、监控系统
l 从可扩展性的角度
自定义责任链,自定义属性抽取
l 从实时角度
实时捕捉,实时配置有效,实时监控,实时测试
l 从系统架构来看
分布式架构,服务层主从切换设计,轻量级(只依赖队列、数据库、java)
五个传说
①
②
③
爬虫模块ui二(1.6任务配置):
定义每个爬虫任务的处理和执行责任链。不同的爬虫任务可以有不同的处理链。对于系统来说,处理每一个待爬取的url都会按照责任链的顺序执行。后处理类是在一批任务执行后(比如上面的100个url)进行批量提交的方法。比如文件登陆、存储、推送到线上系统等。通过定义任务处理,可以自定义各种场景的爬虫业务,增加系统的灵活性,无需编码。
④
属性配置:
如图,如果维护者添加了测试的url,定义了要提取的属性,就可以在线定义页面对应的属性输出,查看即可。在增加便利性和可测试性的基础上,可以灵活选择页面的任意属性。值得一提的是,sizzle的配置可以通过firefox插件获取。
⑤
1.9查看详情:
在爬虫系统运行过程中,几乎可以实时监控任务。由于爬虫任务将爬取状态实时写入数据库,因此可以通过ui界面进行管理和监控。1. 监控:监控当前时间爬虫任务成功数、错误数、什么模块出错,甚至是属性提取错误。2.管理:维护人员观察监控效果后,可以实时编辑管理(见上图),满足不同网站修改的需要。所有编辑实时生效。编辑后无需重启服务,可实时监控爬虫任务的最新效果。
高级建筑师
十余年数据研发经验,擅长数据处理,如爬虫、搜索引擎、大数据应用的高并发。历任架构师、研发经理等职务。曾主导开发大型爬虫、搜索引擎和大数据广告DMP系统。目前负责奇安科技数据平台的开发建设。 查看全部
htmlunit抓取动态网页(
开发爬虫项目有通用性吗?如何构建基于配置化的分布式爬虫应用?)

一起
在我工作的很多公司里,有很多领域,比如房地产、电商、广告等领域。虽然业务差别很大,但都涉及到爬虫领域。开发了更多爬虫项目后,自然会面临一个问题——
l 这些开发的爬虫项目通用吗?
l 是否可以以更低的成本完成一个新的爬虫需求?
l 在维护和运行过程中,是否可以工具化构建基于配置的分布式爬虫应用?
这就是我们今天要讨论的内容。
二 项目要求
在项目开始时,我们尝试从使用的脚提出一些要求。
1. 分布式爬取
由于爬取的量可能非常大,一台机器不足以处理超过一百万的爬取任务,所以分布式爬虫应用是第一个要面对和解决的问题。
2. 模块化、轻量级
我们将爬虫应用分为四个角色:“应用层、服务层、业务处理层、调度层”。
3. 可管理、可监控
管理监控是一个系统,即配置可以管理,运行可以实时监控。当系统正常运行时,可以更改爬虫的配置。一旦实时监控爬虫出现异常,可以实时修正配置进行干预。一切都可以通过UI界面进行操作。
4. 通用的,可扩展的。
爬虫业务往往是多变的,不同领域的爬取需求是不一样的。例如,房源采集包括图像采集、社区信息采集、房源去重等模块。新闻抓取包括内容抓取、文本提取、信息摘要等。
因此,系统需要能够支持业务扩展需求,能够支持不同业务使用相同的框架进行应用开发。
三模块分解
针对业务需求,我们将系统分解为多个应用模块。
应用层
应用层适用于管理员和系统维护人员。主要分为两个模块,系统配置模块和运行管理模块。
l 系统配置模块:系统配置模块包括抓取网站管理配置、在线测试等功能。
l 运营管理模块:运营管理模块包括实时抓拍量统计、分析、准确率等,甚至包括故障原因、故障数量。
系统操作人员可以根据操作模块得到实时反馈,并使用系统配置模块进行配置修正。在线测试无误后,配置生效,然后实时监控新配置的效果。
服务层
服务层是整个系统传输的中心,相当于整个分布式集中式系统总线和数据总线。服务层提供http/thrift接口,读取数据库,输出配置信息。
一种。提供网站爬虫配置界面。实时从数据库中读取配置信息,响应业务层的配置请求。
湾。提供业务层的输出写入接口。实时接收业务层爬取的信息汇总,包括正确数据量、错误数据量、错误原因等。
C。提供实时报表统计分析。响应应用层的运营管理模块,查询数据库,实时提供数据分析报告。
业务处理层
业务处理层是整个爬虫系统的核心,可以划分为多个应用服务器进行处理。业务处理层主要包括解决两件事。
l 如何获取网址
l 获取到url后如何处理
(一) 如何获取 url
对于爬虫来说,如何获取 url 非常重要。我们将此过程定义为发现系统。对于发现系统来说,目标是如何发现要爬取的网站的详细URL列表,并尽可能的发现。
假设场景 A
我们来看一个电商网站:打开首页--打开分类页面--可能有多个分类页面--逐层点击--直到最小的分类页面。
当你打开这个分类页面时,你会发现分类页面下的所有分页页面。如果一次向下滚动一页,则可以获取类别页面中的所有产品。
假设情景 B
我们去买车吧网站:打开首页——找到品牌页——然后找到车系——最后找到车型页。
通过以上场景分析,我们可以得出一个结论,人们可以非常智能的找到所有需要爬取的详细页面,即电商产品和车型页面。那么,是否可以通过配置来模拟这个过程呢?
请看下图:

备注如下:
1. 根信息:
定义发现模块的入口页面,就像人们打开公交车站的网页一样,后续的发现都是从这些入口页面开始的。
这里给出的例子是汽车网络的品牌列表页面,根据“模板化”应用变量的配置,总共有100个入口页面。
2. 步骤:
依次遍历这100个入口页面,分别执行steps中定义的步骤。查看和浏览机器模拟人类的方式。
每一步都使用“link_module”定义的类进行逻辑处理。
一种。读取入口页面的html,结合“sub_prefix”、“sub_suffix”和“select”定义的内容,获取页面子区域的html。
湾。使用“link_match_method”方法(包括前缀收录、匹配等)提取子区域的链接。
C。每个链接都匹配“link_pattern”,匹配成功的url进入下一步。
d。每一步得到的url都会自动转发到下一步处理。处理逻辑对上述ac递归,直到“last_step”为真。
这里,“last_step”为真时找到的url就是发现系统最终需要获取的url列表。发现系统总结,通过配置方法,结合人类的浏览习惯,经过数步迭代,最终得到网站的详细页面url列表。
由于每个步骤的提取链接规则和步骤数据都是手动定义的,因此可以适应网站的大部分发现系统。当然,越复杂的网站发现配置可能会越来越复杂,但同样如此。
(二)获取到url后如何处理
前提当然是每个业务的处理都不一样,包括提取页面属性、文本提取、图片获取,甚至与当前系统对接的功能。
由于业务处理不一致,自然会想到通过配置来定义责任链系统,就像著名框架Netty中的Pipeline设计一样。在处理的过程中,定义了一个Context上下文处理类,所有的中间结果都挂在这个Context中。
描述比较空洞,但还是以实际案例为准。

备注如下:
获取 url 后,读取配置并在 url 匹配“site”时应用当前的“site”规则。
1. pipeline 定义了责任链的处理
这里的定义是“爬取模块、Javascript处理模块、通用解析模块”。对应的处理如下:
先执行爬取模块获取html。然后执行Javascript处理模块,输入为html,解析html。这可能是评论或价格。简单来说就是先处理动态加载项目,再处理“通用解析模块”。
2. "parser_rules" 定义解析模块
最终的输出是kv,在java中是map,在python中是dict。即从上一步的html中,找到每个推荐的“sizzle”,执行“prefix”、“suffix”去掉前缀和后缀(过滤为“price:xxx元,前缀“price:”,后缀为元)。
顺便说一句,sizzle 也是一种开源技术。据说大名鼎鼎的Jquery也是一个“咝咝”的引擎。Java可以使用Jsoup解析处理。
你怎么知道要获取什么“嘶嘶作响”的内容?具体可以结合firebug插件,选择即可获得。选择后,可以结合应用层的管理工具进行测试。
3. “需要”
可以看到,配置项中有“isrequire”,表示是否需要这个内容。如果在实际处理中需要而无法获取,则在爬取过程中会记录错误,而错误的原因自然是“$key is null”。另外,每个模块都可能出错,一旦出错,以后就不需要再执行了。
因此,在爬取过程中,业务处理层从服务层获取一批url(默认为100个)后,处理完这100个url后,会上报给服务层,上报内容为:
当前任务处理机在什么时间处理100页。不同的网站有多少成功,有多少失败,有多少模块失败,解析模块中有多少字段失败。
所有这些信息都是实时统计的,并在运行监控系统中以图形方式绘制。必要时可发出警报,维修人员可实时介入。
Q:问个问题,如果我加了一个网站怎么办?
A:其实很简单,再增加一个配置就行了。业务定义管道。如果有解析需求,填写对应的解析项。
以上两个系统,发现系统和处理系统,在我们的实际生产中经过以下步骤运行。
一种。发现系统会累积发现要爬取的详细页面网站,因为它是一个累积和持续的过程。因此,您可以确保继续无限接近 网站 的 100% 页面。
湾。处理系统通过服务层获取配置信息(可能由维护人员实时修正)和待抓取列表进行处理。
待抓取的列表根据业务的优先级分为普通队列和优先级队列,通过任务调度系统统一管理和配置。
调度层
l 调度层主要是业务系统。
l 添加任务调度器网站
l 网站 发现频率,包括增量发现频率和完全发现频率
l 网站抢优先级被推入队列
l 断点续传管理
我...
四系统架构设计
l 从业务模块来看
应用层、服务层、业务处理层、调度层
l 从功能系统来看
发现系统、抓取系统、配置系统、监控系统
l 从可扩展性的角度
自定义责任链,自定义属性抽取
l 从实时角度
实时捕捉,实时配置有效,实时监控,实时测试
l 从系统架构来看
分布式架构,服务层主从切换设计,轻量级(只依赖队列、数据库、java)
五个传说
①

②

③

爬虫模块ui二(1.6任务配置):
定义每个爬虫任务的处理和执行责任链。不同的爬虫任务可以有不同的处理链。对于系统来说,处理每一个待爬取的url都会按照责任链的顺序执行。后处理类是在一批任务执行后(比如上面的100个url)进行批量提交的方法。比如文件登陆、存储、推送到线上系统等。通过定义任务处理,可以自定义各种场景的爬虫业务,增加系统的灵活性,无需编码。
④

属性配置:
如图,如果维护者添加了测试的url,定义了要提取的属性,就可以在线定义页面对应的属性输出,查看即可。在增加便利性和可测试性的基础上,可以灵活选择页面的任意属性。值得一提的是,sizzle的配置可以通过firefox插件获取。
⑤

1.9查看详情:
在爬虫系统运行过程中,几乎可以实时监控任务。由于爬虫任务将爬取状态实时写入数据库,因此可以通过ui界面进行管理和监控。1. 监控:监控当前时间爬虫任务成功数、错误数、什么模块出错,甚至是属性提取错误。2.管理:维护人员观察监控效果后,可以实时编辑管理(见上图),满足不同网站修改的需要。所有编辑实时生效。编辑后无需重启服务,可实时监控爬虫任务的最新效果。
高级建筑师
十余年数据研发经验,擅长数据处理,如爬虫、搜索引擎、大数据应用的高并发。历任架构师、研发经理等职务。曾主导开发大型爬虫、搜索引擎和大数据广告DMP系统。目前负责奇安科技数据平台的开发建设。
htmlunit抓取动态网页(模拟运行1.HTMLUNIT的基本功能分析工具展示 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2022-02-18 07:15
)
HTML单元
htmlunit 是一个开源的java页面分析工具。阅读完页面后,可以有效地使用htmlunit分析页面上的内容。该项目可以模拟浏览器的操作,称为java浏览器的开源实现。它是一个没有快速运行界面的浏览器。它是junit的扩展之一,使用Rhinojs引擎。模拟js运行
1. HTMLUNIT的基本功能展示
首先我们新建一个Maven普通客户端项目,然后打开pom.xml
引入 htmlunit 支持:
1
2 net.sourceforge.htmlunit
3 htmlunit
4 2.26
5
6
7
然后我们写一个测试类来解析获取网页html和网页文本,和httpClient类似,但是底层执行过程默认是js执行过程(当然htmlunit提供了关闭js解析的设置);
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
5import com.gargoylesoftware.htmlunit.WebClient;
6import com.gargoylesoftware.htmlunit.html.HtmlPage;
7
8public class HtmlUnitTest {
9
10 public static void main(String[] args) {
11 WebClient webClient=new WebClient(); // 实例化Web客户端
12 try {
13 HtmlPage page=webClient.getPage("http://www.baidu.com"); // 解析获取页面
14 System.out.println("网页html:"+page.asXml()); // 获取Html
15 System.out.println("====================");
16 System.out.println("网页文本:"+page.asText()); // 获取文本
17 } catch (FailingHttpStatusCodeException e) {
18 // TODO Auto-generated catch block
19 e.printStackTrace();
20 } catch (MalformedURLException e) {
21 // TODO Auto-generated catch block
22 e.printStackTrace();
23 } catch (IOException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }finally{
27 webClient.close(); // 关闭客户端,释放内存
28 }
29 }
30}
31
32
我们之前的测试代码是直接请求,有的网站服务器防火墙会直接拒绝访问。
我们现在使用htmlunit来模拟浏览器请求;主要是添加一些头信息;
这是我们用火狐调试工具看到的请求头中的属性,当然上面还有返回的头信息;
我们使用htmlunit来模拟浏览器执行,内置可以模拟IE、Firefox、Google;
WebClient构造函数中有一个重载方法,可以添加指定的版本属性;
完整代码:
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.HtmlPage;
8
9public class HtmlUnitTest {
10
11 public static void main(String[] args) {
12 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
13 try {
14 HtmlPage page=webClient.getPage("http://www.java1234.com"); // 解析获取页面
15 System.out.println("网页html:"+page.asXml()); // 获取Html
16 System.out.println("====================");
17 System.out.println("网页文本:"+page.asText()); // 获取文本
18 } catch (FailingHttpStatusCodeException e) {
19 // TODO Auto-generated catch block
20 e.printStackTrace();
21 } catch (MalformedURLException e) {
22 // TODO Auto-generated catch block
23 e.printStackTrace();
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }finally{
28 webClient.close(); // 关闭客户端,释放内存
29 }
30 }
31}
32
33
htmlunit提供了丰富的api来获取指定元素jsoup,有些htmlunit也有;
这里我们举一个例子:
<p>1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.DomElement;
8import com.gargoylesoftware.htmlunit.html.DomNodeList;
9import com.gargoylesoftware.htmlunit.html.HtmlDivision;
10import com.gargoylesoftware.htmlunit.html.HtmlListItem;
11import com.gargoylesoftware.htmlunit.html.HtmlPage;
12
13public class HtmlUnitTest2 {
14
15 public static void main(String[] args) {
16 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
17 try {
18 HtmlPage page=webClient.getPage("http://www.baidu.com");
19 HtmlDivision div=page.getHtmlElementById("navMenu"); // 查找指定id的html dom元素
20 System.out.println(div.asXml());
21 System.out.println("======================");
22 DomNodeList aList=page.getElementsByTagName("a"); // 根据tag名称查询所有tag
23 for(int i=0;i 查看全部
htmlunit抓取动态网页(模拟运行1.HTMLUNIT的基本功能分析工具展示
)
HTML单元
htmlunit 是一个开源的java页面分析工具。阅读完页面后,可以有效地使用htmlunit分析页面上的内容。该项目可以模拟浏览器的操作,称为java浏览器的开源实现。它是一个没有快速运行界面的浏览器。它是junit的扩展之一,使用Rhinojs引擎。模拟js运行
1. HTMLUNIT的基本功能展示
首先我们新建一个Maven普通客户端项目,然后打开pom.xml
引入 htmlunit 支持:
1
2 net.sourceforge.htmlunit
3 htmlunit
4 2.26
5
6
7
然后我们写一个测试类来解析获取网页html和网页文本,和httpClient类似,但是底层执行过程默认是js执行过程(当然htmlunit提供了关闭js解析的设置);
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
5import com.gargoylesoftware.htmlunit.WebClient;
6import com.gargoylesoftware.htmlunit.html.HtmlPage;
7
8public class HtmlUnitTest {
9
10 public static void main(String[] args) {
11 WebClient webClient=new WebClient(); // 实例化Web客户端
12 try {
13 HtmlPage page=webClient.getPage("http://www.baidu.com"); // 解析获取页面
14 System.out.println("网页html:"+page.asXml()); // 获取Html
15 System.out.println("====================");
16 System.out.println("网页文本:"+page.asText()); // 获取文本
17 } catch (FailingHttpStatusCodeException e) {
18 // TODO Auto-generated catch block
19 e.printStackTrace();
20 } catch (MalformedURLException e) {
21 // TODO Auto-generated catch block
22 e.printStackTrace();
23 } catch (IOException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }finally{
27 webClient.close(); // 关闭客户端,释放内存
28 }
29 }
30}
31
32
我们之前的测试代码是直接请求,有的网站服务器防火墙会直接拒绝访问。
我们现在使用htmlunit来模拟浏览器请求;主要是添加一些头信息;
这是我们用火狐调试工具看到的请求头中的属性,当然上面还有返回的头信息;
我们使用htmlunit来模拟浏览器执行,内置可以模拟IE、Firefox、Google;
WebClient构造函数中有一个重载方法,可以添加指定的版本属性;
完整代码:
1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.HtmlPage;
8
9public class HtmlUnitTest {
10
11 public static void main(String[] args) {
12 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
13 try {
14 HtmlPage page=webClient.getPage("http://www.java1234.com"); // 解析获取页面
15 System.out.println("网页html:"+page.asXml()); // 获取Html
16 System.out.println("====================");
17 System.out.println("网页文本:"+page.asText()); // 获取文本
18 } catch (FailingHttpStatusCodeException e) {
19 // TODO Auto-generated catch block
20 e.printStackTrace();
21 } catch (MalformedURLException e) {
22 // TODO Auto-generated catch block
23 e.printStackTrace();
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }finally{
28 webClient.close(); // 关闭客户端,释放内存
29 }
30 }
31}
32
33
htmlunit提供了丰富的api来获取指定元素jsoup,有些htmlunit也有;
这里我们举一个例子:
<p>1import java.io.IOException;
2import java.net.MalformedURLException;
3
4import com.gargoylesoftware.htmlunit.BrowserVersion;
5import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
6import com.gargoylesoftware.htmlunit.WebClient;
7import com.gargoylesoftware.htmlunit.html.DomElement;
8import com.gargoylesoftware.htmlunit.html.DomNodeList;
9import com.gargoylesoftware.htmlunit.html.HtmlDivision;
10import com.gargoylesoftware.htmlunit.html.HtmlListItem;
11import com.gargoylesoftware.htmlunit.html.HtmlPage;
12
13public class HtmlUnitTest2 {
14
15 public static void main(String[] args) {
16 WebClient webClient=new WebClient(BrowserVersion.FIREFOX_52); // 实例化Web客户端
17 try {
18 HtmlPage page=webClient.getPage("http://www.baidu.com");
19 HtmlDivision div=page.getHtmlElementById("navMenu"); // 查找指定id的html dom元素
20 System.out.println(div.asXml());
21 System.out.println("======================");
22 DomNodeList aList=page.getElementsByTagName("a"); // 根据tag名称查询所有tag
23 for(int i=0;i
htmlunit抓取动态网页(1.HtmlUnit中文文档获取页面中特定的元素tips:1.)
网站优化 • 优采云 发表了文章 • 0 个评论 • 117 次浏览 • 2022-02-18 07:14
1.HtmlUnit 简介
HtmlUnit 是一个 java 无界面浏览器库。它模拟 HTML 文档并提供相应的 API,允许您调用页面、填写表单、单击链接等,就像您在“普通”浏览器中所做的一样。它有相当不错的 JavaScript 支持(仍在改进),甚至能够处理相当复杂的 AJAX 库,根据使用的配置模拟 Chrome、Firefox 或 Internet Explorer。它通常用于测试目的或从 网站 检索信息。
HtmlUnit 不是一个通用的单元测试框架。它是一种模拟浏览器以进行测试的方法,旨在用于其他测试框架,例如 JUnit 或 TestNG。有关介绍,请参见文档“HtmlUnit 入门”。HtmlUnit 用作不同的开源工具,如 Canoo WebTest、JWebUnit、WebDriver、JSFUnit、WETATOR、Celerity、Spring MVC Test HtmlUnit 作为底层“浏览器”。
HtmlUnit 最初由 Gargoyle Software 的 Mike Bowler 编写,并在 Apache 2 许可下发布。从那时起,它收到了许多其他开发者的贡献,今天将得到他们的帮助。
几年前,我在为购物网站 做数据采集工作时偶然发现了HtmlUnit。记得当时页面上的价格数据是抓不到的,httpfox也无法追踪到价格数据的url。在我不知所措的时候,HtmlUnit出现了,帮我解决了问题。所以今天我要说声谢谢并向大家推荐HtmlUnit。
2.htmlUnit 中文文档
3.1 获取页面的TITLE、XML代码、文本
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//创建一个webclient
WebClient webClient = new WebClient();
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
//获取页面
HtmlPage page = webClient.getPage("http://www.baidu.com/");
//获取页面的TITLE
str = page.getTitleText();
System.out.println(str);
//获取页面的XML代码
str = page.asXml();
System.out.println(str);
//获取页面的文本
str = page.asText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}
3.2 用不同版本的浏览器打开
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//使用FireFox读取网页
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = webClient.getPage("http://www.baidu.com/");
str = page.getTitleText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}
3.3 在页面中查找特定元素
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//通过id获得"百度一下"按钮
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
System.out.println(btn.getDefaultValue());
//关闭webclient
webClient.closeAllWindows();
}
}
提示:有些元素没有 id 和 name 或其他节点。您可以通过查找其子节点和父节点之间的规律性来获取该元素。具体方法请参考:
它的核心代码是:
final HtmlPage nextPage = ((DomElement)(htmlpage.getElementByName("key").getParentNode().getParentNode())).getLastElementChild().click();
3.4 元素检索
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//查找所有div
List hbList = page.getByXPath("//div");
HtmlDivision hb = (HtmlDivision)hbList.get(0);
System.out.println(hb.toString());
//查找并获取特定input
List inputList = page.getByXPath("//input[@id='su']");
HtmlInput input = (HtmlInput)inputList.get(0);
System.out.println(input.toString());
//关闭webclient
webClient.closeAllWindows();
}
}
3.5 提交搜索
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//获取搜索输入框并提交搜索内容
HtmlInput input = (HtmlInput)page.getHtmlElementById("kw");
System.out.println(input.toString());
input.setValueAttribute("ymd");
System.out.println(input.toString());
//获取搜索按钮并点击
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
HtmlPage page2 = btn.click();
//输出新页面的文本
System.out.println(page2.asText());
}
}
3.htmlUnit方法介绍
一、环境介绍
因为我是在自己的spring boot项目中引入的,所以只需要在pom文件中添加依赖即可
net.sourceforge.htmlunit
htmlunit
2.41.0
如果只是爬一点js 网站 建议改一下下面的依赖
net.sourceforge.htmlunit
htmlunit
2.23
两者的区别将在后面讨论。当然,如果你用的不是maven项目(没有pom),可以去官网下载源码库
二、使用
HtmlUnit 使用起来非常简单。使用的时候可以去官网手册查看语法。其实说明书只是介绍,下面听我说就够了;
1、创建客户端并配置客户端
final String url ="https:****";//大家这可以填自己爬虫的地址
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_68);//创建火狐浏览器 2.23版本是FIREFOX_45 new不写参数是默认浏览器
webClient.getOptions().setCssEnabled(false);//(屏蔽)css 因为css并不影响我们抓取数据 反而影响网页渲染效率
webClient.getOptions().setThrowExceptionOnScriptError(false);//(屏蔽)异常
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//(屏蔽)日志
webClient.getOptions().setJavaScriptEnabled(true);//加载js脚本
webClient.getOptions().setTimeout(50000);//设置超时时间
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置ajax
HtmlPage htmlPage = webClient.getPage(url);//将客户端获取的树形结构转化为HtmlPage
Thread.sleep(10000);//主线程休眠10秒 让客户端有时间执行js代码 也可以写成webClient.waitForBackgroundJavaScript(1000)
有一个等待js执行,2.41.0非常兼容很多js,但是2.3总是有问题不能刷新网页,2. 41.0 打印也很详细,执行过程比较慢,可能是慢而细致。
远程地址页差不多就到这里了。我们现在要做的就是解析dom节点并填写数据来模拟点击等事件。如果要打印出来 htmlPage.asText() 输出 htmlPage 节点的文本 htmlPage.asXml() 输出 htmlPage 节点的 xml 代码
2、节点获取
在这个链接中,建议准备一点前端知识
HtmlUnit 提供了两种获取节点的方法
XPath 查询:
更详细的xpath解释:
final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net");
//get list of all divs
final List divs = htmlPage .getByXPath("//div");
//get div which has a 'name' attribute of 'John'
final HtmlDivision div = (HtmlDivision) htmlPage .getByXPath("//div[@name='John']").get(0);
css 选择器:(我更喜欢它)
final DomNodeList divs = htmlPage .querySelectorAll("div");
for (DomNode div : divs) {
....
}
//get div which has the id 'breadcrumbs'
final DomNode div = htmlPage .querySelector("div#breadcrumbs");
css给出了一个集合查询querySelectorAll和一个单一查询querySelector,如果你没有基础,我给你下面的例子来理解:
htmlPage.querySelectorAll("div") 返回 htmlPage 下面的 div 标签集合
htmlPage.querySelector("div:nth-child(1)") 返回htmlPage下面的div的第一个div
htmlPage .querySelector(".submit") 返回htmlPage下的第一个class=submit标签
htmlPage .querySelector("#submit") 返回htmlPage下id=submit的第一个标签
htmlPage.querySelector("div.submit") 返回htmlPage下第一个带有submit类的div标签
htmlPage.querySelector("div[id='submit']") 返回 htmlPage 下面的第一个 div 标签,id 为 submit
上面的枚举方式相信就够了,如果还不够,可以参考css选择器
下面列出了常见的html标签和HtmlUnit类的对应关系
div -> HtmlDivision
div集合 -> DomNodeList
fieldSet -> HtmlFieldSet
form -> HtmlForm
button -> HtmlButton
a -> HtmlAnchor
-> HtmlXxxInput
( -> HtmlTextInput)
table -> HtmlTable
tr -> HtmlTableRow
td -> TableDataCell
节点的属性样式有一个setAttribute()方法,setNodeValue()设置节点值。你的英语突然提高了吗?几乎所有的标签都能找到对应的类。来看看我的实战:这是一个在线填写温度的excel文档。如果你访问并更改地址,他会提示登录页面上有一个登录按钮。如果已经登录,页面上没有登录按钮登录按钮,我们现在模拟打开自动登录框:
//这段代码是为了让网页的的某个按钮加载出来之后再执行下面的代码
while (htmlPage.querySelector("#header-login-btn")==null) {
synchronized (htmlPage) {
htmlPage.wait(1000);
}
}
HtmlButton login = htmlPage.querySelector("#header-login-btn");//获取到登陆按钮
if (login!=null){//如果网页上没这个按钮你还要去获取他只会得到一个空对象,所以我们用空的方式可以判断网页上是否有这个按钮
System.out.println("-----未登录测试-----");
htmlPage=login.click();//模拟按钮点击后要将网页返回回来方便动态更新数据
System.out.println(htmlPage.asText());
HtmlAnchor switcher_plogin = htmlPage.querySelector("a[id='switcher_plogin']");
if (switcher_plogin!=null) {//帐号密码登录
System.out.println("-----点击了帐号密码登陆-----");
htmlPage = switcher_plogin.click();
System.out.println(htmlPage.asText());
}
}
System.out.println(htmlPage.asText());
webClient.close();
爬虫最重要的一步就是先调试网页,有哪些按钮,点击哪些,设置哪些值。毕竟,我们要用代码来调度代码。
**扩展:**如果要从网页中获取数据或下载文件,仅HtmlUnit解析是不够的。推荐使用Jsoup库,可以和HtmlUnit一起使用,比较好用,这里就不一一列举了。
三、实现一个小demo
注意:不是所有htmlunit引用的jar包都会报奇怪的错误
使用maven方法更方便
参考: 查看全部
htmlunit抓取动态网页(1.HtmlUnit中文文档获取页面中特定的元素tips:1.)
1.HtmlUnit 简介
HtmlUnit 是一个 java 无界面浏览器库。它模拟 HTML 文档并提供相应的 API,允许您调用页面、填写表单、单击链接等,就像您在“普通”浏览器中所做的一样。它有相当不错的 JavaScript 支持(仍在改进),甚至能够处理相当复杂的 AJAX 库,根据使用的配置模拟 Chrome、Firefox 或 Internet Explorer。它通常用于测试目的或从 网站 检索信息。
HtmlUnit 不是一个通用的单元测试框架。它是一种模拟浏览器以进行测试的方法,旨在用于其他测试框架,例如 JUnit 或 TestNG。有关介绍,请参见文档“HtmlUnit 入门”。HtmlUnit 用作不同的开源工具,如 Canoo WebTest、JWebUnit、WebDriver、JSFUnit、WETATOR、Celerity、Spring MVC Test HtmlUnit 作为底层“浏览器”。
HtmlUnit 最初由 Gargoyle Software 的 Mike Bowler 编写,并在 Apache 2 许可下发布。从那时起,它收到了许多其他开发者的贡献,今天将得到他们的帮助。
几年前,我在为购物网站 做数据采集工作时偶然发现了HtmlUnit。记得当时页面上的价格数据是抓不到的,httpfox也无法追踪到价格数据的url。在我不知所措的时候,HtmlUnit出现了,帮我解决了问题。所以今天我要说声谢谢并向大家推荐HtmlUnit。
2.htmlUnit 中文文档
3.1 获取页面的TITLE、XML代码、文本

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//创建一个webclient
WebClient webClient = new WebClient();
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
//获取页面
HtmlPage page = webClient.getPage("http://www.baidu.com/");
//获取页面的TITLE
str = page.getTitleText();
System.out.println(str);
//获取页面的XML代码
str = page.asXml();
System.out.println(str);
//获取页面的文本
str = page.asText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}

3.2 用不同版本的浏览器打开

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import java.util.List;
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
String str;
//使用FireFox读取网页
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = webClient.getPage("http://www.baidu.com/");
str = page.getTitleText();
System.out.println(str);
//关闭webclient
webClient.closeAllWindows();
}
}

3.3 在页面中查找特定元素
public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//通过id获得"百度一下"按钮
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
System.out.println(btn.getDefaultValue());
//关闭webclient
webClient.closeAllWindows();
}
}
提示:有些元素没有 id 和 name 或其他节点。您可以通过查找其子节点和父节点之间的规律性来获取该元素。具体方法请参考:
它的核心代码是:
final HtmlPage nextPage = ((DomElement)(htmlpage.getElementByName("key").getParentNode().getParentNode())).getLastElementChild().click();
3.4 元素检索

public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//查找所有div
List hbList = page.getByXPath("//div");
HtmlDivision hb = (HtmlDivision)hbList.get(0);
System.out.println(hb.toString());
//查找并获取特定input
List inputList = page.getByXPath("//input[@id='su']");
HtmlInput input = (HtmlInput)inputList.get(0);
System.out.println(input.toString());
//关闭webclient
webClient.closeAllWindows();
}
}

3.5 提交搜索

public class helloHtmlUnit{
public static void main(String[] args) throws Exception{
//创建webclient
WebClient webClient = new WebClient(BrowserVersion.CHROME);
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.baidu.com/");
//获取搜索输入框并提交搜索内容
HtmlInput input = (HtmlInput)page.getHtmlElementById("kw");
System.out.println(input.toString());
input.setValueAttribute("ymd");
System.out.println(input.toString());
//获取搜索按钮并点击
HtmlInput btn = (HtmlInput)page.getHtmlElementById("su");
HtmlPage page2 = btn.click();
//输出新页面的文本
System.out.println(page2.asText());
}
}

3.htmlUnit方法介绍
一、环境介绍
因为我是在自己的spring boot项目中引入的,所以只需要在pom文件中添加依赖即可
net.sourceforge.htmlunit
htmlunit
2.41.0
如果只是爬一点js 网站 建议改一下下面的依赖
net.sourceforge.htmlunit
htmlunit
2.23
两者的区别将在后面讨论。当然,如果你用的不是maven项目(没有pom),可以去官网下载源码库
二、使用
HtmlUnit 使用起来非常简单。使用的时候可以去官网手册查看语法。其实说明书只是介绍,下面听我说就够了;
1、创建客户端并配置客户端
final String url ="https:****";//大家这可以填自己爬虫的地址
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_68);//创建火狐浏览器 2.23版本是FIREFOX_45 new不写参数是默认浏览器
webClient.getOptions().setCssEnabled(false);//(屏蔽)css 因为css并不影响我们抓取数据 反而影响网页渲染效率
webClient.getOptions().setThrowExceptionOnScriptError(false);//(屏蔽)异常
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//(屏蔽)日志
webClient.getOptions().setJavaScriptEnabled(true);//加载js脚本
webClient.getOptions().setTimeout(50000);//设置超时时间
webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置ajax
HtmlPage htmlPage = webClient.getPage(url);//将客户端获取的树形结构转化为HtmlPage
Thread.sleep(10000);//主线程休眠10秒 让客户端有时间执行js代码 也可以写成webClient.waitForBackgroundJavaScript(1000)
有一个等待js执行,2.41.0非常兼容很多js,但是2.3总是有问题不能刷新网页,2. 41.0 打印也很详细,执行过程比较慢,可能是慢而细致。
远程地址页差不多就到这里了。我们现在要做的就是解析dom节点并填写数据来模拟点击等事件。如果要打印出来 htmlPage.asText() 输出 htmlPage 节点的文本 htmlPage.asXml() 输出 htmlPage 节点的 xml 代码
2、节点获取
在这个链接中,建议准备一点前端知识
HtmlUnit 提供了两种获取节点的方法
XPath 查询:
更详细的xpath解释:
final HtmlPage page = webClient.getPage("http://htmlunit.sourceforge.net");
//get list of all divs
final List divs = htmlPage .getByXPath("//div");
//get div which has a 'name' attribute of 'John'
final HtmlDivision div = (HtmlDivision) htmlPage .getByXPath("//div[@name='John']").get(0);
css 选择器:(我更喜欢它)
final DomNodeList divs = htmlPage .querySelectorAll("div");
for (DomNode div : divs) {
....
}
//get div which has the id 'breadcrumbs'
final DomNode div = htmlPage .querySelector("div#breadcrumbs");
css给出了一个集合查询querySelectorAll和一个单一查询querySelector,如果你没有基础,我给你下面的例子来理解:
htmlPage.querySelectorAll("div") 返回 htmlPage 下面的 div 标签集合
htmlPage.querySelector("div:nth-child(1)") 返回htmlPage下面的div的第一个div
htmlPage .querySelector(".submit") 返回htmlPage下的第一个class=submit标签
htmlPage .querySelector("#submit") 返回htmlPage下id=submit的第一个标签
htmlPage.querySelector("div.submit") 返回htmlPage下第一个带有submit类的div标签
htmlPage.querySelector("div[id='submit']") 返回 htmlPage 下面的第一个 div 标签,id 为 submit
上面的枚举方式相信就够了,如果还不够,可以参考css选择器
下面列出了常见的html标签和HtmlUnit类的对应关系
div -> HtmlDivision
div集合 -> DomNodeList
fieldSet -> HtmlFieldSet
form -> HtmlForm
button -> HtmlButton
a -> HtmlAnchor
-> HtmlXxxInput
( -> HtmlTextInput)
table -> HtmlTable
tr -> HtmlTableRow
td -> TableDataCell
节点的属性样式有一个setAttribute()方法,setNodeValue()设置节点值。你的英语突然提高了吗?几乎所有的标签都能找到对应的类。来看看我的实战:这是一个在线填写温度的excel文档。如果你访问并更改地址,他会提示登录页面上有一个登录按钮。如果已经登录,页面上没有登录按钮登录按钮,我们现在模拟打开自动登录框:
//这段代码是为了让网页的的某个按钮加载出来之后再执行下面的代码
while (htmlPage.querySelector("#header-login-btn")==null) {
synchronized (htmlPage) {
htmlPage.wait(1000);
}
}
HtmlButton login = htmlPage.querySelector("#header-login-btn");//获取到登陆按钮
if (login!=null){//如果网页上没这个按钮你还要去获取他只会得到一个空对象,所以我们用空的方式可以判断网页上是否有这个按钮
System.out.println("-----未登录测试-----");
htmlPage=login.click();//模拟按钮点击后要将网页返回回来方便动态更新数据
System.out.println(htmlPage.asText());
HtmlAnchor switcher_plogin = htmlPage.querySelector("a[id='switcher_plogin']");
if (switcher_plogin!=null) {//帐号密码登录
System.out.println("-----点击了帐号密码登陆-----");
htmlPage = switcher_plogin.click();
System.out.println(htmlPage.asText());
}
}
System.out.println(htmlPage.asText());
webClient.close();
爬虫最重要的一步就是先调试网页,有哪些按钮,点击哪些,设置哪些值。毕竟,我们要用代码来调度代码。
**扩展:**如果要从网页中获取数据或下载文件,仅HtmlUnit解析是不够的。推荐使用Jsoup库,可以和HtmlUnit一起使用,比较好用,这里就不一一列举了。
三、实现一个小demo
注意:不是所有htmlunit引用的jar包都会报奇怪的错误
使用maven方法更方便
参考:
htmlunit抓取动态网页(爬取一个动态网页刷新问题,解决方案如下思路使用 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 114 次浏览 • 2022-02-18 07:01
)
更新。. . . . 这个动态网页其实可以直接抓取ajax请求。这很简单。之前觉得很复杂 虽然也实现了,效率极低,不过没关系。这是对 Selenium 的学习。
1.我最近在爬动态网页。为了更新页面,需要选择不同的选项,即处理下拉框。这里的下拉框是一个假的通过输入实现的下拉框,但是他还有一个隐藏的选择,我原本以为隐藏的选择会用js脚本修改变为可见,然后点击等操作,但是使用网上的方法后,发现选择可见可见,但是点击后没有效果,各方搜索无果,最后决定自己解决这个问题,解决方法如下
想法用selenium完全模拟人类操作,一步一步点击可见按钮
, 1、找到下拉框按钮,点击,
二、点击下拉框按钮后,会出现一个列表,在列表中定位一个元素,点击。注意这一步必须在下拉框按钮被点击后进行(使用time.sleep()等待几秒,否则会提示点击的内容不存在)
通过这两步,我们可以改变动态网页的信息,代码如下
def getButton(browser):
# 获取下拉框按钮
Button = browser.find_elements_by_class_name("textbox-icon") # 定位哪一栋楼按钮
buildButton = Button[0]
floorButton = Button[1]
buildingsAndFloors = browser.find_elements_by_class_name("combobox-item") # 楼选项
floors = buildingsAndFloors[30:]
buildings = buildingsAndFloors[:30]
info = dict()
info['floors'] = floors
info['buildings'] = buildings
info['buildButton'] = buildButton
info['floorButton'] = floorButton
return info
2.另外,在爬取的时候,经常会提示点击按钮或者不存在的东西,所以一定要设置延迟。
3.某些动态网页的源代码与您在使用 f12 的网页上看到的不同。我的解决方法是先对网页进行操作,然后获取源码,就正常了
4.动态网页存在不断刷新的问题,但是每次刷新后都会提示旧元素不能使用,所以必须重新获取不能使用的信息,如下,getButton( )函数获取Button信息,每次页面刷新后需要点击按钮时再次获取。
# 获取某一栋楼某一层的信息所对应页面的源代码
def getSoup(buildNumber, floor):
info = getButton(browser)
info['buildButton'].click() # 点击指定楼
info['buildings'][buildNumber].click()
time.sleep(1)
info = getButton(browser) # 重新获取信息
time.sleep(1)
info['floorButton'].click() # 点击指定楼层
info['floors'][floor].click()
soup = BeautifulSoup(browser.page_source, 'html.parser')
return soup 查看全部
htmlunit抓取动态网页(爬取一个动态网页刷新问题,解决方案如下思路使用
)
更新。. . . . 这个动态网页其实可以直接抓取ajax请求。这很简单。之前觉得很复杂 虽然也实现了,效率极低,不过没关系。这是对 Selenium 的学习。
1.我最近在爬动态网页。为了更新页面,需要选择不同的选项,即处理下拉框。这里的下拉框是一个假的通过输入实现的下拉框,但是他还有一个隐藏的选择,我原本以为隐藏的选择会用js脚本修改变为可见,然后点击等操作,但是使用网上的方法后,发现选择可见可见,但是点击后没有效果,各方搜索无果,最后决定自己解决这个问题,解决方法如下
想法用selenium完全模拟人类操作,一步一步点击可见按钮
, 1、找到下拉框按钮,点击,
二、点击下拉框按钮后,会出现一个列表,在列表中定位一个元素,点击。注意这一步必须在下拉框按钮被点击后进行(使用time.sleep()等待几秒,否则会提示点击的内容不存在)
通过这两步,我们可以改变动态网页的信息,代码如下
def getButton(browser):
# 获取下拉框按钮
Button = browser.find_elements_by_class_name("textbox-icon") # 定位哪一栋楼按钮
buildButton = Button[0]
floorButton = Button[1]
buildingsAndFloors = browser.find_elements_by_class_name("combobox-item") # 楼选项
floors = buildingsAndFloors[30:]
buildings = buildingsAndFloors[:30]
info = dict()
info['floors'] = floors
info['buildings'] = buildings
info['buildButton'] = buildButton
info['floorButton'] = floorButton
return info

2.另外,在爬取的时候,经常会提示点击按钮或者不存在的东西,所以一定要设置延迟。
3.某些动态网页的源代码与您在使用 f12 的网页上看到的不同。我的解决方法是先对网页进行操作,然后获取源码,就正常了
4.动态网页存在不断刷新的问题,但是每次刷新后都会提示旧元素不能使用,所以必须重新获取不能使用的信息,如下,getButton( )函数获取Button信息,每次页面刷新后需要点击按钮时再次获取。
# 获取某一栋楼某一层的信息所对应页面的源代码
def getSoup(buildNumber, floor):
info = getButton(browser)
info['buildButton'].click() # 点击指定楼
info['buildings'][buildNumber].click()
time.sleep(1)
info = getButton(browser) # 重新获取信息
time.sleep(1)
info['floorButton'].click() # 点击指定楼层
info['floors'][floor].click()
soup = BeautifulSoup(browser.page_source, 'html.parser')
return soup
htmlunit抓取动态网页(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
网站优化 • 优采云 发表了文章 • 0 个评论 • 74 次浏览 • 2022-02-15 21:20
由于其他项目组都在做舆情预测项目,我只是手头没有项目,突然心血来潮想研究一个简单的爬虫原型和分析。网上这方面的资料很多,看得我眼花缭乱。对于我这样的新手,想做一个简单的爬虫程序,所以HttpClient + jsoup是个不错的选择。前者是用来管理请求的,后者是用来解析页面的,主要是后者的select语法和jquery很像,对我这个用js的人来说太方便了。
昨天和他们聊天时,他们使用了几个知名的开源框架。聊了几句,他们发现自己根本无法爬取动态网页,尤其是一些重要的数字,比如评论数和回复数。等等我有一个大致的了解。比如TRS的爬虫需要为js调用编写js脚本,但分析量巨大。他们的技术人员告诉我们,如果他们匹配这样的模板,他们每天只能匹配2到3个。,更何况我们这些中途修士。碰巧是一个相当大的挑战,所以我昨天答应他们,看看他们是否能找到一个相对简单的解决方案,当然,不管效率如何。
举个简单的例子,如下图
“我有话要说”后面的1307是后载的,但这些数字往往对舆情分析更重要。
对需求有了大致的了解后,我们来分析如何解决它们。通常我们得到的一个请求的响应收录js代码和html元素,所以像jsoup这样的html解析器很难在这里利用,因为它所能得到的html,1307还没有生成。这时候就需要一个可以运行js的平台,运行js代码后的页面会被html解析,这样才能正确得到结果。
因为懒,一开始写脚本的方式被我抛弃了,因为分析一个页面太痛苦了,代码乱成一锅粥。看的太累了。所以我的首要任务是,为什么我不能让这个地址在某个浏览器中运行,然后将运行结果交给html解析器解析,那么整个问题就解决了。这样,我的临时解决方案是在爬虫服务器上打开一个后台浏览器,或者是有浏览器内核的程序,把url地址交给它去请求,然后从浏览器中取出页面的元素给它到 html 解析器进行解析以获取您想要的信息。
没错,最后我还是用 Selenium 来实现我在上一篇文章中提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果我还是可以接受的。
继续昨天的话题,既然我们要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的首选是htmlunit,先简单介绍一下htmlunit。以下段落摘自互联网。
htmlunit 是一个开源的java页面分析工具。启动htmlunit后,会在底层启动一个非界面浏览器。用户可以指定浏览器类型:firefox、ie等,不指定则默认使用INTERNET_EXPLORER_7:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
只需调用:
HtmlPage 页面 = webClient.getPage(url);
可以获取页面的 HtmlPage 表示,然后通过:
InputStream 是 = targetPage.getWebResponse().getContentAsStream()
可以获取页面的输入流,从而获取页面的源代码,对于网络爬虫项目非常有用。
当然,你也可以从page中获取更多的页面元素。
重要的是,HtmlUnit 提供对执行 javascript 的支持:
page.executeJavaScript(javascript)
执行js后,返回一个ScriptResult对象,通过该对象可以获取执行js后的页面等信息。默认情况下,执行完js后,内部浏览器会进行页面跳转,跳转到执行完js后生成的新页面。如果js执行失败,则不会执行页面跳转。
最后可以通过page.executeJavaScript(javascript).getNewPage()获取执行的页面。也就是说,这里需要人为地执行javascript,这显然不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻的页面时总是出错。根据网络上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数顺序或者编码问题,请求失败,报错。关键是,运行它后我没有得到我需要的结果。
然后我寻找另一种解决方案。这时,我找到了 SeleniumWebDriver,这是我需要的解决方案。
参考资料和例子,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn");
11 list.add("http://www.sohu.com");
12 list.add("http://www.163.com");
13 list.add("http://www.qq.com");
14
15 long start,end;
16
17 for(int i=0;i 查看全部
htmlunit抓取动态网页(别的项目组什么项目突然心血来潮想研究一下爬虫、分析的简单原型)
由于其他项目组都在做舆情预测项目,我只是手头没有项目,突然心血来潮想研究一个简单的爬虫原型和分析。网上这方面的资料很多,看得我眼花缭乱。对于我这样的新手,想做一个简单的爬虫程序,所以HttpClient + jsoup是个不错的选择。前者是用来管理请求的,后者是用来解析页面的,主要是后者的select语法和jquery很像,对我这个用js的人来说太方便了。
昨天和他们聊天时,他们使用了几个知名的开源框架。聊了几句,他们发现自己根本无法爬取动态网页,尤其是一些重要的数字,比如评论数和回复数。等等我有一个大致的了解。比如TRS的爬虫需要为js调用编写js脚本,但分析量巨大。他们的技术人员告诉我们,如果他们匹配这样的模板,他们每天只能匹配2到3个。,更何况我们这些中途修士。碰巧是一个相当大的挑战,所以我昨天答应他们,看看他们是否能找到一个相对简单的解决方案,当然,不管效率如何。
举个简单的例子,如下图
“我有话要说”后面的1307是后载的,但这些数字往往对舆情分析更重要。
对需求有了大致的了解后,我们来分析如何解决它们。通常我们得到的一个请求的响应收录js代码和html元素,所以像jsoup这样的html解析器很难在这里利用,因为它所能得到的html,1307还没有生成。这时候就需要一个可以运行js的平台,运行js代码后的页面会被html解析,这样才能正确得到结果。
因为懒,一开始写脚本的方式被我抛弃了,因为分析一个页面太痛苦了,代码乱成一锅粥。看的太累了。所以我的首要任务是,为什么我不能让这个地址在某个浏览器中运行,然后将运行结果交给html解析器解析,那么整个问题就解决了。这样,我的临时解决方案是在爬虫服务器上打开一个后台浏览器,或者是有浏览器内核的程序,把url地址交给它去请求,然后从浏览器中取出页面的元素给它到 html 解析器进行解析以获取您想要的信息。
没错,最后我还是用 Selenium 来实现我在上一篇文章中提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果我还是可以接受的。
继续昨天的话题,既然我们要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的首选是htmlunit,先简单介绍一下htmlunit。以下段落摘自互联网。
htmlunit 是一个开源的java页面分析工具。启动htmlunit后,会在底层启动一个非界面浏览器。用户可以指定浏览器类型:firefox、ie等,不指定则默认使用INTERNET_EXPLORER_7:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
只需调用:
HtmlPage 页面 = webClient.getPage(url);
可以获取页面的 HtmlPage 表示,然后通过:
InputStream 是 = targetPage.getWebResponse().getContentAsStream()
可以获取页面的输入流,从而获取页面的源代码,对于网络爬虫项目非常有用。
当然,你也可以从page中获取更多的页面元素。
重要的是,HtmlUnit 提供对执行 javascript 的支持:
page.executeJavaScript(javascript)
执行js后,返回一个ScriptResult对象,通过该对象可以获取执行js后的页面等信息。默认情况下,执行完js后,内部浏览器会进行页面跳转,跳转到执行完js后生成的新页面。如果js执行失败,则不会执行页面跳转。
最后可以通过page.executeJavaScript(javascript).getNewPage()获取执行的页面。也就是说,这里需要人为地执行javascript,这显然不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻的页面时总是出错。根据网络上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数顺序或者编码问题,请求失败,报错。关键是,运行它后我没有得到我需要的结果。
然后我寻找另一种解决方案。这时,我找到了 SeleniumWebDriver,这是我需要的解决方案。
参考资料和例子,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn");
11 list.add("http://www.sohu.com");
12 list.add("http://www.163.com");
13 list.add("http://www.qq.com");
14
15 long start,end;
16
17 for(int i=0;i
htmlunit抓取动态网页(分享一种解决方案,代码以及部分截图不方便贴出,请谅解!)
网站优化 • 优采云 发表了文章 • 0 个评论 • 88 次浏览 • 2022-02-15 06:15
说明:只是分享一个解决方案,代码和部分截图不便贴,请谅解!
前段时间,我一直在研究爬虫来爬取网络上的特定数据。如果只是一个静态网页,那就很简单了。直接使用Jsoup:
Document doc = Jsoup.connect(url).timeout(2000).get();
获取Document然后为所欲为,但是一旦遇到一些动态生成的网站就不行了,因为数据是页面加载完成后执行js代码加载的,或者是用户滑动触发的浏览js加载数据,这样的网页使用Jsoup显然无法获取到想要的数据。
后来用Selenium获取动态网页的数据,可以成功获取到数据(实现方法),程序打包在一台机器上运行,开始测试,然后结果不太理想,并且经常出现内存溢出,或者浏览器升级导致驱动和浏览器版本不匹配等一系列问题。今天早上来到公司,发现程序又被炸了。半夜没人动机器,鼠标键盘都失灵了,只好重启,不说是什么问题,所以测试修改测试太麻烦,所以决定放弃用Selenium,稳定性太差,我考虑用htmlunit等但是那些工具效果不是很好,
首先,动态网页,既然是动态的,肯定是在浏览器加载网页后,向服务器发送了网络请求。如果我得到网络请求的url,模拟参数,自己发送请求,解析数据是不是更好,然后开始工作:
抓包工具:fiddle
不懂fiddle的,建议百度学习一下
安装好后打开fiddle,打开浏览器,打开目标url,然后就可以看到fiddle中打开这个网页的所有网络请求了:
我不会在这里发图片,我怕人家惹我。. . .
然后就是一一查看网络请求:
先看左边的图标,直接略过图,显然我们需要的是数据,重点关注文本格式的请求,然后右键copy->just url 把url复制到浏览器看看可以get,最后找到18行的request就是数据接口,可以直接获取数据,而且是json格式!!!!!!!!
真的很爽,直接json就行了,剩下的就简单了,解析数据。. . . . . . . 略略。. . . . . 话不多说,继续敲代码,这里只是分享一个解析动态网页的方法,欢迎在此发表评论,一起讨论,寻找更好的解决问题的方法!
2016-11-07
迦南香 查看全部
htmlunit抓取动态网页(分享一种解决方案,代码以及部分截图不方便贴出,请谅解!)
说明:只是分享一个解决方案,代码和部分截图不便贴,请谅解!
前段时间,我一直在研究爬虫来爬取网络上的特定数据。如果只是一个静态网页,那就很简单了。直接使用Jsoup:
Document doc = Jsoup.connect(url).timeout(2000).get();
获取Document然后为所欲为,但是一旦遇到一些动态生成的网站就不行了,因为数据是页面加载完成后执行js代码加载的,或者是用户滑动触发的浏览js加载数据,这样的网页使用Jsoup显然无法获取到想要的数据。
后来用Selenium获取动态网页的数据,可以成功获取到数据(实现方法),程序打包在一台机器上运行,开始测试,然后结果不太理想,并且经常出现内存溢出,或者浏览器升级导致驱动和浏览器版本不匹配等一系列问题。今天早上来到公司,发现程序又被炸了。半夜没人动机器,鼠标键盘都失灵了,只好重启,不说是什么问题,所以测试修改测试太麻烦,所以决定放弃用Selenium,稳定性太差,我考虑用htmlunit等但是那些工具效果不是很好,
首先,动态网页,既然是动态的,肯定是在浏览器加载网页后,向服务器发送了网络请求。如果我得到网络请求的url,模拟参数,自己发送请求,解析数据是不是更好,然后开始工作:
抓包工具:fiddle
不懂fiddle的,建议百度学习一下
安装好后打开fiddle,打开浏览器,打开目标url,然后就可以看到fiddle中打开这个网页的所有网络请求了:
我不会在这里发图片,我怕人家惹我。. . .
然后就是一一查看网络请求:
先看左边的图标,直接略过图,显然我们需要的是数据,重点关注文本格式的请求,然后右键copy->just url 把url复制到浏览器看看可以get,最后找到18行的request就是数据接口,可以直接获取数据,而且是json格式!!!!!!!!
真的很爽,直接json就行了,剩下的就简单了,解析数据。. . . . . . . 略略。. . . . . 话不多说,继续敲代码,这里只是分享一个解析动态网页的方法,欢迎在此发表评论,一起讨论,寻找更好的解决问题的方法!
2016-11-07
迦南香
htmlunit抓取动态网页(Web网络爬虫系统的原理及应用)
网站优化 • 优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-02-15 06:12
1、爬虫技术概述
网络爬虫是根据一定的规则自动从万维网上爬取信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,它可以自动采集它可以访问的所有页面获取或更新这些网站的内容和检索方法。从功能上来说,爬虫一般分为数据采集、处理、存储三部分。传统爬虫从一个或多个初始网页的URL开始,获取初始网页上的URL。在抓取网页的过程中,它不断地从当前页面中提取新的 URL 并放入队列中,直到满足系统的某些停止条件。焦点爬虫的工作流程比较复杂。它需要按照一定的网页分析算法过滤掉与主题无关的链接,保留有用的链接,并放入等待抓取的URL队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。
与通用网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
(1) 获取目标的描述或定义;
(2) 网页或数据的分析和过滤;
(3) URL 的搜索策略。
2、爬虫原理
2.1 网络爬虫原理
网络爬虫系统的功能是下载网页数据,为搜索引擎系统提供数据源。许多大型网络搜索引擎系统被称为基于Web数据的搜索引擎系统采集,如Google、百度等。这显示了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文字信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程像爬虫或者蜘蛛一样在网络上漫游,所以才叫做网络爬虫系统或者网络蜘蛛系统,英文叫Spider或者Crawler。
2.2 网络爬虫系统的工作原理
在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多个线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页和处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等。爬虫的基本工作是由解析器完成的。资源库用于存储下载的网络资源。通常使用大型数据库,例如 Oracle 数据库来存储和索引它。
控制器
控制器是网络爬虫的中央控制器。主要负责根据系统发送的URL链接分配一个线程,然后启动线程调用爬虫爬取网页。
解析器
解析器负责网络爬虫的主要部分。它的主要任务是:下载网页的功能,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
资源库
它主要是一个容器,用于存储从网页下载的数据记录,并为索引生成提供目标源。大中型数据库产品包括:Oracle、Sql Server等。
网络爬虫系统一般会选择一些比较重要的出度(网页中超链接数)网站较大的URL作为种子URL集。网络爬虫系统使用这些种子集作为初始 URL 来开始数据爬取。因为网页中收录链接信息,所以会通过已有网页的URL获取一些新的URL。网页之间的指向结构可以看作是一片森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能导致爬虫系统陷入网站内部,不利于搜索距离网站首页比较近的网页信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。
网络爬虫的基本工作流程如下:
1.首先选择一个精心挑选的种子 URL 的子集;
2.将这些网址放入待抓取的网址队列中;
3. 从待爬取URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页,存入下载的网页库中。此外,将这些 URL 放入 Crawl URL 队列。
4.分析已经爬取的URL队列中的URL,分析其中的其他URL,将这些URL放入待爬取的URL队列,从而进入下一个循环。
2.3 爬取策略
在爬虫系统中,待爬取的 URL 队列是一个重要的部分。待爬取的URL队列中的URL的排列顺序也是一个重要的问题,因为它涉及到先爬到哪个页面,再爬到哪个页面。确定这些 URL 排列顺序的方法称为爬取策略。下面重点介绍几种常见的爬取策略:
2.3.1 深度优先遍历策略
深度优先遍历策略是指网络爬虫会从起始页开始,每次一个链接跟踪每个链接,处理完该行后移动到下一个起始页,并继续跟踪该链接。我们以下图为例:
遍历的路径:AFG EHI BCD
2.3.2 广度优先遍历策略
广度优先遍历的基本思想是将新下载的网页中找到的链接直接插入待爬取URL队列的末尾。也就是说,网络爬虫会先爬取起始网页链接的所有网页,然后选择其中一个链接的网页,继续爬取该网页链接的所有网页。或者以上图为例:
遍历路径:ABCDEF GHI
2.3.3 反向链接策略
反向链接数是指从其他网页指向一个网页的链接数。反向链接的数量表示网页内容被他人推荐的程度。因此,在很多情况下,搜索引擎的爬取系统会使用这个指标来评估网页的重要性,从而确定不同网页的爬取顺序。
在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量并不能完全等同于他人的重要性。因此,搜索引擎倾向于考虑一些可靠的反向链接计数。
2.3.4部分PageRank策略
Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,与待爬取的URL队列中的URL一起形成一组网页,计算每个页面的PageRank值. URL 按 PageRank 值排序,并按该顺序抓取页面。
如果每次爬取一个页面都重新计算一次PageRank值,一个折中的方案是每次爬取K个页面都重新计算一次PageRank值。但是这种情况还是有一个问题:对于下载页面中分析的链接,也就是我们前面提到的那部分未知网页,暂时没有PageRank值。为了解决这个问题,给这些页面一个临时的PageRank值:把这个网页的所有传入链接传入的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排序. 以下示例说明:
2.3.5OPICStrategy
该算法实际上为页面分配了一个重要性分数。在算法开始之前,所有页面都会获得相同的初始现金。当某个页面P被下载时,P的现金分配给从P分析的所有链接,P的现金被清空。根据现金数量对待爬取URL队列中的所有页面进行排序。
2.3.六大网站优先策略
所有待爬取的URL队列中的网页都按照它们所属的网站进行分类。网站需要下载的页面较多,请先下载。这种策略也称为大站点优先策略。
3、爬虫分类
我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫类,基本上可以分为三类:
(1)分布式爬虫:Nutch
(2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
(3)非JAVA爬虫:scrapy(基于Python语言开发)
3.1 分布式爬虫
爬虫使用分布式,主要解决两个问题:
1)海量网址管理
2)网速
现在比较流行的分布式爬虫是Apache的Nutch。但是对于大多数用户来说,Nutch 是这些爬虫中最差的选择,原因如下:
1)Nutch 是为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的三分之二的流程是为搜索引擎设计的。提取意义不大。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发让Nutch适合提取业务,那你基本上会破坏Nutch的框架,把Nutch改得面目全非,而且有能力修改Nutch,还不如自己写一个新的。分布式爬虫框架。
2)Nutch 依赖hadoop 运行,hadoop 本身消耗大量时间。如果集群机器数量少,爬取速度不如单机爬虫快。
3)虽然Nutch有一套插件机制,但还是作为亮点来宣传的。可以看到一些开源的Nutch插件,提供精准提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多糟糕。使用反射机制加载和调用插件,使得程序的编写和调试变得异常困难,更不用说在其上开发复杂的提取系统了。并且 Nutch 没有提供对应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点都是给搜索引擎服务的,不提供细提取的挂载点。Nutch 的大部分精炼提取插件都挂载在“页面解析”(parser)挂载点上。这个挂载点其实是用来解析链接(为后续爬取提供URL)和提供一些搜索引擎的。易于提取的网页信息(元信息、网页文本)。
4)使用Nutch进行爬虫的二次开发,编写和调试爬虫所需的时间往往是单机爬虫所需时间的十倍以上。学习 Nutch 源码的成本非常高,更何况团队中的每个人都必须了解 Nutch 源码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
5)很多人说Nutch2有gora,可以把数据持久化到avro文件、hbase、mysql等,其实很多人都搞错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
6)Nutch2 的版本目前不适合开发。Nutch的官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果要使用hbase和nutch(大多数人使用nutch2是为了使用hbase),只能使用版本0.90左右的hbase,相应地,将hadoop版本降低到hadoop 0.左右@>2。而且nutch2的官方教程也颇具误导性。Nutch2的教程有两个,分别是Nutch1.x和Nutch2.x。Nutch2.x官网是为了支持hbase0.94而写的。但其实这个Nutch2.x是指Nutch2.3之前和Nutch2.2.1之后的一个版本,在官方SVN中不断更新。而且它'
所以,如果你不是搜索引擎,尽量不要选择 Nutch 作为爬虫。一些团队喜欢跟风。他们坚持选择Nutch来开发精制履带。其实是针对Nutch的名声(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目延期。
如果你在做搜索引擎,Nutch1.x 是一个非常不错的选择。Nutch1.x 和 solr 或 es 可以组成一个非常强大的搜索引擎。如果必须使用 Nutch2,建议等到 Nutch2.3 发布。当前的 Nutch2 是一个非常不稳定的版本。
分布式爬虫平台架构图
3.2 JAVA爬虫
在这里,将JAVA爬虫划分为一个单独的类别,因为JAVA在网络爬虫的生态系统中非常完善。相关资料也是最全的。这里可能有争议,我只是随便说说。
其实开源网络爬虫(框架)的开发很简单,难点和复杂的问题已经被前人解决了(比如DOM树解析定位、字符集检测、海量URL去重),可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历本机的文件以查找文件中的信息。没有任何困难。选择开源爬虫框架的原因是为了省事。比如爬虫的URL管理、线程池等模块,任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
对于爬虫的功能。用户比较关心的问题往往是:
1)爬虫是否支持多线程,爬虫是否可以使用代理,爬虫是否可以爬取重复数据,爬虫是否可以爬取JS生成的信息?
不支持多线程、不支持代理、不能过滤重复URL的不叫开源爬虫,叫循环执行http请求。
js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理一个页面。因此,一种策略是利用这些爬虫遍历网站,当遇到需要解析的页面时,将网页的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
2)爬虫可以抓取ajax信息吗?
网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax的http请求,自己生成ajax请求的url,获取返回的数据。如果你自己生成ajax请求,那么使用开源爬虫有什么意义呢?其实就是利用开源爬虫的线程池和URL管理功能(比如断点爬取)。
如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来爬取这些请求呢?
爬虫往往被设计成广度遍历或深度遍历的方式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫并不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历 网站。爬虫的第一轮爬取就是爬取种子集(seeds)中的所有url。简单来说就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫对这些种子进行深度为 1 的广度遍历(默认为广度遍历)。
3)爬虫如何爬取待登录的网站?
这些开源爬虫都支持在爬取时指定cookies,而模拟登录主要依赖cookies。至于如何获取cookies,就不是爬虫管理的问题了。您可以手动获取cookies,使用http请求模拟登录,或者使用模拟浏览器自动登录。
4)爬虫如何从网页中提取信息?
开源爬虫一般会集成网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,我这里就不评论了。
5)爬虫是如何保存网页信息的?
有一些爬虫带有一个负责持久性的模块。例如,webmagic 有一个名为 pipeline 的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等。还有一些爬虫不直接为用户提供数据持久化模块。比如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于用管道模块好不好,就类似于用ORM操作数据库好不好的问题,看你的业务。
6)爬虫被网站拦截了怎么办?
爬虫被网站阻塞,可以通过使用多个代理(随机代理)来解决。但是这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,并编写代码让代理随机获取(从数组中)。
7)网页可以调用爬虫吗?
爬虫的调用是在Web的服务器端调用的。您可以按照平时使用的方式使用它。可以使用这些爬虫。
8)爬虫速度怎么样?
单机开源爬虫的速度基本可以用到本地网速的极限。爬虫速度慢往往是因为用户减少了线程数,网速慢,或者数据持久化时与数据库的交互慢。而这些东西往往是由用户的机器和二次开发的代码决定的。这些开源爬虫的速度非常好。
9) 明明代码写对了,但是数据爬不出来。爬虫有问题吗?另一个爬虫可以解决吗?
如果代码写得正确,无法爬取数据,其他爬虫也将无法爬取。在这种情况下,要么是 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。如果无法爬取数据,则无法通过更改爬虫来解决。
10)哪个爬虫可以判断网站是否已经爬完,哪个爬虫可以根据主题爬取?
爬虫无法判断网站是否已经爬完,只能尽量覆盖。
至于根据主题爬,爬虫把内容爬下来后就知道主题是什么了。因此,通常是整体爬下来,然后对内容进行过滤。如果爬取的范围太广,可以通过限制 URL 正则化来缩小范围。
11)哪个爬虫的设计模式和架构比较好?
设计模式是胡说八道。都说软件设计模式不错,软件开发后总结了几种设计模式。设计模式对软件开发没有指导意义。使用设计模式设计爬虫只会让爬虫的设计更加臃肿。
至于架构,目前开源爬虫主要是设计详细的数据结构,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,用任何框架都谈不上。
所以对于 JAVA 开源爬虫,我认为,只要找到一个运行良好的。如果业务复杂,使用哪个爬虫,只能通过复杂的二次开发来满足需求。
3.3 非JAVA爬虫
在非JAVA语言编写的爬虫中,不乏优秀的爬虫。这里提取为一个类别,不是为了讨论爬虫本身的好坏,而是为了讨论larbin、scrapy等爬虫对开发成本的影响。
先说python爬虫,python用30行代码就可以完成JAVA 50行代码的任务。Python写代码确实很快,但是在调试代码阶段,调试python代码所消耗的时间往往比编码阶段节省的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务也不复杂,用scrapy还是不错的,可以轻松完成爬取任务。
上图是Scrapy的架构图。绿线是数据流。从初始 URL 开始,Scheduler 会将其交给 Downloader 进行下载。下载完成后交给 Spider 进行分析,将要保存的数据发送到 Item Pipeline ,也就是对数据进行后处理。此外,可以在数据流通道中安装各种中间件,进行必要的处理。因此,在开发爬虫时,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
对于C++爬虫来说,学习成本会比较大。而且不能只计算一个人的学习成本。如果软件需要一个团队来开发或者移交,那就是很多人的学习成本。软件调试不是那么容易。
还有一些ruby和php爬虫,这里就不多评价了。确实有一些非常小的data采集任务,在ruby或者php中都用得上。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能存在一些你找不到的bug(很少有人使用它们,而且信息也较少)
4、反爬虫技术
由于搜索引擎的普及,网络爬虫已经成为一种非常流行的网络技术。除了专注于搜索的谷歌、雅虎、微软和百度之外,几乎每个大型门户网站网站都有自己的搜索引擎,无论大小。可以叫的名字有几十种,不知道的种类有上万种。对于一个内容驱动的网站,难免会被网络爬虫光顾。
一些智能搜索引擎爬虫的爬取频率比较合理,资源消耗也比较小,但是很多不良网络爬虫对网页的爬取能力很差,经常循环重复上百个请求。拿,这种爬虫对中小型网站来说往往是毁灭性的打击,尤其是一些缺乏爬虫编写经验的程序员编写的爬虫,破坏性极大,导致网站访问压力会很大非常大,这将导致 网站 访问缓慢甚至无法访问。
一般网站反爬虫从三个方面:用户请求的头文件、用户行为、网站目录和数据加载方式。前两种比较容易遇到,从这些角度来看,大部分网站都是反爬虫。会使用第三种使用ajax的网站,增加了爬取的难度。
4.1 反爬虫通过Headers
反爬取用户请求的头部是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(有些资源的防盗链网站就是检测Referer)。如果遇到这种反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值改为目标网站域名【注释:往往容易被Ignore,通过对请求的抓包分析,确定referer,在模拟访问请求的header中添加】在节目中。对于检测Headers的反爬虫,在爬虫中修改或添加Headers可以很好的绕过。
4.2 基于用户行为的反爬虫
网站的另一部分是检测用户行为,比如同一个IP在短时间内多次访问同一个页面,或者同一个账号在短时间内多次执行相同的操作。【这个反爬需要有足够的ip来处理】
大多数网站都是前一种情况,使用IP代理就可以了。可以专门写一个爬虫来爬取网上公开的代理ip,检测到后全部保存。这样的代理ip爬虫经常使用,最好自己准备一个。有大量代理IP,可以每隔几次更换一个IP,这在requests或者urllib2中很容易做到,这样就可以轻松绕过第一个反爬虫。[评论:动态拨号也是一种解决方案]
对于第二种情况,下一个请求可以在每个请求之后以几秒的随机间隔发出。一些有逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求的方式绕过同一账号短时间内不能多次请求的限制。【点评:账号反爬限制一般比较难处理,随机几秒的请求可能经常被屏蔽。如果可以有多个账号,切换使用,效果会更好】
4.3 动态页面的反爬虫
以上情况大多出现在静态页面中,也有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。一、使用Firebug或者HttpFox分析网络请求【点评:我感觉Google和IE的网络请求分析和使用也很不错】。如果我们能找到ajax请求并分析出具体参数和响应的具体含义,我们可以使用上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
能够直接模拟ajax请求获取数据是很棒的,但是有的网站把ajax请求的所有参数都加密了。我们根本无法构造对我们需要的数据的请求。我这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,接口参数是加密的。遇到这样的网站,我们就不能使用上面的方法了。我使用selenium+phantomJS框架调用浏览器内核,使用phantomJS执行js模拟人类操作,触发页面中的js脚本。从填表到点击按钮再到页面滚动,都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。[评论:支持phantomJS]
使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面提到的添加header在一定程度上是冒充浏览器),它本身就是浏览器,而且phantomJS 是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别触摸类型(12306)或者滑动类型的验证码,页面表单的暴力破解等)。它还将在自动化渗透中发挥重要作用,并将在未来发挥作用。提到这一点。 查看全部
htmlunit抓取动态网页(Web网络爬虫系统的原理及应用)
1、爬虫技术概述
网络爬虫是根据一定的规则自动从万维网上爬取信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,它可以自动采集它可以访问的所有页面获取或更新这些网站的内容和检索方法。从功能上来说,爬虫一般分为数据采集、处理、存储三部分。传统爬虫从一个或多个初始网页的URL开始,获取初始网页上的URL。在抓取网页的过程中,它不断地从当前页面中提取新的 URL 并放入队列中,直到满足系统的某些停止条件。焦点爬虫的工作流程比较复杂。它需要按照一定的网页分析算法过滤掉与主题无关的链接,保留有用的链接,并放入等待抓取的URL队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。保留有用的链接,并将它们放入等待抓取的 URL 队列中。然后,它会根据一定的搜索策略从队列中选择下一个要爬取的网页URL,并重复上述过程,直到达到系统的一定条件并停止。此外,爬虫爬取的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。爬虫抓取到的所有网页都会被系统存储,经过一定的分析、过滤、索引,以供后续查询和检索;对于重点爬虫来说,这个过程中得到的分析结果也可能对后续的爬取过程给出反馈和指导。
与通用网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
(1) 获取目标的描述或定义;
(2) 网页或数据的分析和过滤;
(3) URL 的搜索策略。
2、爬虫原理
2.1 网络爬虫原理
网络爬虫系统的功能是下载网页数据,为搜索引擎系统提供数据源。许多大型网络搜索引擎系统被称为基于Web数据的搜索引擎系统采集,如Google、百度等。这显示了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文字信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程像爬虫或者蜘蛛一样在网络上漫游,所以才叫做网络爬虫系统或者网络蜘蛛系统,英文叫Spider或者Crawler。
2.2 网络爬虫系统的工作原理
在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多个线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页和处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等。爬虫的基本工作是由解析器完成的。资源库用于存储下载的网络资源。通常使用大型数据库,例如 Oracle 数据库来存储和索引它。
控制器
控制器是网络爬虫的中央控制器。主要负责根据系统发送的URL链接分配一个线程,然后启动线程调用爬虫爬取网页。
解析器
解析器负责网络爬虫的主要部分。它的主要任务是:下载网页的功能,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
资源库
它主要是一个容器,用于存储从网页下载的数据记录,并为索引生成提供目标源。大中型数据库产品包括:Oracle、Sql Server等。
网络爬虫系统一般会选择一些比较重要的出度(网页中超链接数)网站较大的URL作为种子URL集。网络爬虫系统使用这些种子集作为初始 URL 来开始数据爬取。因为网页中收录链接信息,所以会通过已有网页的URL获取一些新的URL。网页之间的指向结构可以看作是一片森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能导致爬虫系统陷入网站内部,不利于搜索距离网站首页比较近的网页信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部获取一个 URL 来下载其对应的网页。获取网页内容并存储后,通过解析网页中的链接信息可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,以此类推,直到遍历全网或者满足某个条件。
网络爬虫的基本工作流程如下:
1.首先选择一个精心挑选的种子 URL 的子集;
2.将这些网址放入待抓取的网址队列中;
3. 从待爬取URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页,存入下载的网页库中。此外,将这些 URL 放入 Crawl URL 队列。
4.分析已经爬取的URL队列中的URL,分析其中的其他URL,将这些URL放入待爬取的URL队列,从而进入下一个循环。
2.3 爬取策略
在爬虫系统中,待爬取的 URL 队列是一个重要的部分。待爬取的URL队列中的URL的排列顺序也是一个重要的问题,因为它涉及到先爬到哪个页面,再爬到哪个页面。确定这些 URL 排列顺序的方法称为爬取策略。下面重点介绍几种常见的爬取策略:
2.3.1 深度优先遍历策略
深度优先遍历策略是指网络爬虫会从起始页开始,每次一个链接跟踪每个链接,处理完该行后移动到下一个起始页,并继续跟踪该链接。我们以下图为例:
遍历的路径:AFG EHI BCD
2.3.2 广度优先遍历策略
广度优先遍历的基本思想是将新下载的网页中找到的链接直接插入待爬取URL队列的末尾。也就是说,网络爬虫会先爬取起始网页链接的所有网页,然后选择其中一个链接的网页,继续爬取该网页链接的所有网页。或者以上图为例:
遍历路径:ABCDEF GHI
2.3.3 反向链接策略
反向链接数是指从其他网页指向一个网页的链接数。反向链接的数量表示网页内容被他人推荐的程度。因此,在很多情况下,搜索引擎的爬取系统会使用这个指标来评估网页的重要性,从而确定不同网页的爬取顺序。
在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量并不能完全等同于他人的重要性。因此,搜索引擎倾向于考虑一些可靠的反向链接计数。
2.3.4部分PageRank策略
Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,与待爬取的URL队列中的URL一起形成一组网页,计算每个页面的PageRank值. URL 按 PageRank 值排序,并按该顺序抓取页面。
如果每次爬取一个页面都重新计算一次PageRank值,一个折中的方案是每次爬取K个页面都重新计算一次PageRank值。但是这种情况还是有一个问题:对于下载页面中分析的链接,也就是我们前面提到的那部分未知网页,暂时没有PageRank值。为了解决这个问题,给这些页面一个临时的PageRank值:把这个网页的所有传入链接传入的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排序. 以下示例说明:
2.3.5OPICStrategy
该算法实际上为页面分配了一个重要性分数。在算法开始之前,所有页面都会获得相同的初始现金。当某个页面P被下载时,P的现金分配给从P分析的所有链接,P的现金被清空。根据现金数量对待爬取URL队列中的所有页面进行排序。
2.3.六大网站优先策略
所有待爬取的URL队列中的网页都按照它们所属的网站进行分类。网站需要下载的页面较多,请先下载。这种策略也称为大站点优先策略。
3、爬虫分类
我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫类,基本上可以分为三类:
(1)分布式爬虫:Nutch
(2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
(3)非JAVA爬虫:scrapy(基于Python语言开发)
3.1 分布式爬虫
爬虫使用分布式,主要解决两个问题:
1)海量网址管理
2)网速
现在比较流行的分布式爬虫是Apache的Nutch。但是对于大多数用户来说,Nutch 是这些爬虫中最差的选择,原因如下:
1)Nutch 是为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的三分之二的流程是为搜索引擎设计的。提取意义不大。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发让Nutch适合提取业务,那你基本上会破坏Nutch的框架,把Nutch改得面目全非,而且有能力修改Nutch,还不如自己写一个新的。分布式爬虫框架。
2)Nutch 依赖hadoop 运行,hadoop 本身消耗大量时间。如果集群机器数量少,爬取速度不如单机爬虫快。
3)虽然Nutch有一套插件机制,但还是作为亮点来宣传的。可以看到一些开源的Nutch插件,提供精准提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多糟糕。使用反射机制加载和调用插件,使得程序的编写和调试变得异常困难,更不用说在其上开发复杂的提取系统了。并且 Nutch 没有提供对应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点都是给搜索引擎服务的,不提供细提取的挂载点。Nutch 的大部分精炼提取插件都挂载在“页面解析”(parser)挂载点上。这个挂载点其实是用来解析链接(为后续爬取提供URL)和提供一些搜索引擎的。易于提取的网页信息(元信息、网页文本)。
4)使用Nutch进行爬虫的二次开发,编写和调试爬虫所需的时间往往是单机爬虫所需时间的十倍以上。学习 Nutch 源码的成本非常高,更何况团队中的每个人都必须了解 Nutch 源码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
5)很多人说Nutch2有gora,可以把数据持久化到avro文件、hbase、mysql等,其实很多人都搞错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
6)Nutch2 的版本目前不适合开发。Nutch的官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果要使用hbase和nutch(大多数人使用nutch2是为了使用hbase),只能使用版本0.90左右的hbase,相应地,将hadoop版本降低到hadoop 0.左右@>2。而且nutch2的官方教程也颇具误导性。Nutch2的教程有两个,分别是Nutch1.x和Nutch2.x。Nutch2.x官网是为了支持hbase0.94而写的。但其实这个Nutch2.x是指Nutch2.3之前和Nutch2.2.1之后的一个版本,在官方SVN中不断更新。而且它'
所以,如果你不是搜索引擎,尽量不要选择 Nutch 作为爬虫。一些团队喜欢跟风。他们坚持选择Nutch来开发精制履带。其实是针对Nutch的名声(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目延期。
如果你在做搜索引擎,Nutch1.x 是一个非常不错的选择。Nutch1.x 和 solr 或 es 可以组成一个非常强大的搜索引擎。如果必须使用 Nutch2,建议等到 Nutch2.3 发布。当前的 Nutch2 是一个非常不稳定的版本。
分布式爬虫平台架构图
3.2 JAVA爬虫
在这里,将JAVA爬虫划分为一个单独的类别,因为JAVA在网络爬虫的生态系统中非常完善。相关资料也是最全的。这里可能有争议,我只是随便说说。
其实开源网络爬虫(框架)的开发很简单,难点和复杂的问题已经被前人解决了(比如DOM树解析定位、字符集检测、海量URL去重),可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历本机的文件以查找文件中的信息。没有任何困难。选择开源爬虫框架的原因是为了省事。比如爬虫的URL管理、线程池等模块,任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
对于爬虫的功能。用户比较关心的问题往往是:
1)爬虫是否支持多线程,爬虫是否可以使用代理,爬虫是否可以爬取重复数据,爬虫是否可以爬取JS生成的信息?
不支持多线程、不支持代理、不能过滤重复URL的不叫开源爬虫,叫循环执行http请求。
js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理一个页面。因此,一种策略是利用这些爬虫遍历网站,当遇到需要解析的页面时,将网页的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
2)爬虫可以抓取ajax信息吗?
网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax的http请求,自己生成ajax请求的url,获取返回的数据。如果你自己生成ajax请求,那么使用开源爬虫有什么意义呢?其实就是利用开源爬虫的线程池和URL管理功能(比如断点爬取)。
如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来爬取这些请求呢?
爬虫往往被设计成广度遍历或深度遍历的方式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫并不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历 网站。爬虫的第一轮爬取就是爬取种子集(seeds)中的所有url。简单来说就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫对这些种子进行深度为 1 的广度遍历(默认为广度遍历)。
3)爬虫如何爬取待登录的网站?
这些开源爬虫都支持在爬取时指定cookies,而模拟登录主要依赖cookies。至于如何获取cookies,就不是爬虫管理的问题了。您可以手动获取cookies,使用http请求模拟登录,或者使用模拟浏览器自动登录。
4)爬虫如何从网页中提取信息?
开源爬虫一般会集成网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,我这里就不评论了。
5)爬虫是如何保存网页信息的?
有一些爬虫带有一个负责持久性的模块。例如,webmagic 有一个名为 pipeline 的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等。还有一些爬虫不直接为用户提供数据持久化模块。比如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于用管道模块好不好,就类似于用ORM操作数据库好不好的问题,看你的业务。
6)爬虫被网站拦截了怎么办?
爬虫被网站阻塞,可以通过使用多个代理(随机代理)来解决。但是这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,并编写代码让代理随机获取(从数组中)。
7)网页可以调用爬虫吗?
爬虫的调用是在Web的服务器端调用的。您可以按照平时使用的方式使用它。可以使用这些爬虫。
8)爬虫速度怎么样?
单机开源爬虫的速度基本可以用到本地网速的极限。爬虫速度慢往往是因为用户减少了线程数,网速慢,或者数据持久化时与数据库的交互慢。而这些东西往往是由用户的机器和二次开发的代码决定的。这些开源爬虫的速度非常好。
9) 明明代码写对了,但是数据爬不出来。爬虫有问题吗?另一个爬虫可以解决吗?
如果代码写得正确,无法爬取数据,其他爬虫也将无法爬取。在这种情况下,要么是 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。如果无法爬取数据,则无法通过更改爬虫来解决。
10)哪个爬虫可以判断网站是否已经爬完,哪个爬虫可以根据主题爬取?
爬虫无法判断网站是否已经爬完,只能尽量覆盖。
至于根据主题爬,爬虫把内容爬下来后就知道主题是什么了。因此,通常是整体爬下来,然后对内容进行过滤。如果爬取的范围太广,可以通过限制 URL 正则化来缩小范围。
11)哪个爬虫的设计模式和架构比较好?
设计模式是胡说八道。都说软件设计模式不错,软件开发后总结了几种设计模式。设计模式对软件开发没有指导意义。使用设计模式设计爬虫只会让爬虫的设计更加臃肿。
至于架构,目前开源爬虫主要是设计详细的数据结构,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,用任何框架都谈不上。
所以对于 JAVA 开源爬虫,我认为,只要找到一个运行良好的。如果业务复杂,使用哪个爬虫,只能通过复杂的二次开发来满足需求。
3.3 非JAVA爬虫
在非JAVA语言编写的爬虫中,不乏优秀的爬虫。这里提取为一个类别,不是为了讨论爬虫本身的好坏,而是为了讨论larbin、scrapy等爬虫对开发成本的影响。
先说python爬虫,python用30行代码就可以完成JAVA 50行代码的任务。Python写代码确实很快,但是在调试代码阶段,调试python代码所消耗的时间往往比编码阶段节省的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务也不复杂,用scrapy还是不错的,可以轻松完成爬取任务。
上图是Scrapy的架构图。绿线是数据流。从初始 URL 开始,Scheduler 会将其交给 Downloader 进行下载。下载完成后交给 Spider 进行分析,将要保存的数据发送到 Item Pipeline ,也就是对数据进行后处理。此外,可以在数据流通道中安装各种中间件,进行必要的处理。因此,在开发爬虫时,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
对于C++爬虫来说,学习成本会比较大。而且不能只计算一个人的学习成本。如果软件需要一个团队来开发或者移交,那就是很多人的学习成本。软件调试不是那么容易。
还有一些ruby和php爬虫,这里就不多评价了。确实有一些非常小的data采集任务,在ruby或者php中都用得上。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能存在一些你找不到的bug(很少有人使用它们,而且信息也较少)
4、反爬虫技术
由于搜索引擎的普及,网络爬虫已经成为一种非常流行的网络技术。除了专注于搜索的谷歌、雅虎、微软和百度之外,几乎每个大型门户网站网站都有自己的搜索引擎,无论大小。可以叫的名字有几十种,不知道的种类有上万种。对于一个内容驱动的网站,难免会被网络爬虫光顾。
一些智能搜索引擎爬虫的爬取频率比较合理,资源消耗也比较小,但是很多不良网络爬虫对网页的爬取能力很差,经常循环重复上百个请求。拿,这种爬虫对中小型网站来说往往是毁灭性的打击,尤其是一些缺乏爬虫编写经验的程序员编写的爬虫,破坏性极大,导致网站访问压力会很大非常大,这将导致 网站 访问缓慢甚至无法访问。
一般网站反爬虫从三个方面:用户请求的头文件、用户行为、网站目录和数据加载方式。前两种比较容易遇到,从这些角度来看,大部分网站都是反爬虫。会使用第三种使用ajax的网站,增加了爬取的难度。
4.1 反爬虫通过Headers
反爬取用户请求的头部是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(有些资源的防盗链网站就是检测Referer)。如果遇到这种反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值改为目标网站域名【注释:往往容易被Ignore,通过对请求的抓包分析,确定referer,在模拟访问请求的header中添加】在节目中。对于检测Headers的反爬虫,在爬虫中修改或添加Headers可以很好的绕过。
4.2 基于用户行为的反爬虫
网站的另一部分是检测用户行为,比如同一个IP在短时间内多次访问同一个页面,或者同一个账号在短时间内多次执行相同的操作。【这个反爬需要有足够的ip来处理】
大多数网站都是前一种情况,使用IP代理就可以了。可以专门写一个爬虫来爬取网上公开的代理ip,检测到后全部保存。这样的代理ip爬虫经常使用,最好自己准备一个。有大量代理IP,可以每隔几次更换一个IP,这在requests或者urllib2中很容易做到,这样就可以轻松绕过第一个反爬虫。[评论:动态拨号也是一种解决方案]
对于第二种情况,下一个请求可以在每个请求之后以几秒的随机间隔发出。一些有逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求的方式绕过同一账号短时间内不能多次请求的限制。【点评:账号反爬限制一般比较难处理,随机几秒的请求可能经常被屏蔽。如果可以有多个账号,切换使用,效果会更好】
4.3 动态页面的反爬虫
以上情况大多出现在静态页面中,也有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。一、使用Firebug或者HttpFox分析网络请求【点评:我感觉Google和IE的网络请求分析和使用也很不错】。如果我们能找到ajax请求并分析出具体参数和响应的具体含义,我们可以使用上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
能够直接模拟ajax请求获取数据是很棒的,但是有的网站把ajax请求的所有参数都加密了。我们根本无法构造对我们需要的数据的请求。我这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,接口参数是加密的。遇到这样的网站,我们就不能使用上面的方法了。我使用selenium+phantomJS框架调用浏览器内核,使用phantomJS执行js模拟人类操作,触发页面中的js脚本。从填表到点击按钮再到页面滚动,都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。[评论:支持phantomJS]
使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面提到的添加header在一定程度上是冒充浏览器),它本身就是浏览器,而且phantomJS 是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别触摸类型(12306)或者滑动类型的验证码,页面表单的暴力破解等)。它还将在自动化渗透中发挥重要作用,并将在未来发挥作用。提到这一点。
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 61 次浏览 • 2022-02-14 18:06
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键—— > 点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。
使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ
欢迎补充:) 查看全部
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键—— > 点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。

使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ

欢迎补充:)
htmlunit抓取动态网页(让我们一起出发探索未知的奥秘吧!(组图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 81 次浏览 • 2022-02-12 05:25
下面就给大家介绍一下如何通过html+css+mysql+php快速创建动态网页,让我们一起来探索未知的奥秘吧!!!
一、搭建开发环境
(1)apache+php+mysql环境搭建
因为使用apache作为服务器,使用mysql作为数据库存储数据,使用php编写代码实现网页与数据库的交互数据,需要下载以上软件,但是安装以上软件的环境和配置都很麻烦,所以这里我们使用一个强大的建站集成软件包---XAMPP,
(2)数据库客户端软件导航
直接在cmd命令控制台中操作数据库不方便,不够直观。当然也可以直接用phpmyadmin操作(上面的xampp包安装好后,在浏览器输入127.0.0.1/phpmyadmin可以打开),但是phpmyadmin操作不方便,这里我们使用Navicat制作的数据库客户端
点击connect,输入连接名称,(这里我直接取IP地址的名称127.0.0.1),主机名和端口号不需要要更改的,这里的用户名和密码,如果你使用的是xampp,用户名是root,密码为空;如果不是xampp安装的,可以根据你设置的用户名和密码登录。填写完后点击连接测试,没有问题直接确认连接数据库。
另外,如果你想掌握数据库,简单来说,你想对数据库进行任何操作都必须操作sql语句。一般来说,它分为四种操作:添加、删除、修改和查询。
①添加:将数据写入数据库
语句:插入用户(`username`,`password`)值('name','passwd')
(ps新手一定要注意用户数据表后面的``符号是tab键上面的引号,值后面的值是单引号)
②删除:删除已有数据
声明:从用户中删除 WHERE id='3'
③Change:修改数据
语句:update set users username='new value', password='new value' WHERE id=3
④检查:从数据库中读取数据
语句:select * from users where id>1 order by id desc limit 0,2
(3)html网页创作工具sublime text
Sublime Text 是一个代码编辑器(Sublime Text 2 是付费软件,但可以无限期试用)和一个用于 HTML 和散文的高级文本编辑器。Sublime text 拥有漂亮的用户界面和强大的功能,非常适合写代码的程序员。
使用sublime text写网页代码,可以掌握这么一个小技巧,先新建一个文件,保存格式为html网页格式,然后用sublime text打开,输入html:4s然后按tab键生成一个通用框架。当然,如果要使用这个快捷键,必须按照我上面给出的链接,按照步骤安装好Emmet插件,才能使用。
(4)网站域名配置
一般来说,当你在浏览器中打开URL 127.0.0.1 时,会跳转到apache默认目录下的一个URL。这里我修改一下,修改为我的项目目录,E:PHPxamppapacheconf,打开httpd.conf文件,修改里面的路径为你存放网站的目录,这里我的修改是
DocumentRoot "E:/php/xampp/workplace"
这里要注意根据自己下载的路径修改自己的目录。其次,我也再次修改了URL 127.0.0.1,使其虚拟域名为,,修改后重启后,在浏览器中输入,会出现如下场景:
这里发现我修改的DNS配置,不知道什么时候在前面加了注释,所以打不开。大家也应该注意按照我给的连接配置。如果无法打开,请检查配置文件。错误。
总之,配置环境和工具基本搭建成功,接下来就开始讲解本篇博客的项目。
二、写博客网站写作
1.整体框架
首先介绍一下我的整体框架,解释一下,让大家先熟悉一下。
blog为项目名称,admin文件夹存放后台登录文件,core文件夹存放核心文件,theme文件夹存放网页样式文件,upfiles文件夹存放从本地上传到的图片信息服务器,然后 config.php 文件是整个博客的配置文件网站,header.inc.php是加载了一个页面样式信息,index.php文件是网站的首页@>,read.php 文件是 网站 文章 特定链接的主页。
这里给出数据库表的设计,供大家参考学习。这里我主要建三张表,admin用来存放后台管理员的注册登录数据,也就是账号和密码:
页表主要用于存放博客信息,这里也给出图片方便安装图建表:
最后给出设置表,主要用于存放博客的系统设置:
2.网站后台管理员写作
(1)登录界面(login.php)
关于这个页面,我会在这里给出源代码。登录页面实际上是一个从数据库中读取的过程。这个登录页面的设计主要是使用bootstrap来设计的。
在里面,它收录了各种样式、组件和 JavaScript 插件,可以说是非常好用。
我这里使用的方式是下载bootstrap,然后加压文件,复制到主题文件夹。调用方法见下方源码。我在源代码中给出了详细的解释。
源代码:
管理员登录界面
<p class="container">
<p class="row" style="margin-top:200px;">
管理员登录
导航.inc.php
<p class="container-fluid">
<p class="navbar-header">
Toggle navigation
ADMIN
博客管理 (current)
管理员管理
系统管理
退出
</p>
</p>
(4) 博客管理界面(blog.php)
这里一共有三个功能,修改、删除、添加博客界面。下面我将分别列出添加博客接口。
(5)添加博客接口(blog_add.php)
这里,如果编辑器需要图片上传功能,需要在文件中设置。此文件设置为 (blog_uopload.php)
blog_add.php 源代码
<p>
添加博客
<p class="container">
博客管理 返回
<p class="rows"> 查看全部
htmlunit抓取动态网页(让我们一起出发探索未知的奥秘吧!(组图))
下面就给大家介绍一下如何通过html+css+mysql+php快速创建动态网页,让我们一起来探索未知的奥秘吧!!!

一、搭建开发环境
(1)apache+php+mysql环境搭建
因为使用apache作为服务器,使用mysql作为数据库存储数据,使用php编写代码实现网页与数据库的交互数据,需要下载以上软件,但是安装以上软件的环境和配置都很麻烦,所以这里我们使用一个强大的建站集成软件包---XAMPP,

(2)数据库客户端软件导航
直接在cmd命令控制台中操作数据库不方便,不够直观。当然也可以直接用phpmyadmin操作(上面的xampp包安装好后,在浏览器输入127.0.0.1/phpmyadmin可以打开),但是phpmyadmin操作不方便,这里我们使用Navicat制作的数据库客户端

点击connect,输入连接名称,(这里我直接取IP地址的名称127.0.0.1),主机名和端口号不需要要更改的,这里的用户名和密码,如果你使用的是xampp,用户名是root,密码为空;如果不是xampp安装的,可以根据你设置的用户名和密码登录。填写完后点击连接测试,没有问题直接确认连接数据库。

另外,如果你想掌握数据库,简单来说,你想对数据库进行任何操作都必须操作sql语句。一般来说,它分为四种操作:添加、删除、修改和查询。
①添加:将数据写入数据库
语句:插入用户(`username`,`password`)值('name','passwd')
(ps新手一定要注意用户数据表后面的``符号是tab键上面的引号,值后面的值是单引号)
②删除:删除已有数据
声明:从用户中删除 WHERE id='3'
③Change:修改数据
语句:update set users username='new value', password='new value' WHERE id=3
④检查:从数据库中读取数据
语句:select * from users where id>1 order by id desc limit 0,2
(3)html网页创作工具sublime text
Sublime Text 是一个代码编辑器(Sublime Text 2 是付费软件,但可以无限期试用)和一个用于 HTML 和散文的高级文本编辑器。Sublime text 拥有漂亮的用户界面和强大的功能,非常适合写代码的程序员。

使用sublime text写网页代码,可以掌握这么一个小技巧,先新建一个文件,保存格式为html网页格式,然后用sublime text打开,输入html:4s然后按tab键生成一个通用框架。当然,如果要使用这个快捷键,必须按照我上面给出的链接,按照步骤安装好Emmet插件,才能使用。
(4)网站域名配置
一般来说,当你在浏览器中打开URL 127.0.0.1 时,会跳转到apache默认目录下的一个URL。这里我修改一下,修改为我的项目目录,E:PHPxamppapacheconf,打开httpd.conf文件,修改里面的路径为你存放网站的目录,这里我的修改是
DocumentRoot "E:/php/xampp/workplace"
这里要注意根据自己下载的路径修改自己的目录。其次,我也再次修改了URL 127.0.0.1,使其虚拟域名为,,修改后重启后,在浏览器中输入,会出现如下场景:

这里发现我修改的DNS配置,不知道什么时候在前面加了注释,所以打不开。大家也应该注意按照我给的连接配置。如果无法打开,请检查配置文件。错误。
总之,配置环境和工具基本搭建成功,接下来就开始讲解本篇博客的项目。
二、写博客网站写作
1.整体框架
首先介绍一下我的整体框架,解释一下,让大家先熟悉一下。

blog为项目名称,admin文件夹存放后台登录文件,core文件夹存放核心文件,theme文件夹存放网页样式文件,upfiles文件夹存放从本地上传到的图片信息服务器,然后 config.php 文件是整个博客的配置文件网站,header.inc.php是加载了一个页面样式信息,index.php文件是网站的首页@>,read.php 文件是 网站 文章 特定链接的主页。

这里给出数据库表的设计,供大家参考学习。这里我主要建三张表,admin用来存放后台管理员的注册登录数据,也就是账号和密码:

页表主要用于存放博客信息,这里也给出图片方便安装图建表:

最后给出设置表,主要用于存放博客的系统设置:

2.网站后台管理员写作
(1)登录界面(login.php)

关于这个页面,我会在这里给出源代码。登录页面实际上是一个从数据库中读取的过程。这个登录页面的设计主要是使用bootstrap来设计的。

在里面,它收录了各种样式、组件和 JavaScript 插件,可以说是非常好用。

我这里使用的方式是下载bootstrap,然后加压文件,复制到主题文件夹。调用方法见下方源码。我在源代码中给出了详细的解释。
源代码:
管理员登录界面
<p class="container">
<p class="row" style="margin-top:200px;">
管理员登录
导航.inc.php
<p class="container-fluid">
<p class="navbar-header">
Toggle navigation
ADMIN
博客管理 (current)
管理员管理
系统管理
退出
</p>
</p>
(4) 博客管理界面(blog.php)
这里一共有三个功能,修改、删除、添加博客界面。下面我将分别列出添加博客接口。

(5)添加博客接口(blog_add.php)
这里,如果编辑器需要图片上传功能,需要在文件中设置。此文件设置为 (blog_uopload.php)
blog_add.php 源代码
<p>
添加博客
<p class="container">
博客管理 返回
<p class="rows">
htmlunit抓取动态网页(selenium模块为第三方模块需要安装的操作软件操作原理)
网站优化 • 优采云 发表了文章 • 0 个评论 • 59 次浏览 • 2022-02-09 14:04
【百度云搜索,搜索各种素材:】【搜索网盘,搜索各种素材:】
硒模块
selenium 模块是需要安装的第三方模块。 selenium模块是一个api接口模块,操作各种浏览器对应的软件
selenium模块是api接口模块,操作各种浏览器对应的软件,所以需要下载浏览器对应的操作软件
工作原理是:selenium模块操作浏览器操作软件,浏览器操作软件操作浏览器
Selenium 2.0 用于以下浏览器
谷歌浏览器
Internet Explorer 7、8、9、10、11
火狐
Safari
歌剧
HtmlUnit
幻影
安卓
iOS
Selenium的核心是用js控制浏览器
下载相应的浏览器操作软件
铬:
边缘:
火狐:
Safari:
我们这里使用 Firefox 作为一栏
首先将火狐浏览器的操作软件geckodriver.exe文件放入爬虫目录
selenium 模块可以模拟用户行为来操作各种版本的浏览器
webdriver.Firefox('操作浏览器软件路径') 实例化Firefox浏览器对象
get('url') 访问网站
find_element_by_xpath('xpath expression') 通过xpath表达式找到对应的元素
clear() 清除输入框内容
send_keys('content')将内容写入输入框
click()点击事件
get_screenshot_as_file('截屏保存路径名') 将网页截图保存到该目录
page_source 获取网页 htnl 源代码
browser.close() 关闭浏览器
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.tmall.com/?spm=a220o.1000855.a2226mz.1.5c90c3484bZCx6')
# 模拟用户操作
browser.find_element_by_xpath('//input[@id="mq"]').clear() # 通过xpath表达式找到输入框,clear()清空输入框里的内容
browser.find_element_by_xpath('//input[@id="mq"]').send_keys('连衣裙') # 通过xpath表达式找到输入框,send_keys()将内容写入输入框
browser.find_element_by_xpath('//button[@type="submit"]').click() # 通过xpath表达式找到搜索按钮,click()点击事件
time.sleep(3) # 等待3秒
browser.get_screenshot_as_file('H:/py/17/img/123.jpg') # 将网页截图,保存到此目录
neir = browser.page_source # 获取网页内容
print(neir)
browser.close() # 关闭浏览器
使用 scrapy 的 Selector 方法。过滤所选数据
Selector()方法,过滤选中的数据,参数为获取的字符串html源码
Selenium 操作浏览器滚动条
execute_script(js)方法,执行原生态js脚本
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
from scrapy.selector import Selector
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.oschina.net/blog')
time.sleep(3) # 等待3秒
for i in range(3): # 滚动3次滚动条
js = 'window.scrollTo(0,document.body.scrollHeight); var lenofpage=document.body.scrollHeight; return lenofpage'
browser.execute_script(js) # 执行js语言滚动滚动条
time.sleep(3)
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
设置请求页面不加载图片,提高请求效率
ChromeOptions() 方法,创建谷歌浏览器设置对象
Chrome() 方法,创建谷歌浏览器对象
谷歌浏览器在下面列出
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
from scrapy.selector import Selector
#设置请求网页不加载图片,提高请求效率
chrome_options = webdriver.ChromeOptions() #创建谷歌浏览器设置对象
prefs = {"profile.managed_default_content_settings.images": 2} #设置谷歌浏览器不加载图片
chrome_options.add_experimental_option('prefs', prefs) #将不加载图片添加到浏览器
browser = webdriver.Chrome(executable_path='H:/py/16/adc/adc/Firefox/chromedriver.exe', chrome_options=chrome_options)
# browser.set_page_load_timeout(40) #设置页面最长加载时间为40s
browser.get('https://www.taobao.com/')
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
selenium 模块也可以操作 PhantomJS 浏览器。 PhantomJS是无界面浏览器,比较清爽,但是多线程会降低性能
重要提示:我们建议使用 chromedriver.exe、谷歌浏览器 查看全部
htmlunit抓取动态网页(selenium模块为第三方模块需要安装的操作软件操作原理)
【百度云搜索,搜索各种素材:】【搜索网盘,搜索各种素材:】
硒模块
selenium 模块是需要安装的第三方模块。 selenium模块是一个api接口模块,操作各种浏览器对应的软件
selenium模块是api接口模块,操作各种浏览器对应的软件,所以需要下载浏览器对应的操作软件
工作原理是:selenium模块操作浏览器操作软件,浏览器操作软件操作浏览器
Selenium 2.0 用于以下浏览器
谷歌浏览器
Internet Explorer 7、8、9、10、11
火狐
Safari
歌剧
HtmlUnit
幻影
安卓
iOS

Selenium的核心是用js控制浏览器
下载相应的浏览器操作软件
铬:
边缘:
火狐:
Safari:
我们这里使用 Firefox 作为一栏
首先将火狐浏览器的操作软件geckodriver.exe文件放入爬虫目录
selenium 模块可以模拟用户行为来操作各种版本的浏览器
webdriver.Firefox('操作浏览器软件路径') 实例化Firefox浏览器对象
get('url') 访问网站
find_element_by_xpath('xpath expression') 通过xpath表达式找到对应的元素
clear() 清除输入框内容
send_keys('content')将内容写入输入框
click()点击事件
get_screenshot_as_file('截屏保存路径名') 将网页截图保存到该目录
page_source 获取网页 htnl 源代码
browser.close() 关闭浏览器
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.tmall.com/?spm=a220o.1000855.a2226mz.1.5c90c3484bZCx6')
# 模拟用户操作
browser.find_element_by_xpath('//input[@id="mq"]').clear() # 通过xpath表达式找到输入框,clear()清空输入框里的内容
browser.find_element_by_xpath('//input[@id="mq"]').send_keys('连衣裙') # 通过xpath表达式找到输入框,send_keys()将内容写入输入框
browser.find_element_by_xpath('//button[@type="submit"]').click() # 通过xpath表达式找到搜索按钮,click()点击事件
time.sleep(3) # 等待3秒
browser.get_screenshot_as_file('H:/py/17/img/123.jpg') # 将网页截图,保存到此目录
neir = browser.page_source # 获取网页内容
print(neir)
browser.close() # 关闭浏览器
使用 scrapy 的 Selector 方法。过滤所选数据
Selector()方法,过滤选中的数据,参数为获取的字符串html源码
Selenium 操作浏览器滚动条
execute_script(js)方法,执行原生态js脚本
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
import time
from scrapy.selector import Selector
browser = webdriver.Firefox(executable_path='H:/py/16/adc/adc/Firefox/geckodriver.exe')
browser.get('https://www.oschina.net/blog')
time.sleep(3) # 等待3秒
for i in range(3): # 滚动3次滚动条
js = 'window.scrollTo(0,document.body.scrollHeight); var lenofpage=document.body.scrollHeight; return lenofpage'
browser.execute_script(js) # 执行js语言滚动滚动条
time.sleep(3)
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
设置请求页面不加载图片,提高请求效率
ChromeOptions() 方法,创建谷歌浏览器设置对象
Chrome() 方法,创建谷歌浏览器对象
谷歌浏览器在下面列出
#!/usr/bin/env python
# -*- coding:utf8 -*-
from selenium import webdriver # 导入selenium模块来操作浏览器软件
from scrapy.selector import Selector
#设置请求网页不加载图片,提高请求效率
chrome_options = webdriver.ChromeOptions() #创建谷歌浏览器设置对象
prefs = {"profile.managed_default_content_settings.images": 2} #设置谷歌浏览器不加载图片
chrome_options.add_experimental_option('prefs', prefs) #将不加载图片添加到浏览器
browser = webdriver.Chrome(executable_path='H:/py/16/adc/adc/Firefox/chromedriver.exe', chrome_options=chrome_options)
# browser.set_page_load_timeout(40) #设置页面最长加载时间为40s
browser.get('https://www.taobao.com/')
neir = browser.page_source # 获取网页内容
# print(neir)
gl_neir = Selector(text=neir)
dedao = gl_neir.css('title::text').extract()
print(dedao)
# browser.close() # 关闭浏览器
selenium 模块也可以操作 PhantomJS 浏览器。 PhantomJS是无界面浏览器,比较清爽,但是多线程会降低性能
重要提示:我们建议使用 chromedriver.exe、谷歌浏览器
htmlunit抓取动态网页(使用本文中推荐的开源工具——HtmlUnit,一款能够模拟浏览器的抓包神器!)
网站优化 • 优采云 发表了文章 • 0 个评论 • 52 次浏览 • 2022-02-06 04:23
之前,一峰写过一篇关于使用Jsoup爬取网页内容的文章文章:
[Jsoup] HTML解析器,轻松获取网页内容
Jsoup提供的api非常方便,完全类似于JQuery操作,轻松抓取网页数据。但是像Jsoup这样的普通爬虫工具的缺点是不能处理js生成的内容。
做过Html开发的都知道现在很多网站都是用ajax和JavaScript来获取和处理数据,普通爬虫工具已经无法处理js中的内容了。
比如我们在本地新建一个测试web文件text.html,源码如下:
main.html
a {
line-height: 30px;
margin: 20px;
}
var datas = [ {
href : "http://www.jianshu.com/p/8d8edf25850d",
title : "推荐一款编程字体,让代码看着更美"
}, {
href : "http://www.jianshu.com/p/153d9f31288d",
title : "Android 利用Camera实现中轴3D卡牌翻转效果"
}, {
href : "http://www.jianshu.com/p/d6fb0c9c9c26",
title : "【Eclipse】挖掘专属最有用的快捷键组合"
}, {
href : "http://www.jianshu.com/p/72d69b49d135",
title : "【IIS】Windows下利用IIS建立网站并实现局域网共享"
} ];
window.onload = function() {
var infos = document.getElementById("infos");
for( var i = 0 ; i < datas.length ; i++)
{
var a = document.createElement("a");
a.href = datas[i].href ;
a.innerText = datas[i].title;
infos.appendChild(a);
infos.appendChild(document.createElement("br"))
}
}
HtmlUnit 测试网页内容!
通过IIS发布本地网站(参考之前逸峰写的文章:
【IIS】在Windows下使用IIS建立网站,实现局域网共享),
网页在浏览器中显示的效果如下:
网页显示效果.jpg
虽然通过网页检查元素,可以看到body中收录了网页显示的文字内容:
网络评论元素.jpg
但是,它根本无法通过 Jsoup 工具获得!从网页的源码可以看出,我们需要爬取的内容是在页面显示出来后通过ajax和JavaScript加载的。
那么该怎么办?使用本文推荐的开源工具——HtmlUnit,一个可以模拟浏览器的抓包神器!
在官网下载对应的jar包,添加到项目工程的lib中。简单的测试代码如下:
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.ParseException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
/**
* @author 亦枫
* @created_time 2016年1月12日
* @file_user_todo Java测试类
* @blog http://www.jianshu.com/users/1 ... icles
*/
public class JavaTest {
/**
* 入口函数
* @param args
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
try {
WebClient webClient = new WebClient(BrowserVersion.CHROME);
HtmlPage htmlPage = (HtmlPage) webClient.getPage("http://localhost/test.html");
DomNodeList domNodeList = htmlPage.getElementsByTagName("a");
for (int i = 0; i < domNodeList.size(); i++) {
DomElement domElement = (DomElement) domNodeList.get(i);
System.out.println(domElement.asText());
}
webClient.close();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行后,控制台打印出结果:
HtmlUnit测试结果.jpg
可以看出,HtmlUnit 能够抓取 AJAX 和 JavaScript 加载的内容。
HtmlUnit的介绍在官网上很详细。以下内容为易峰翻译的部分内容,供大家参考:
HtmlUnit 是一个基于 Java 的浏览器程序,没有图形界面。它可以调用 HTML 文档并提供 API,让开发人员可以像在普通浏览器上一样获取 Web 内容、填写表单、单击超链接等。
它对 JavaScript 的支持非常好并且还在改进中,可以解析非常复杂的 AJAX 库,模拟不同配置下的 Chrome、Firefox 和 IE 浏览器。
HtmlUnit 通常用于测试目的和检索 网站 信息。
HtmlUnit 提供了许多测试网络请求和爬取网页内容的功能。可以去官网或者其他网站学习使用。 查看全部
htmlunit抓取动态网页(使用本文中推荐的开源工具——HtmlUnit,一款能够模拟浏览器的抓包神器!)
之前,一峰写过一篇关于使用Jsoup爬取网页内容的文章文章:
[Jsoup] HTML解析器,轻松获取网页内容
Jsoup提供的api非常方便,完全类似于JQuery操作,轻松抓取网页数据。但是像Jsoup这样的普通爬虫工具的缺点是不能处理js生成的内容。
做过Html开发的都知道现在很多网站都是用ajax和JavaScript来获取和处理数据,普通爬虫工具已经无法处理js中的内容了。
比如我们在本地新建一个测试web文件text.html,源码如下:
main.html
a {
line-height: 30px;
margin: 20px;
}
var datas = [ {
href : "http://www.jianshu.com/p/8d8edf25850d",
title : "推荐一款编程字体,让代码看着更美"
}, {
href : "http://www.jianshu.com/p/153d9f31288d",
title : "Android 利用Camera实现中轴3D卡牌翻转效果"
}, {
href : "http://www.jianshu.com/p/d6fb0c9c9c26",
title : "【Eclipse】挖掘专属最有用的快捷键组合"
}, {
href : "http://www.jianshu.com/p/72d69b49d135",
title : "【IIS】Windows下利用IIS建立网站并实现局域网共享"
} ];
window.onload = function() {
var infos = document.getElementById("infos");
for( var i = 0 ; i < datas.length ; i++)
{
var a = document.createElement("a");
a.href = datas[i].href ;
a.innerText = datas[i].title;
infos.appendChild(a);
infos.appendChild(document.createElement("br"))
}
}
HtmlUnit 测试网页内容!
通过IIS发布本地网站(参考之前逸峰写的文章:
【IIS】在Windows下使用IIS建立网站,实现局域网共享),
网页在浏览器中显示的效果如下:
网页显示效果.jpg
虽然通过网页检查元素,可以看到body中收录了网页显示的文字内容:
网络评论元素.jpg
但是,它根本无法通过 Jsoup 工具获得!从网页的源码可以看出,我们需要爬取的内容是在页面显示出来后通过ajax和JavaScript加载的。
那么该怎么办?使用本文推荐的开源工具——HtmlUnit,一个可以模拟浏览器的抓包神器!
在官网下载对应的jar包,添加到项目工程的lib中。简单的测试代码如下:
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.ParseException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
/**
* @author 亦枫
* @created_time 2016年1月12日
* @file_user_todo Java测试类
* @blog http://www.jianshu.com/users/1 ... icles
*/
public class JavaTest {
/**
* 入口函数
* @param args
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
try {
WebClient webClient = new WebClient(BrowserVersion.CHROME);
HtmlPage htmlPage = (HtmlPage) webClient.getPage("http://localhost/test.html");
DomNodeList domNodeList = htmlPage.getElementsByTagName("a");
for (int i = 0; i < domNodeList.size(); i++) {
DomElement domElement = (DomElement) domNodeList.get(i);
System.out.println(domElement.asText());
}
webClient.close();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行后,控制台打印出结果:
HtmlUnit测试结果.jpg
可以看出,HtmlUnit 能够抓取 AJAX 和 JavaScript 加载的内容。
HtmlUnit的介绍在官网上很详细。以下内容为易峰翻译的部分内容,供大家参考:
HtmlUnit 是一个基于 Java 的浏览器程序,没有图形界面。它可以调用 HTML 文档并提供 API,让开发人员可以像在普通浏览器上一样获取 Web 内容、填写表单、单击超链接等。
它对 JavaScript 的支持非常好并且还在改进中,可以解析非常复杂的 AJAX 库,模拟不同配置下的 Chrome、Firefox 和 IE 浏览器。
HtmlUnit 通常用于测试目的和检索 网站 信息。
HtmlUnit 提供了许多测试网络请求和爬取网页内容的功能。可以去官网或者其他网站学习使用。
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 100 次浏览 • 2022-02-04 06:12
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键->点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。
使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但是我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ
欢迎补充:)
转载于: 查看全部
htmlunit抓取动态网页(1.maven依赖引入2.Java代码3.其他功能总结(组图))
通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient来获取网页的源代码,直观可见,代码内容与网页内容一致通过浏览器右键->点击查看网页源代码。
但是现在越来越多的网站使用Js动态生成内容来提高相应的速度,而HttpClient只是在后端返回相应响应的请求体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient无法获取。
对于获取Js生成的网页,我们主要是模拟浏览器的操作,渲染响应的请求体,最后得到相应的内容。
我们在这里讨论的模拟方法大致有两种:
抓取目标
我们这次的目标是获取bilibili动态生成的动画列表。左上为抓取的目标列表,左下为浏览器渲染的HTML内容,右为服务器返回的响应正文。通过对比可以看出,目标列表是由Js生成的。

使用 Selenium 获取页面
Selenium 是一种用于自动测试 Web 应用程序的工具,更多的是在 Google 上。这里我们主要用它来模拟页面的操作并返回结果,对于网页截图的功能也是可行的。
Selenium 支持模拟很多浏览器,但是我们这里只模拟 PhantomJS,因为 PhantomJS 是一个脚本化的、无界面的 WebKit,它使用 JavaScript 作为脚本语言来实现各种功能。由于是无接口的,所以在速度性能方面会更好。
1.下载
使用PhantomJS需要从官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip
2.maven依赖介绍:
org.seleniumhq.selenium
selenium-java
2.53.0
com.codeborne
phantomjsdriver
1.2.1
org.seleniumhq.selenium
selenium-remote-driver
org.seleniumhq.selenium
selenium-java
3.示例代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.ArrayList;
/**
* @author GinPonson
*/
public class TestSelenium {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args){
System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
//设置代理或者其他参数
ArrayList cliArgsCap = new ArrayList();
//cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
//cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
//cliArgsCap.add("--proxy-type=http");
capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
//capabilities.setCapability("phantomjs.page.settings.userAgent", "");
WebDriver driver = new PhantomJSDriver(capabilities);
driver.get("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(driver.getPageSource());
driver.quit();
}
}
4.其他功能
使用 HtmlUnit 获取页面
HtmlUnit 在功能上是 Selenium 的一个子集,Selenium 有相应的 HtmlUnit 实现。HtmlUnit 是一个用 Java 编写的非界面浏览器。因为没有接口,所以执行速度还是可以的。
1.maven依赖介绍
net.sourceforge.htmlunit
htmlunit
2.25
2.Java 代码
/**
* @author GinPonson
*/
public class TestHtmlUnit {
static final String HOST = "127.0.0.1";
static final String PORT = "80";
static final String USER = "gin";
static final String PWD = "12345";
public static void main(String[] args) throws Exception{
WebClient webClient = new WebClient();
//设置代理
//ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
//proxyConfig.setProxyHost(HOST);
//proxyConfig.setProxyPort(Integer.valueOf(PORT));
//DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//credentialsProvider.addCredentials(USER, PWD);
//设置参数
//webClient.getOptions().setCssEnabled(false);
//webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = webClient.getPage("http://www.bilibili.com/video/ ... 6quot;);
System.out.println(page.asXml());
webClient.close();
}
}
3.其他功能
总结
PhantomJS 和 HtmlUnit 都有很好的模拟浏览器页面生成的功能。PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,并且有浏览器截图功能,可以模拟登录操作。HtmlUnit 使用 Rhino 引擎解析 Js。有时解析速度很慢。和上面的例子一样,需要很长时间,但是 HtmlUnit 可以获取页面并解析元素。不错的工具。
HtmlUnit遇到错误后,处理前后相差7分钟,可能我不会用QAQ

欢迎补充:)
转载于:
htmlunit抓取动态网页( 所有无需环境下的浏览器开源项目,你知道几个?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2022-02-02 21:14
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个开源项目,用于面向 .net 的 Web 自动化测试。它为 Web 元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇 查看全部
htmlunit抓取动态网页(
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个开源项目,用于面向 .net 的 Web 自动化测试。它为 Web 元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇
htmlunit抓取动态网页(网络爬虫软件从指定网页获取特定内容的几种解决方案)
网站优化 • 优采云 发表了文章 • 0 个评论 • 40 次浏览 • 2022-02-02 10:14
摘要:对于程序员或开发者来说,拥有编程能力可以让他们轻松、有趣地构建一个网络数据抓取程序。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。
网页数据抓取是指从网站中提取特定内容,而不需要请求网站的API接口来获取内容。“网页数据” 作为网站 用户体验的一部分,例如网页上的文本、图像、声音、视频和动画,它们都是网页数据。
对于程序员或开发人员来说,拥有编程技能使得构建 Web 数据抓取程序变得非常容易和有趣。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。以下是一些使用 优采云采集器 抓取 Web 数据的解决方案:
1、从动态网页中提取内容
网页可以是静态的或动态的。通常,您要提取的网页内容会随着您访问 网站 的时间而改变。通常,这个 网站 是一个动态的网站,它使用 AJAX 技术或其他技术来使 Web 内容保持最新。AJAX 是一种延迟加载和异步更新的脚本技术。通过在后台与服务器交换少量数据,可以在不重新加载整个网页的情况下更新网页的某一部分。
性能特点是当点击网页中的某个选项时,网站的大部分URL不会改变;网页没有完全加载,而只是部分加载了数据,这些数据会发生变化。这时候可以在优采云的“高级选项”元素的“Ajax加载”中设置,就可以抓取Ajax加载的网页数据了。
优采云 中的 AJAX 设置
2、从网页中抓取隐藏的内容
你有没有想过从 网站 获取特定的数据,但是当你触发链接或鼠标悬停在某处时,内容就会出现?例如下图中的网站,需要将鼠标移到选中的彩票上,才能显示类别。对于此功能,您可以设置“鼠标悬停在此链接上”功能,以捕获网页中的隐藏内容。.
将鼠标移到链接上的 content采集 方法
3、从无限滚动的网页中提取内容
滚动到页面底部后,有些网站只有你要提取的一部分数据。例如,在今日头条首页,你需要一直滚动到页面底部才能加载更多的文章内容。无限滚动 网站 通常使用 AJAX 或 JavaScript 向 网站 内容请求附加内容。在这种情况下,您可以设置 AJAX 超时设置并选择滚动方式和滚动时间以从网页中提取内容。
4、 从网络上抓取所有链接
一个普通的网站会收录至少一个超链接,如果你想从一个网页中提取所有的链接,你可以使用优采云来获取网页上发布的所有超链接。
5、从网页中抓取所有文本
有时您需要提取 HTML 文档中的所有文本,即放置在 HTML 标记中,例如
标签或标签)。优采云使您能够提取网页源代码中的所有或特定文本。
6、从网上抓取所有图片
有的朋友有采集网页图片的需求。优采云可以下载网页中图片的URL采集,然后使用优采云专用图片批量下载工具下载我们采集@的图片URL中的图片> 到。下载并保存到本地计算机。 查看全部
htmlunit抓取动态网页(网络爬虫软件从指定网页获取特定内容的几种解决方案)
摘要:对于程序员或开发者来说,拥有编程能力可以让他们轻松、有趣地构建一个网络数据抓取程序。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。
网页数据抓取是指从网站中提取特定内容,而不需要请求网站的API接口来获取内容。“网页数据” 作为网站 用户体验的一部分,例如网页上的文本、图像、声音、视频和动画,它们都是网页数据。
对于程序员或开发人员来说,拥有编程技能使得构建 Web 数据抓取程序变得非常容易和有趣。但是对于大多数没有任何编程知识的人来说,最好使用一些网络爬虫软件从指定的网页中获取特定的内容。以下是一些使用 优采云采集器 抓取 Web 数据的解决方案:
1、从动态网页中提取内容
网页可以是静态的或动态的。通常,您要提取的网页内容会随着您访问 网站 的时间而改变。通常,这个 网站 是一个动态的网站,它使用 AJAX 技术或其他技术来使 Web 内容保持最新。AJAX 是一种延迟加载和异步更新的脚本技术。通过在后台与服务器交换少量数据,可以在不重新加载整个网页的情况下更新网页的某一部分。
性能特点是当点击网页中的某个选项时,网站的大部分URL不会改变;网页没有完全加载,而只是部分加载了数据,这些数据会发生变化。这时候可以在优采云的“高级选项”元素的“Ajax加载”中设置,就可以抓取Ajax加载的网页数据了。

优采云 中的 AJAX 设置
2、从网页中抓取隐藏的内容
你有没有想过从 网站 获取特定的数据,但是当你触发链接或鼠标悬停在某处时,内容就会出现?例如下图中的网站,需要将鼠标移到选中的彩票上,才能显示类别。对于此功能,您可以设置“鼠标悬停在此链接上”功能,以捕获网页中的隐藏内容。.

将鼠标移到链接上的 content采集 方法
3、从无限滚动的网页中提取内容
滚动到页面底部后,有些网站只有你要提取的一部分数据。例如,在今日头条首页,你需要一直滚动到页面底部才能加载更多的文章内容。无限滚动 网站 通常使用 AJAX 或 JavaScript 向 网站 内容请求附加内容。在这种情况下,您可以设置 AJAX 超时设置并选择滚动方式和滚动时间以从网页中提取内容。

4、 从网络上抓取所有链接
一个普通的网站会收录至少一个超链接,如果你想从一个网页中提取所有的链接,你可以使用优采云来获取网页上发布的所有超链接。
5、从网页中抓取所有文本
有时您需要提取 HTML 文档中的所有文本,即放置在 HTML 标记中,例如
标签或标签)。优采云使您能够提取网页源代码中的所有或特定文本。
6、从网上抓取所有图片
有的朋友有采集网页图片的需求。优采云可以下载网页中图片的URL采集,然后使用优采云专用图片批量下载工具下载我们采集@的图片URL中的图片> 到。下载并保存到本地计算机。
htmlunit抓取动态网页(网站静态页面和动态页面有什么区别,他们的优缺点汇总)
网站优化 • 优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2022-02-02 10:11
网站静态页面和动态页面有什么区别,它们的优缺点是什么?似乎很多 网站 用户对他们了解不多。在这里,我们重点介绍一下外贸网站建设的神灯资讯。总结一下各自的优缺点,仅供参考。
先说静态页面,它是真实存在的,不需要服务器编译,直接加载到客户端的浏览器中显示出来。静态页面需要占用一定的服务器空间,不能独立管理和发布更新的页面。如果要更新网页内容,必须通过FTP软件下载文件,并用网页制作软件进行修改(通过fso等技术除外)。网站的后缀为:htm、html、shtml、xml等常见的静态网页形式。
动态页面是指相对于静态网页的一种网页编程技术。虽然动态页面的页面代码不会改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。不要将动态网页与页面内容是否是动态的混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果没有直接关系。动态网页也可以是纯文本内容或收录各种动画内容。这些只是特定于网页。内容的呈现形式,无论网页是否具有动态效果,只要是通过动态网站技术生成的,都可以称为动态网页。
那么在了解了它们的定义之后,我们再来看看它们的优缺点。
1、静态页面加载速度快。加载静态页面时,无需搜索数据库。动态页面比较麻烦。网页接收到用户指令后,将指令带到数据库中,找到指令对应的数据,然后传递给服务器,通过服务器的编译,将动态页面编译成标准的HTML代码,传递给用户的浏览器,以便用户可以看到网页。结果,加载时间变长,用户不愿意再次访问您的页面。
2、静态页面的内容比较稳定,容易被搜索引擎搜索到收录,动态页面是用户输入指令后形成的页面,没有这样的页面,搜索引擎会只抓取现成的页面,不自行进入。虽然现在大部分搜索引擎都支持动态页面的爬取,但毕竟还不够完善。
3、静态网页没有数据库的支持,网站制作和维护的工作量比较大。因此,在网站信息量很大的情况下,很难完全依赖静态网页制作方式。动态网页一般基于数据库技术,可以大大减少网站维护的工作量。
4、静态网页交互性较差,功能有限。网站 使用动态网页技术可以实现更多功能,如用户注册、用户登录、在线调查、用户管理、订单管理等。
一般来说,网站构造的基础是静态网页,静态网页和动态网页并非互不兼容。为了提高网站中的搜索速度,使用了动态网页技术。网站,它还可以将网页内容转成静态网页运行,将网页转成静态是网站开发的一个很好的方法,可以提高网页打开速度. 查看全部
htmlunit抓取动态网页(网站静态页面和动态页面有什么区别,他们的优缺点汇总)
网站静态页面和动态页面有什么区别,它们的优缺点是什么?似乎很多 网站 用户对他们了解不多。在这里,我们重点介绍一下外贸网站建设的神灯资讯。总结一下各自的优缺点,仅供参考。
先说静态页面,它是真实存在的,不需要服务器编译,直接加载到客户端的浏览器中显示出来。静态页面需要占用一定的服务器空间,不能独立管理和发布更新的页面。如果要更新网页内容,必须通过FTP软件下载文件,并用网页制作软件进行修改(通过fso等技术除外)。网站的后缀为:htm、html、shtml、xml等常见的静态网页形式。
动态页面是指相对于静态网页的一种网页编程技术。虽然动态页面的页面代码不会改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。不要将动态网页与页面内容是否是动态的混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果没有直接关系。动态网页也可以是纯文本内容或收录各种动画内容。这些只是特定于网页。内容的呈现形式,无论网页是否具有动态效果,只要是通过动态网站技术生成的,都可以称为动态网页。
那么在了解了它们的定义之后,我们再来看看它们的优缺点。
1、静态页面加载速度快。加载静态页面时,无需搜索数据库。动态页面比较麻烦。网页接收到用户指令后,将指令带到数据库中,找到指令对应的数据,然后传递给服务器,通过服务器的编译,将动态页面编译成标准的HTML代码,传递给用户的浏览器,以便用户可以看到网页。结果,加载时间变长,用户不愿意再次访问您的页面。
2、静态页面的内容比较稳定,容易被搜索引擎搜索到收录,动态页面是用户输入指令后形成的页面,没有这样的页面,搜索引擎会只抓取现成的页面,不自行进入。虽然现在大部分搜索引擎都支持动态页面的爬取,但毕竟还不够完善。
3、静态网页没有数据库的支持,网站制作和维护的工作量比较大。因此,在网站信息量很大的情况下,很难完全依赖静态网页制作方式。动态网页一般基于数据库技术,可以大大减少网站维护的工作量。
4、静态网页交互性较差,功能有限。网站 使用动态网页技术可以实现更多功能,如用户注册、用户登录、在线调查、用户管理、订单管理等。
一般来说,网站构造的基础是静态网页,静态网页和动态网页并非互不兼容。为了提高网站中的搜索速度,使用了动态网页技术。网站,它还可以将网页内容转成静态网页运行,将网页转成静态是网站开发的一个很好的方法,可以提高网页打开速度.
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
网站优化 • 优采云 发表了文章 • 0 个评论 • 45 次浏览 • 2022-02-01 18:04
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,是指通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
所以将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而通过java代码实现页面的动态变化。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论! 查看全部
htmlunit抓取动态网页(Java爬取博客阅读文章最多)
更新,这很尴尬,这个文章博客是阅读最多的文章,但也是最被践踏的。
爬取思路:
所谓动态,是指通过请求后台,可以动态改变对应的html页面,开始时页面并不是全部显示出来的。
大多数操作都是通过请求完成的,一个请求,一个返回。在大多数网页中,请求往往被开发者隐藏在 js 代码中。
所以将爬取动态网页的思路转化为找到对应的js代码并执行对应的js代码,从而通过java代码实现页面的动态变化。
而当页面能够正确显示的时候,我们就可以像爬静态网页一样爬取数据了!
首先,可以使用htmlunit来模拟鼠标点击事件,很容易实现:
/**
* 通过htmlunit来获得一些搜狗的网址。
* 通过模拟鼠标点击事件来实现
* @param key
* @return
* @throws Exception
*/
public String getNextUrl(String key){
String page = new String();
try {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(false);
//去拿网页
HtmlPage htmlPage = webClient.getPage("http://pic.sogou.com/");
//得到表单
HtmlForm form = htmlPage.getFormByName("searchForm");
//得到提交按钮
HtmlSubmitInput button = form.getInputByValue("搜狗搜索");
//得到输入框
HtmlTextInput textField = form.getInputByName("query");
//输入内容
textField.setValueAttribute(key);
//点一下按钮
HtmlPage nextPage = button.click();
String str = nextPage.toString();
page = cutString(str);
webClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return page;
}
如上图,我只是通过java代码将关键字填入搜索我的,然后通过getInputByValue方法得到按钮控件,最后直接button.click(),
即可以模拟点击,将点击后返回的http请求解析成html页面。
这个功能其实很强大。比如你可以使用这个功能来模拟抢票,或者使用点击事件,加上搜索相关知识,将整个系统下线,并以html的形式保存。
接下来就是使用强大的htmlunit来执行js代码了。
先写一个简单的jsp页面:
Insert title here
原数字
function change(value) {
document.getElementById("test").innerHTML = value;
return "hello htmlUnit";
}
从上面可以看出,jsp页面很简单,只是一个函数变化,用来调用htmlUnit。
接下来是一个使用 htmlunit 的类。此类通过支持 JavaScript 解释器来工作,
然后将自己编写的JavaScript代码嵌入到页面中执行,获取执行后的返回结果并返回页面。
package com.blog.anla;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class TestMyOwnPage {
private void action() {
WebClient webClient = new WebClient();
try {
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true); // 设置支持JavaScript。
// 去拿网页
HtmlPage htmlPage = webClient
.getPage("http://localhost:8989/testHtmlScrop/index.jsp");
String s = "更改后的数字";
ScriptResult t = htmlPage.executeJavaScript("change(\"" + s
+ "\");", "injected script", 500);
// 这里是在500行插入这一小行JavaScript代码段,因为如果在默认的1行,那不会有结果
// 因为js是顺序执行的,当你执行第一行js代码时,可能还没有渲染body里面的标签。
HtmlPage myPage = (HtmlPage) t.getNewPage();
String nextPage = myPage.asXml().toString();
String nextPage2 = myPage.asText().toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
public static void main(String[] args) {
TestMyOwnPage tmop = new TestMyOwnPage();
tmop.action();
}
}
t.getNewPage()中有两个属性,一个是
javaScriptResult:执行这段代码后返回的结果,如果有(我上面写的,返回hello htmlunit),如果没有(返回Undefined)。
newPage_:执行此代码后返回的整个页面。
结果如下:
这段代码执行的最终结果如下:
asXml():将整个页面的html代码返回给我们:
而asText()只返回页面上可以显示的值,即head标签和label标签:
这种执行思路还可以动态执行相应的js代码,从而爬取需要的数据。
-------------------------------------------------- --------------------------------------2017 年 7 月更新---------- -------------------------------------- -------------------------------------------------- -----
这两天一直在做一个关于网络爬虫的系统
然而,当我开始攀爬时,我发现了一个问题。js的动态页面爬不下来。
网上找了很多方法,google也问了,主要是指htmlunit,下面是核心代码,
使用htmlunit的主要目的是模拟浏览器操作,因为有些链接点击无法直接通过src获取url,一般使用JavaScript。
简单拼接后的URL,所以用htmlunit直接模拟浏览器点击比较简单。
WebClient webClient = new WebClient();
webClient.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
webClient.getOptions().setCssEnabled(false); //禁用css支持
webClient.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
webClient.getOptions().setTimeout(20000);
HtmlPage page = wc.getPage("http://www.hao123.com");
//我认为这个最重要
String pageXml = page.asXml(); //以xml的形式获取响应文本
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml, "http://cq.qq.com");
这个时候,就可以得到jsoup中的document对象了,接下来就好写了,就像爬普通静态网页一样了。
不过,webclient解析是还是会出现一些问题,js的问题,
主要是由于目标url的js写的有些问题,但在实际的浏览器中却会忽略,eclipse中会报异常。
今天看,好多人踩了,可能我当时没认真写博客吧。如果想找java爬虫项目,可以去我的专栏
图片搜索包括使用jsoup爬取图片,以及lire索引和搜索图片。
玫瑰会在你的手中留下挥之不去的芬芳。有什么问题可以多多讨论!
htmlunit抓取动态网页( 所有无需环境下的浏览器开源项目,你知道几个?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 57 次浏览 • 2022-02-01 17:16
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个面向 .net 的网络自动化测试的开源项目。它为网页元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇 查看全部
htmlunit抓取动态网页(
所有无需环境下的浏览器开源项目,你知道几个?)
此表列出了几乎所有不需要 GUI 环境的浏览器开源项目,可用于自动化、测试或其他目的。
快来夸我吧!~
软件名称
介绍
支持的语言
Awesomium 基于 Chromium 无 GUI 浏览器引擎。C++、.NET
bev Benv 是由 node.js 开发的用于测试客户端代码的无界面浏览器测试环境。
爪哇
browser-launcher Browser-Launcher 可以检测系统上的所有浏览器版本,并在单独的配置文件中启动它们以进行自动化测试。爪哇
browser.rb 无接口 Ruby 浏览器。红宝石
Browserjet 无界面 webkit 浏览器,使用 node.js 接口。爪哇
BrowserKit 模拟浏览器行为。PHP
CasperJS CasperJS是一个开源的导航脚本和测试工具,基于PhantomJS用Java编写,用于测试Web应用功能,Phantom JS是一个服务器端Java API WebKit。它支持各种 Web 标准:DOM 操作、CSS 选择器、JSON、Canvas 和 SVG。爪哇
DalekJS DalekJS 是一个基于 Java(或 Node.js)的免费开源测试自动化接口。它能够同时在一组流行的浏览器(Chrome、IE、Firefox 和 WebKit)上运行测试。爪哇
Erik Erik 是一款基于WebKit 的无界面浏览器,可用于测试功能功能和使用Java 操作和访问网页。迅速
Geb Geb 是一个浏览器自动化测试解决方案。时髦的
ghost.py ghost.py 是一个 Python Webkit Web 客户端。Python
Ghostbuster Ghostbuster 是一个基于 phantomjs 的自动化浏览器测试工具,这意味着你可以获得一个模拟的浏览器、一个真实的 DOM 和一个模拟的测试环境。爪哇
grope Grope 是一个无 GUI 的浏览器环境,使用 WebKit 框架 + RubyCocoa。
红宝石
Guillotine Guillotine 是用 C# 开发的 .NET 无界面浏览器。。网
Headless Headless 是一款无界面浏览器,支持快速网络验收测试并使用.Net 环境。
。网
headless_browser Headless-Browser 是一个基于 WebKit 的无界面浏览器,用 C++ 开发。
C++
HeadlessBrowser HeadlessBrowser 是用于 DOM 测试的轻量级无 GUI 浏览器。
爪哇
HtmlUnit HtmlUnit 是一个“Java 程序无 GUI 浏览器”。爪哇
Jabba-Webkit Jabba-Webkit 是一个非图形化的 WebKit 浏览器,主要用于爬取 Ajax 网页。
Python
Jasmine-Headless-Webkit Jasmine-Headless-Webkit 是一个基于 jasmine 的非图形化 web 工具。
蟒蛇,Java,红宝石
Jaunt Java Web Scraping & Automation API Java
jBrowserDriver jBrowserDriver 是一个非图形浏览器,用纯 Java 编写,基于 WebKit,与 Selenium 兼容。
爪哇
jedi-crawler Jedi-Crawler 是一个轻量级的 Node/PhantomJS 爬虫,可以动态爬取网页内容。
爪哇
Lotte Lotte 是一个使用 phantomJs 的自动化图形浏览器测试工具。
爪哇
MechanicalSoup MechanicalSoup 是一个 Python 库,用于自动与 网站 交互。
Python
用于网页浏览的机械化状态编程。Python
Nightmare 高级浏览器自动化库,建立在 PhantomJS 之上。爪哇
PhantomJS Phantom JS 是用于 WebKit Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R(通过 Selenium)的服务器端 Java API
phantompy Phantompy 是建立在强大的 Qt5 Webkit API 之上的无头 WebKit 引擎。
Python
Python-Webkit Python-Webkit 是一个 Webkit python 扩展,提供对网页 DOM 的完全访问。Python
RoboBrowser RoboBrowser 是一个简单的 Pythonic 库,用于在不依赖单独浏览器的情况下浏览网页。
Python
Selenium 跨平台自动化 Web 浏览器。
Java、Python、Ruby、Java、C#、Haskell、Objective-C、Perl、PHP、R
SimpleBrowser SimpleBrowser 是一款灵活直观的浏览器引擎,专为自动化任务而设计,内置 .Net 4 框架。
。网
SlimerJS SlimerJS 是一款面向 Web 开发人员的浏览器,可以通过脚本以编程方式进行控制。爪哇
Splash Splash 是一个使用 Python 和 QT 开发的 HTTP API 轻量级浏览器。
任何
Splinter Splinter 是一个用于对用 Python 编写的 Web 应用程序进行验收测试的工具。Python
Spynner Spynner 是一个可编程的网络浏览器 Python 模块。支持 AJAX。
Python
SST SST (selenium-simple-test) 是一个 Web 测试框架,它使用 Python 生成基于浏览器的功能测试。Python
stanislaw Stanislaw 是一个 Python 无头浏览器测试工具。
Python
trifleJS 一个无头 IE 浏览器。它使用 .NET WebBrowser 类,具有 Java API,并在 V8 引擎上运行。
爪哇
twill Twill 是一种简单的语言,它允许用户通过命令行界面浏览网页。
Python
WatiN Watin 是一个面向 .net 的网络自动化测试的开源项目。它为网页元素提供了丰富的类库,使用起来非常简单。。网
Watir-WebDriver Watir 的实现基于 WebDriver 的 Ruby 绑定。
红宝石
WKZombie WKZombie 是 iOS/OSX 的 Swift 框架,用于在没有 UI 或 API 的情况下进行 网站 导航和数据采集,也称为无界面浏览器。迅速
Zombie.js 一个轻量级框架,用于在模拟环境中测试客户端 Java 代码。Zombie.js 使用 Node.js 实现了一个快速的无头全栈测试平台。爪哇