2)JS动态生成HTML元素的爬取
2)JS动态生成HTML元素的爬取
import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import cn.edu.hfut.dmic.webcollector.crawler.DeepCrawler; import cn.edu.hfut.dmic.webcollector.model.Links; import cn.edu.hfut.dmic.webcollector.model.Page; /* * JS爬取 * Refer: http://blog.csdn.net/smilings/article/details/7395509 */ public class WebCollector3 extends DeepCrawler { public WebCollector3(String crawlPath) { super(crawlPath); // TODO Auto-generated constructor stub } @Override public Links visitAndGetNextLinks(Page page) { /*HtmlUnitDriver可以抽取JS生成的数据*/ // HtmlUnitDriver driver=PageUtils.getDriver(page,BrowserVersion.CHROME); // String content = PageUtils.getPhantomJSDriver(page); WebDriver driver = PageUtils.getWebDriver(page); // List<WebElement> divInfos=driver.findElementsByCssSelector("#feed_content"); List<WebElement> divInfos=driver.findElements(By.cssSelector("#feed_content span")); for(WebElement divInfo:divInfos){ System.out.println("Text是:" + divInfo.getText()); } return null; } public static void main(String[] args) { WebCollector3 crawler=new WebCollector3("/home/hu/data/wb"); for(int page=1;page<=5;page++) // crawler.addSeed("http://www.sogou.com/web?query="+URLEncoder.encode("编程")+"&page="+page); crawler.addSeed("http://cq.qq.com/baoliao/detail.htm?294064"); try { crawler.start(1); } catch (Exception e) { e.printStackTrace(); } } }
PageUtils.java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.phantomjs.PhantomJSDriver; import com.gargoylesoftware.htmlunit.BrowserVersion; import cn.edu.hfut.dmic.webcollector.model.Page; public class PageUtils { public static HtmlUnitDriver getDriver(Page page) { HtmlUnitDriver driver = new HtmlUnitDriver(); driver.setJavascriptEnabled(true); driver.get(page.getUrl()); return driver; } public static HtmlUnitDriver getDriver(Page page, BrowserVersion browserVersion) { HtmlUnitDriver driver = new HtmlUnitDriver(browserVersion); driver.setJavascriptEnabled(true); driver.get(page.getUrl()); return driver; } public static WebDriver getWebDriver(Page page) { // WebDriver driver = new HtmlUnitDriver(true); // System.setProperty("webdriver.chrome.driver", "D:\\Installs\\Develop\\crawling\\chromedriver.exe"); // WebDriver driver = new ChromeDriver(); System.setProperty("phantomjs.binary.path", "D:\\Installs\\Develop\\crawling\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe"); WebDriver driver = new PhantomJSDriver(); driver.get(page.getUrl()); // JavascriptExecutor js = (JavascriptExecutor) driver; // js.executeScript("function(){}"); return driver; } public static String getPhantomJSDriver(Page page) { Runtime rt = Runtime.getRuntime(); Process process = null; try { process = rt.exec("D:\\Installs\\Develop\\crawling\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe " + "D:\\workspace\\crawlTest1\\src\\crawlTest1\\parser.js " + page.getUrl().trim()); InputStream in = process.getInputStream(); InputStreamReader reader = new InputStreamReader( in, "UTF-8"); BufferedReader br = new BufferedReader(reader); StringBuffer sbf = new StringBuffer(); String tmp = ""; while((tmp = br.readLine())!=null){ sbf.append(tmp); } return sbf.toString(); } catch (IOException e) { e.printStackTrace(); } return null; } }
2.1)HtmlUnitDriver getDriver是selenium 1.x的作法,已经outdate了,现在用WebDriver getWebDriver
2.2)这里用了几种方法:HtmlUnitDriver, ChromeDriver, PhantomJSDriver,
PhantomJS,参考 http://blog.csdn.net/five3/article/details/19085303,各自之间的优缺
点如下:
| driver类型 | 优点 | 缺点 | 应用 |
| 真实浏览器driver | 真实模拟用户行为 | 效率、稳定性低 | 兼容性测试 |
| HtmlUnit | 速度快 | js引擎不是主流的浏览器支持的 | 包含少量js的页面测试 |
| PhantomJS | 速度中等、模拟行为接近真实 | 不能模拟不同/特定浏览器的行为 | 非GUI的功能性测试 |
* 真实浏览器driver 包括 Firefox, Chrome, IE
2.3)用PhantomJSDriver的时候,遇上错
误:ClassNotFoundException: org.openqa.selenium.browserlaunchers.Proxies,原
因竟然是selenium 2.44 的bug,后来通过maven找到phantomjsdriver-1.2.1.jar 才解决了。
2.4)另外,我还试了PhantomJS 原生调用(也就是不用selenium,直接调用PhantomJS,见上面的方法),原生要调用JS,这里的parser.js代码如下:
system = require('system')
address = system.args[1];//获得命令行第二个参数 接下来会用到
//console.log('Loading a web page');
var page = require('webpage').create();
var url = address;
//console.log(url);
page.open(url, function (status) {
//Page is loaded!
if (status !== 'success') {
console.log('Unable to post!');
} else {
//此处的打印,是将结果一流的形式output到java中,java通过InputStream可以获取该输出内容
console.log(page.content);
}
phantom.exit();
});
3)后话
3.1)HtmlUnitDriver + PhantomJSDriver是当前最可靠的动态抓取方案。
3.2)这过程中用到很多包、exe,遇到很多的墙~,有需要的朋友可以找我要。
Reference
http://www.ibm.com/developerworks/cn/web/1309_fengyq_seleniumvswebdriver/
http://blog.csdn.net/smilings/article/details/7395509
http://phantomjs.org/download.html
http://blog.csdn.net/five3/article/details/19085303
http://phantomjs.org/quick-start.html
... ...
动态网页爬取例子(WebCollector+selenium+phantomjs)
2)JS动态生成HTML元素的爬取的更多相关文章
- JS动态生成的元素,其对应的方法不响应(比如单击事件,鼠标移动事件等)
主要原因:在页面给元素注册点击事件的时候[ $(function () { XXX }); ],JS动态生成的元素还尚未生成,所以click事件就没有生效 解决方法: 方案一:js动态生成元素后再给 ...
- Javascript动态生成的页面信息爬取和openpyxl包FAQ小记
最近,笔者在使用Requests模拟浏览器发送Post请求时,发现程序返回的html与浏览器F12观察到的略有不同,经过观察返回的response.text,cookies确认有效,因为我们可以看到返 ...
- 抓取Js动态生成数据且以滚动页面方式分页的网页
代码也可以从我的开源项目HtmlExtractor中获取. 当我们在进行数据抓取的时候,如果目标网站是以Js的方式动态生成数据且以滚动页面的方式进行分页,那么我们该如何抓取呢? 如类似今日头条这样的网 ...
- js 动态生成html 触发事件传参字符转义
通常,在使用 JS 动态生成 html 的过程中,会嵌入相应的样式.事件等属性元素,而这时经常会出现所谓的 “单.双引号不够用” 的情况,别急,这时可以利用 html 语言中的转义字符来解决.下面就来 ...
- 爬虫案例(js动态生成数据)
需求:爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/018d244441062d8916dd472a4c6a0a0b.html页面中的 ...
- 动态生成html元素并为元素追加属性
动态生成HTML元素的方法有三种: 第一种:document.createElement()创建元素,再用appendChild( )方法将元素添加到指定节点 <!DOCTYPE html> ...
- 抓取js动态生成的数据分析案例
需求:爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/018d244441062d8916dd472a4c6a0a0b.html页面中的 ...
- Angular如何给动态生成的元素绑定事件
在AngularJS中,操作DOM一般在指令中完成,事件监听机制是在对于已经静态生成的dom绑定事件,而如果在指令中动态生成了DOM节点,动态生成的节点不会被JS事件监听. 举例来说: angular ...
- js动态生成canvas
最近看代码发现一个小现象,就是用js动态生成的canvas在浏览器审查元素的时候,发现它没有结束标签,但是不会影响canvas上图形的绘制,同时还有一点就是在动态设置canvas宽度和高度的时候,不要 ...
随机推荐
- inode结构体成员详解
概述:inode译成中文就是索引节点,它用来存放档案及目录的基本信息,包含时间.档名.使用者及群组等.inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS ino ...
- poj1860 解题报告
题意:这里有N种货币,分别记为1~N,有M种货币交换的方式,每一种方式有A,B两种钱币,有RAB, CAB, RBA and CBA,四个数,表示交换率, Nick手上有其中的一种货币S,货币S的钱数 ...
- ORA-00942:表或视图不存在(低级错误)
在好多时候.调试PL/SQL对象时会报.ORA-00942 看看错误原因吧: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFjc29uX2JhaQ== ...
- boost::asio设置同步连接超时
boost::asio设置同步连接超时 CSDN上求助无果,只好用自创的非主流方法了.asio自带的例子里是用deadline_timer的async_wait方法来实现超时的,这种方法需要单独写 ...
- TCP/IP笔记 二.网络层(2)——ICMP,RIP,OSPF,BGP
1. ICMP ICMP (Internet Control Message Protocol) 作用:提高 IP 数据报交付成功的机会. 1.1 特点 ICMP 允许主机或路由器报告差错情况和提供有 ...
- autotools入门笔记(一)
GNU autotools作用:收集系统配置信息并自动生成Makefile文件. GNU autotools主要包括三个工具:autoconf.automake.libtool,还有很多辅助的工具,包 ...
- 静态书架和js模拟翻书效果
书籍图片随便找了个,有点难看,须要的自己替换个好看点的png格式图片 源代码下载:http://download.csdn.net/detail/sweetsuzyhyf/7604091
- C语言深度解剖读书笔记(6.函数的核心)
对于本节的函数内容其实就没什么难点了,但是对于函数这节又涉及到了顺序点的问题,我觉得可以还是忽略吧. 本节知识点: 1.函数中的顺序点:f(k,k++); 这样的问题大多跟编译器有关,不要去刻意追求 ...
- MP3文件的结构与编程
有一个朋友喜欢听MP3,为了获取MP3,写了一个程序,专门从一家音乐网站上搜索下载mp3,一下子下载了有上千首.这时朋友又犯愁了,这些MP3的歌曲名字都是使用1,2,3,4,..等数字命名,挑选起来十 ...
- csdn的登录框好难看
不好意思说实话了,新的登陆框样式挺难看的,那种橙不明朗,介于黄和橙之间,跟整个网站主色调红和黑很不搭.不过,倒是有点跟风Win8平实的style,但是比Win8更简陋了点. tooltip要不加都不加 ...