目标:动态网页爬取

说明:这里的动态网页指几种可能:1)需要用户交互,如常见的登录操作;2)网页通过JS /
AJAX动态生成,如一个html里有<div id="test"></div>,通过JS生成<div
id="test"><span>aaa</span></div>。

这里用了WebCollector 2进行爬虫,这东东也方便,不过要支持动态关键还是要靠另外一个API -- selenium 2(集成htmlunit 和 phantomjs).

1)需要登录后的爬取,如新浪微博

  1. import java.util.Set;
  2. import cn.edu.hfut.dmic.webcollector.crawler.DeepCrawler;
  3. import cn.edu.hfut.dmic.webcollector.model.Links;
  4. import cn.edu.hfut.dmic.webcollector.model.Page;
  5. import cn.edu.hfut.dmic.webcollector.net.HttpRequesterImpl;
  6. import org.openqa.selenium.Cookie;
  7. import org.openqa.selenium.WebElement;
  8. import org.openqa.selenium.htmlunit.HtmlUnitDriver;
  9. import org.jsoup.nodes.Element;
  10. import org.jsoup.select.Elements;
  11. /*
  12. * 登录后爬取
  13. * Refer: http://nutcher.org/topics/33
  14. * https://github.com/CrawlScript/WebCollector/blob/master/README.zh-cn.md
  15. * Lib required: webcollector-2.07-bin, selenium-java-2.44.0 & its lib
  16. */
  17. public class WebCollector1 extends DeepCrawler {
  18. public WebCollector1(String crawlPath) {
  19. super(crawlPath);
  20. /*获取新浪微博的cookie,账号密码以明文形式传输,请使用小号*/
  21. try {
  22. String cookie=WebCollector1.WeiboCN.getSinaCookie("yourAccount", "yourPwd");
  23. HttpRequesterImpl myRequester=(HttpRequesterImpl) this.getHttpRequester();
  24. myRequester.setCookie(cookie);
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. @Override
  30. public Links visitAndGetNextLinks(Page page) {
  31. /*抽取微博*/
  32. Elements weibos=page.getDoc().select("div.c");
  33. for(Element weibo:weibos){
  34. System.out.println(weibo.text());
  35. }
  36. /*如果要爬取评论,这里可以抽取评论页面的URL,返回*/
  37. return null;
  38. }
  39. public static void main(String[] args) {
  40. WebCollector1 crawler=new WebCollector1("/home/hu/data/weibo");
  41. crawler.setThreads(3);
  42. /*对某人微博前5页进行爬取*/
  43. for(int i=0;i<5;i++){
  44. crawler.addSeed("http://weibo.cn/zhouhongyi?vt=4&page="+i);
  45. }
  46. try {
  47. crawler.start(1);
  48. } catch (Exception e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. public static class WeiboCN {
  53. /**
  54. * 获取新浪微博的cookie,这个方法针对weibo.cn有效,对weibo.com无效
  55. * weibo.cn以明文形式传输数据,请使用小号
  56. * @param username 新浪微博用户名
  57. * @param password 新浪微博密码
  58. * @return
  59. * @throws Exception
  60. */
  61. public static String getSinaCookie(String username, String password) throws Exception{
  62. StringBuilder sb = new StringBuilder();
  63. HtmlUnitDriver driver = new HtmlUnitDriver();
  64. driver.setJavascriptEnabled(true);
  65. driver.get("http://login.weibo.cn/login/");
  66. WebElement mobile = driver.findElementByCssSelector("input[name=mobile]");
  67. mobile.sendKeys(username);
  68. WebElement pass = driver.findElementByCssSelector("input[name^=password]");
  69. pass.sendKeys(password);
  70. WebElement rem = driver.findElementByCssSelector("input[name=remember]");
  71. rem.click();
  72. WebElement submit = driver.findElementByCssSelector("input[name=submit]");
  73. submit.click();
  74. Set<Cookie> cookieSet = driver.manage().getCookies();
  75. driver.close();
  76. for (Cookie cookie : cookieSet) {
  77. sb.append(cookie.getName()+"="+cookie.getValue()+";");
  78. }
  79. String result=sb.toString();
  80. if(result.contains("gsid_CTandWM")){
  81. return result;
  82. }else{
  83. throw new Exception("weibo login failed");
  84. }
  85. }
  86. }
  87. }

* 这里有个自定义路径/home/hu/data/weibo(WebCollector1 crawler=new WebCollector1("/home/hu/data/weibo");),是用来保存到嵌入式数据库Berkeley DB。

* 总体上来自Webcollector 作者的sample。

2)JS动态生成HTML元素的爬取

  1. import java.util.List;
  2. import org.openqa.selenium.By;
  3. import org.openqa.selenium.WebDriver;
  4. import org.openqa.selenium.WebElement;
  5. import cn.edu.hfut.dmic.webcollector.crawler.DeepCrawler;
  6. import cn.edu.hfut.dmic.webcollector.model.Links;
  7. import cn.edu.hfut.dmic.webcollector.model.Page;
  8. /*
  9. * JS爬取
  10. * Refer: http://blog.csdn.net/smilings/article/details/7395509
  11. */
  12. public class WebCollector3 extends DeepCrawler {
  13. public WebCollector3(String crawlPath) {
  14. super(crawlPath);
  15. // TODO Auto-generated constructor stub
  16. }
  17. @Override
  18. public Links visitAndGetNextLinks(Page page) {
  19. /*HtmlUnitDriver可以抽取JS生成的数据*/
  20. //      HtmlUnitDriver driver=PageUtils.getDriver(page,BrowserVersion.CHROME);
  21. //      String content = PageUtils.getPhantomJSDriver(page);
  22. WebDriver driver = PageUtils.getWebDriver(page);
  23. //        List<WebElement> divInfos=driver.findElementsByCssSelector("#feed_content");
  24. List<WebElement> divInfos=driver.findElements(By.cssSelector("#feed_content span"));
  25. for(WebElement divInfo:divInfos){
  26. System.out.println("Text是:" + divInfo.getText());
  27. }
  28. return null;
  29. }
  30. public static void main(String[] args) {
  31. WebCollector3 crawler=new WebCollector3("/home/hu/data/wb");
  32. for(int page=1;page<=5;page++)
  33. //        crawler.addSeed("http://www.sogou.com/web?query="+URLEncoder.encode("编程")+"&page="+page);
  34. crawler.addSeed("http://cq.qq.com/baoliao/detail.htm?294064");
  35. try {
  36. crawler.start(1);
  37. } catch (Exception e) {
  38. e.printStackTrace();
  39. }
  40. }
  41. }

PageUtils.java

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.InputStreamReader;
  5. import org.openqa.selenium.JavascriptExecutor;
  6. import org.openqa.selenium.WebDriver;
  7. import org.openqa.selenium.chrome.ChromeDriver;
  8. import org.openqa.selenium.htmlunit.HtmlUnitDriver;
  9. import org.openqa.selenium.ie.InternetExplorerDriver;
  10. import org.openqa.selenium.phantomjs.PhantomJSDriver;
  11. import com.gargoylesoftware.htmlunit.BrowserVersion;
  12. import cn.edu.hfut.dmic.webcollector.model.Page;
  13. public class PageUtils {
  14. public static HtmlUnitDriver getDriver(Page page) {
  15. HtmlUnitDriver driver = new HtmlUnitDriver();
  16. driver.setJavascriptEnabled(true);
  17. driver.get(page.getUrl());
  18. return driver;
  19. }
  20. public static HtmlUnitDriver getDriver(Page page, BrowserVersion browserVersion) {
  21. HtmlUnitDriver driver = new HtmlUnitDriver(browserVersion);
  22. driver.setJavascriptEnabled(true);
  23. driver.get(page.getUrl());
  24. return driver;
  25. }
  26. public static WebDriver getWebDriver(Page page) {
  27. //      WebDriver driver = new HtmlUnitDriver(true);
  28. //      System.setProperty("webdriver.chrome.driver", "D:\\Installs\\Develop\\crawling\\chromedriver.exe");
  29. //      WebDriver driver = new ChromeDriver();
  30. System.setProperty("phantomjs.binary.path", "D:\\Installs\\Develop\\crawling\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe");
  31. WebDriver driver = new PhantomJSDriver();
  32. driver.get(page.getUrl());
  33. //      JavascriptExecutor js = (JavascriptExecutor) driver;
  34. //      js.executeScript("function(){}");
  35. return driver;
  36. }
  37. public static String getPhantomJSDriver(Page page) {
  38. Runtime rt = Runtime.getRuntime();
  39. Process process = null;
  40. try {
  41. process = rt.exec("D:\\Installs\\Develop\\crawling\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe " +
  42. "D:\\workspace\\crawlTest1\\src\\crawlTest1\\parser.js " +
  43. page.getUrl().trim());
  44. InputStream in = process.getInputStream();
  45. InputStreamReader reader = new InputStreamReader(
  46. in, "UTF-8");
  47. BufferedReader br = new BufferedReader(reader);
  48. StringBuffer sbf = new StringBuffer();
  49. String tmp = "";
  50. while((tmp = br.readLine())!=null){
  51. sbf.append(tmp);
  52. }
  53. return sbf.toString();
  54. } catch (IOException e) {
  55. e.printStackTrace();
  56. }
  57. return null;
  58. }
  59. }

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代码如下:

  1. system = require('system')
  2. address = system.args[1];//获得命令行第二个参数 接下来会用到
  3. //console.log('Loading a web page');
  4. var page = require('webpage').create();
  5. var url = address;
  6. //console.log(url);
  7. page.open(url, function (status) {
  8. //Page is loaded!
  9. if (status !== 'success') {
  10. console.log('Unable to post!');
  11. } else {
  12. //此处的打印,是将结果一流的形式output到java中,java通过InputStream可以获取该输出内容
  13. console.log(page.content);
  14. }
  15. phantom.exit();
  16. });

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)的更多相关文章

  1. Node.js 动态网页爬取 PhantomJS 使用入门(转)

    Node.js 动态网页爬取 PhantomJS 使用入门 原创NeverSettle101 发布于2017-03-24 09:34:45 阅读数 8309  收藏 展开 版权声明:本文为 winte ...

  2. python动态网页爬取——四六级成绩批量爬取

    需求: 四六级成绩查询网站我所知道的有两个:学信网(http://www.chsi.com.cn/cet/)和99宿舍(http://cet.99sushe.com/),这两个网站采用的都是动态网页. ...

  3. 爬虫入门(三)——动态网页爬取:爬取pexel上的图片

    Pexel上有大量精美的图片,没事总想看看有什么好看的自己保存到电脑里可能会很有用 但是一个一个保存当然太麻烦了 所以不如我们写个爬虫吧(๑•̀ㅂ•́)و✧ 一开始学习爬虫的时候希望爬取pexel上的 ...

  4. 动态网页爬取样例(WebCollector+selenium+phantomjs)

    目标:动态网页爬取 说明:这里的动态网页指几种可能:1)须要用户交互,如常见的登录操作:2)网页通过JS / AJAX动态生成.如一个html里有<div id="test" ...

  5. Python开发爬虫之动态网页抓取篇:爬取博客评论数据——通过Selenium模拟浏览器抓取

    区别于上篇动态网页抓取,这里介绍另一种方法,即使用浏览器渲染引擎.直接用浏览器在显示网页时解析 HTML.应用 CSS 样式并执行 JavaScript 的语句. 这个方法在爬虫过程中会打开一个浏览器 ...

  6. 【图文详解】scrapy爬虫与动态页面——爬取拉勾网职位信息(2)

    上次挖了一个坑,今天终于填上了,还记得之前我们做的拉勾爬虫吗?那时我们实现了一页的爬取,今天让我们再接再厉,实现多页爬取,顺便实现职位和公司的关键词搜索功能. 之前的内容就不再介绍了,不熟悉的请一定要 ...

  7. 爬虫系列5:scrapy动态页面爬取的另一种思路

    前面有篇文章给出了爬取动态页面的一种思路,即应用Selenium+Firefox(参考<scrapy动态页面爬取>).但是selenium需要运行本地浏览器,比较耗时,不太适合大规模网页抓 ...

  8. python网络爬虫-动态网页抓取(五)

    动态抓取的实例 在开始爬虫之前,我们需要了解一下Ajax(异步请求).它的价值在于在与后台进行少量的数据交换就可以使网页实现异步更新. 如果使用Ajax加载的动态网页抓取,有两种方法: 通过浏览器审查 ...

  9. 使用urllib进行网页爬取

    # coding=gbk # 抓取开奖号码 # url:http://datachart.500.com/dlt/zoushi/jbzs_foreback.shtml ''' 对网页逐行迭代,找到目标 ...

随机推荐

  1. 【转】Nginx+Tomcat搭建高性能负载均衡集群

    最近对负载均衡比较感兴趣,研究了公司的负载均衡的配置,用的是阿里的SLB,相当于不用运维,只需要在后台进行简单的配置就能完成Tomcat的负载均衡,索性在网上找了几篇文章去尝试搭建一个集群,然而很多都 ...

  2. spring注解开发中常用注解以及简单配置

    一.spring注解开发中常用注解以及简单配置 1.为什么要用注解开发:spring的核心是Ioc容器和Aop,对于传统的Ioc编程来说我们需要在spring的配置文件中邪大量的bean来向sprin ...

  3. 基础算法-查找:线性索引查找(I)

    前面介绍的几种查找的算法都是基于数据有序的基础上进行的.但是在实际的应用中,很多数据集可能有惊人的数据量,面对这些海量的数据,要保证记录全部按照当中的某个关键字有序,其时间代价是非常昂贵的,所以这种数 ...

  4. kinect for windows - DepthBasics-D2D详解之一

    Depth在kinect中经常被翻译为深度图,指的是图像到摄像头的距离,这些距离数据能让机器知道物理距离有多远.kinect通过两个红外摄像头来实现这个功能的.在这个例子里,就实现了深度图的提取和现实 ...

  5. django在视图中使用模板

    在视图中使用模板   在学习了模板系统的基础之后,现在让我们使用相关知识来创建视图. 重新打开我们在前一章在 mysite.views 中创建的 current_datetime 视图. 以下是其内容 ...

  6. android 时间滚动控件 底部弹出

    下载地址:http://download.csdn.net/detail/ldd119/7440895 转载请说明出处 先上个效果图 watermark/2/text/aHR0cDovL2Jsb2cu ...

  7. Android Texting(2)Testing Fundamentals 测试基础篇

    Testing Fundamentals The Android testing framework, an integral part of the development environment, ...

  8. 如何成为CSDN博客专家

    先看一下官方给出的要求: 申请CSDN博客专家应具备的条件: 1.原创IT类文章总数超过20篇,并且最近一个月内发布了新的原创IT类文章. 2.博客文章总的浏览量超过5万次以上. 3.文章内容的质量很 ...

  9. ceph之crush map

    编辑crush map: 1.获取crush map: 2.反编译crush map: 3.至少编辑一个设备,桶, 规则: 4.重新编译crush map: 5.重新注入crush map: 获取cr ...

  10. haml、sass简单的解释

    1. Haml 全名为 HTML Abstract Markup Language,主要就是让开发者能够使用缩排的方式撰写 HTML,做到永不忘记关 Tag 的效果. 例如:%h1= "He ...