1.maven依赖

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhaowu</groupId>
<artifactId>pachong01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.2</version>
</dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency> <!-- https://mvnrepository.com/artifact/cn.edu.hfut.dmic.webcollector/WebCollector -->
<dependency>
<groupId>cn.edu.hfut.dmic.webcollector</groupId>
<artifactId>WebCollector</artifactId>
<version>2.71</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency> <!-- https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit -->
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.29</version>
</dependency> </dependencies>
</project>

2.建立项目

建立两个java文件。
第一部分,HtmlUnitforBD.java:主要实现摘取百度搜索的URL链接;
第二部分,transURLtoINFO.java:摘取链接的具体内容。

3.观察网页内容

观察网页源码:
3.1百度输入框参数:id=kw
 
3.2“百度一下”的按钮参数:id=su
 
3.3执行搜索“习大大”之后的网页源码,可以发现搜索的结果里面几乎都包含带有data-click属性的<div>标签,就是要把他们全提取出来,另外某些结果的属性是“mu”的,因为含这个属性的<div>标签比较少,本人没有做,有兴趣的可以试着改改。
 
3.4看其他页的代码,找规律获取所有页的地址
规律就是如图:,pn=1(第二页),pn=2(第三页)...,并且其他的部分是相同的,也就是是说,直接替换掉数字就可以定位到该页。

4.好,来代码!

(第一部分中有两处try catch中注释掉的代码,可以取消注释,这样能够查看从网页获取的文本内容。程序执行过程中存在找不到网页返回504等错误,很少碰见,如果出现,可以稍等一下,程序给出反馈后继续执行。
第一部分(获取链接的部分):
  1. package bdsearch;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.net.MalformedURLException;
  6. import java.net.URL;
  7. import java.util.ArrayList;
  8. import org.jsoup.Jsoup;
  9. import org.jsoup.nodes.Element;
  10. import org.jsoup.select.Elements;
  11. import com.gargoylesoftware.htmlunit.BrowserVersion;
  12. import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
  13. import com.gargoylesoftware.htmlunit.WebClient;
  14. import com.gargoylesoftware.htmlunit.html.HtmlInput;
  15. import com.gargoylesoftware.htmlunit.html.HtmlPage;
  16. ///////////////关于htmlunit的相关资料,在此站上有些资料,参考了一下:http://www.cnblogs.com/cation/p/3933408.html
  17. public class HtmlUnitforBD {
  18. private static int N = 3;// 搜索页数
  19. private static String keyW = "习大大";// 搜索词
  20. private static HtmlPage firstBaiduPage;// 保存第一页搜索结果
  21. private static String format = "";// Baidu对应每个搜索结果的第一页第二页第三页等等其中包含“&pn=1”,“&pn=2”,“&pn=3”等等,提取该链接并处理可以获取到一个模板,用于定位某页搜索结果
  22. private static ArrayList<String> eachurl = new ArrayList<String>();// 用于保存链接
  23. public static void main(String[] args) throws Exception {
  24. mainFunction(N, keyW);
  25. }
  26. public static void mainFunction(final int n, final String keyWord) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
  27. Thread thread = new Thread(new Runnable() {
  28. @Override
  29. public void run() {
  30. int x = n;// 页数
  31. System.out.println("要提取百度关于“" + keyWord + "”搜索结果的前" + x + "页");
  32. /*
  33. * 1.获取并输出第一页百度查询内容
  34. */
  35. Elements firstPageURL = null;
  36. try {
  37. firstPageURL = getFirstPage(keyWord);
  38. } catch (FailingHttpStatusCodeException | IOException e) {
  39. e.printStackTrace();
  40. }// 定义firstPageURL作为第一个搜索页的元素集
  41. for (Element newlink : firstPageURL) {
  42. String linkHref = newlink.attr("href");// 提取包含“href”的元素成分,JSoup实现内部具体过程
  43. String linkText = newlink.text();// 声明变量用于保存每个链接的摘要
  44. if (linkHref.length() > 14 & linkText.length() > 2) {// 去除某些无效链接
  45. System.out.println(linkHref + "\n\t\t摘要:" + linkText);// 输出链接和摘要
  46. eachurl.add(linkHref);// 作为存储手段存储在arrayList里面
  47. // try {
  48. // String temp = "";
  49. // try {
  50. // transURLtoINFO.trans(linkHref, temp);
  51. // } catch (IOException e) {
  52. // // TODO Auto-generated catch block
  53. // e.printStackTrace();
  54. // }
  55. // } catch (FailingHttpStatusCodeException e) {
  56. // e.printStackTrace();
  57. // }
  58. }
  59. }
  60. /*
  61. * 2.读取第二页及之后页面预处理
  62. */
  63. nextHref(firstBaiduPage);// 以firstBaiduPage作为参数,定义format,即网页格式。
  64. /*
  65. * 3.获取百度第一页之后的搜索结果
  66. */
  67. for (int i = 1; i < x; i++) {
  68. System.out.println("\n************百度搜索“" + keyW + "”第" + (i + 1) + "页结果************");
  69. String tempURL = format.replaceAll("&pn=1", "&pn=" + i + "");// 根据已知格式修改生成新的一页的链接
  70. System.out.println("该页地址为:" + format.replaceAll("&pn=1", "&pn=" + i + ""));// 显示该搜索模板
  71. HtmlUnitforBD h = new HtmlUnitforBD();
  72. String htmls = h.getPageSource(tempURL, "utf-8");// 不知为何此处直接用JSoup的相关代码摘取网页内容会出现问题,所以采用新的编码来实现摘取网页源码
  73. org.jsoup.nodes.Document doc = Jsoup.parse(htmls);// 网页信息转换为jsoup可识别的doc模式
  74. Elements links = doc.select("a[data-click]");// 摘取该页搜索链接
  75. for (Element newlink : links) {// 该处同上getFirstPage的相关实现
  76. String linkHref = newlink.attr("href");
  77. String linkText = newlink.text();
  78. if (linkHref.length() > 14 & linkText.length() > 2) {// 删除某些无效链接,查查看可发现有些无效链接是不包含信息文本的
  79. System.out.println(linkHref + "\n\t\t摘要:" + linkText);
  80. eachurl.add(linkHref);// 作为存储手段存储在arrayList里面
  81. // try {
  82. // String temp = "";
  83. // try {
  84. // transURLtoINFO.trans(linkHref, temp);
  85. // } catch (IOException e) {
  86. // // TODO Auto-generated catch block
  87. // e.printStackTrace();
  88. // }
  89. // } catch (FailingHttpStatusCodeException e) {
  90. // e.printStackTrace();
  91. // }
  92. }
  93. }
  94. }
  95. System.out.println("\n\n\n输出所有地址");
  96. for (String xx : eachurl) {
  97. System.out.println(xx);
  98. }
  99. return;
  100. }
  101. });
  102. thread.start();
  103. }
  104. /*
  105. * 获取百度搜索第一页内容
  106. */
  107. public static Elements getFirstPage(String w) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
  108. // 创建Web Client
  109. String word = w;
  110. WebClient webClient = new WebClient(BrowserVersion.CHROME);
  111. webClient.getOptions().setJavaScriptEnabled(false);// HtmlUnit对JavaScript的支持不好,关闭之
  112. webClient.getOptions().setCssEnabled(false);// HtmlUnit对CSS的支持不好,关闭之
  113. HtmlPage page = (HtmlPage) webClient.getPage("http://www.baidu.com/");// 百度搜索首页页面
  114. HtmlInput input = (HtmlInput) page.getHtmlElementById("kw");// 获取搜索输入框并提交搜索内容(查看源码获取元素名称)
  115. input.setValueAttribute(word);// 将搜索词模拟填进百度输入框(元素ID如上)
  116. HtmlInput btn = (HtmlInput) page.getHtmlElementById("su");// 获取搜索按钮并点击
  117. firstBaiduPage = btn.click();// 模拟搜索按钮事件
  118. String WebString = firstBaiduPage.asXml().toString();// 将获取到的百度搜索的第一页信息输出
  119. org.jsoup.nodes.Document doc = Jsoup.parse(WebString);// 转换为Jsoup识别的doc格式
  120. System.out.println("************百度搜索“" + word + "”第1页结果************");// 输出第一页结果
  121. Elements links = doc.select("a[data-click]");// 返回包含类似<a......data-click=" "......>等的元素,详查JsoupAPI
  122. return links;// 返回此类链接,即第一页的百度搜素链接
  123. }
  124. /*
  125. * 获取下一页地址
  126. */
  127. public static void nextHref(HtmlPage p) {
  128. // 输入:HtmlPage格式变量,第一页的网页内容;
  129. // 输出:format的模板
  130. WebClient webClient = new WebClient(BrowserVersion.CHROME);
  131. webClient.getOptions().setJavaScriptEnabled(false);
  132. webClient.getOptions().setCssEnabled(false);
  133. p = firstBaiduPage;
  134. String morelinks = p.getElementById("page").asXml();// 获取到百度第一页搜索的底端的页码的html代码
  135. org.jsoup.nodes.Document doc = Jsoup.parse(morelinks);// 转换为Jsoup识别的doc格式
  136. Elements links = doc.select("a[href]");// 提取这个html中的包含<a href=""....>的部分
  137. boolean getFormat = true;// 设置只取一次每页链接的模板格式
  138. for (Element newlink : links) {
  139. String linkHref = newlink.attr("href");// 将提取出来的<a>标签中的链接取出
  140. if (getFormat) {
  141. format = "http://www.baidu.com" + linkHref;// 补全模板格式
  142. getFormat = false;
  143. }
  144. }
  145. }
  146. public String getPageSource(String pageUrl, String encoding) {
  147. // 输入:url链接&编码格式
  148. // 输出:该网页内容
  149. StringBuffer sb = new StringBuffer();
  150. try {
  151. URL url = new URL(pageUrl);// 构建一URL对象
  152. BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), encoding));// 使用openStream得到一输入流并由此构造一个BufferedReader对象
  153. String line;
  154. while ((line = in.readLine()) != null) {
  155. sb.append(line);
  156. sb.append("\n");
  157. }
  158. in.close();
  159. } catch (Exception ex) {
  160. System.err.println(ex);
  161. }
  162. return sb.toString();
  163. }
  164. }
第二部分(提取可能有用的文本):
  1. package bdsearch;
  2. import java.io.BufferedReader;
  3. import java.io.ByteArrayInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.InputStreamReader;
  7. import java.net.ConnectException;
  8. import java.net.MalformedURLException;
  9. import java.util.ArrayList;
  10. import java.util.regex.Matcher;
  11. import java.util.regex.Pattern;
  12. import com.gargoylesoftware.htmlunit.BrowserVersion;
  13. import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
  14. import com.gargoylesoftware.htmlunit.WebClient;
  15. import com.gargoylesoftware.htmlunit.html.HtmlPage;
  16. public class transURLtoINFO {
  17. /*
  18. * 匹配消除html元素
  19. */
  20. // 定义script的正则表达式
  21. private static final String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>";
  22. // 定义style的正则表达式
  23. private static final String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>";
  24. // 定义HTML标签的正则表达式
  25. private static final String regEx_html = "<[^>]+>";
  26. // 定义空格回车换行符
  27. private static final String regEx_space = "\\s*|\t|\r|\n";
  28. public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
  29. String temp = null;
  30. trans("http://www.baidu.com/", temp);
  31. System.out.println("over");
  32. }
  33. public static String trans(String url, String info) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
  34. ArrayList<String> hrefList = new ArrayList<String>();
  35. WebClient webClient = new WebClient(BrowserVersion.CHROME);
  36. webClient.getOptions().setJavaScriptEnabled(false);
  37. webClient.getOptions().setCssEnabled(false);
  38. try {
  39. HtmlPage page = null;
  40. try {
  41. page = (HtmlPage) webClient.getPage(url);
  42. } catch (ConnectException e) {
  43. }
  44. InputStream temp = new ByteArrayInputStream(page.asText().getBytes());
  45. InputStreamReader isr = new InputStreamReader(temp);
  46. BufferedReader br = new BufferedReader(isr);
  47. String str = null, rs = null;
  48. while ((str = br.readLine()) != null) {
  49. rs = str;
  50. if (rs != null)
  51. hrefList.add(rs);
  52. }
  53. System.out.println("从该网址" + url + "查找的可能相关文本如下:");
  54. for (int i = 0; i < hrefList.size(); i++) {
  55. String string = hrefList.get(i);
  56. string = getTextFromHtml(string);
  57. if (string.length() >= 50) {
  58. info += "\n" + string;
  59. System.out.println(string);
  60. }
  61. }
  62. } catch (IOException e) {
  63. }
  64. return info;
  65. }
  66. /*
  67. * 从一行开始清除标签
  68. *
  69. * @return
  70. */
  71. public static String delHTMLTag(String htmlStr) {
  72. Pattern p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE);
  73. Matcher m_space = p_space.matcher(htmlStr);
  74. htmlStr = m_space.replaceAll(""); // 过滤空格回车标签
  75. Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
  76. Matcher m_script = p_script.matcher(htmlStr);
  77. htmlStr = m_script.replaceAll(""); // 过滤script标签
  78. Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
  79. Matcher m_style = p_style.matcher(htmlStr);
  80. htmlStr = m_style.replaceAll(""); // 过滤style标签
  81. Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
  82. Matcher m_html = p_html.matcher(htmlStr);
  83. htmlStr = m_html.replaceAll(""); // 过滤html标签
  84. return htmlStr.trim(); // 返回文本字符串
  85. }
  86. public static String getTextFromHtml(String htmlStr) {
  87. htmlStr = delHTMLTag(htmlStr);
  88. htmlStr = htmlStr.replaceAll(" ", "");
  89. return htmlStr;
  90. }
  91. }
 

运行结果:

 
同时可以输出了所有链接,有需要的可以用此方法专门搜集链接:
 
如果取消注释输出的文本如下:

采集baidu搜索信息的java源代码实现(大部分转发,少量自己修改)(使用了htmlunit和Jsoup)(转发:https://blog.csdn.net/zhaohang_1/article/details/44731039)的更多相关文章

  1. Java类和对象 详解(一)---写的很好通俗易懂---https://blog.csdn.net/wei_zhi/article/details/52745268

    https://blog.csdn.net/wei_zhi/article/details/52745268

  2. 转-java编译时error: illegal character '\ufeff' 的解决办法-https://blog.csdn.net/t518vs20s/article/details/80833061

    原文链接:https://blog.csdn.net/shixing_11/article/details/6976900 最近开发人员通过SVN提交了xxx.java文件,因发布时该包有问题需要回退 ...

  3. java之比较两个日期大小----https://blog.csdn.net/dongfangbaiyun/article/details/51225469

    https://blog.csdn.net/dongfangbaiyun/article/details/51225469 java之比较两个日期大小 最近又用到两个日期大小的比较,因此记录在此,方便 ...

  4. java 生成20位唯一ID,生成不会重复的20位数字----https://blog.csdn.net/weixin_36751895/article/details/70331781

    java 生成20位唯一ID,生成不会重复的20位数字----https://blog.csdn.net/weixin_36751895/article/details/70331781

  5. java定时器的使用(Timer)(转发:https://blog.csdn.net/ecjtuxuan/article/details/2093757)

    1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等. 对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. private java.util.Tim ...

  6. jeecms 强大的采集功能优化 转载 https://blog.csdn.net/jeff06143132/article/details/7099003

    ========================================================= 没办法附件上传不了,AcquisitionSvcImpl.java类: //---- ...

  7. 极大极小搜索思想+(α/β)减枝 【转自-----https://blog.csdn.net/hzk_cpp/article/details/79275772】

    极大极小搜索,即minimax搜索算法,专门用来做博弈论的问题的暴力. 多被称为对抗搜索算法. 这个搜索算法的基本思想就是分两层,一层是先手,记为a,还有一层是后手,记为b. 这个搜索是认为这a与b的 ...

  8. 转:Java面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101

    Java面试题集(51-70) Java程序员面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101 摘要:这一部分主要 ...

  9. maven 依赖文件 pom.xml 编译 mvn compile 运行 不用mvn exec:java -Dexec.mainClass="hello.HelloWorld" 打成jar包 mvn package mvn install http://blog.csdn.net/yaya1943/article/details/48464371

    使用maven编译Java项目 http://blog.csdn.net/yaya1943/article/details/48464371  使用"mvn clean"命令清除编 ...

随机推荐

  1. Java 调用 C/C++ 之 JNA 系列实战篇 —— 输出char * (六)

    一. 工作环境 1. windows (64位), JDK (64位),dll文件 (64位) 2. Linux (64位),      JDK (64位),so文件 (64位) 3. JNA的官方资 ...

  2. js 正则表达式 验证小数点后几位

    function IsFloatByBit (value, state, bit) {             if (state == false) {                 var re ...

  3. Effective C++:条款39:明智而审慎地使用private继承

    (一) (1)private继承意味着"依据某物实现出".仅仅有实现部分被继承.接口部分应略去: (2)它仅仅在软件"实现"层面上有意义,在软件"设计 ...

  4. Flex远程访问获取数据--HTTPService

    编写service类: package services { import com.adobe.serialization.json.JSON; import log.LogUtil; import ...

  5. kettle的job中使用循环

     job中使用循环 在一个不稳定的网络环境下作文件传输.偶尔会有超时或连接重置.这时须要稍等片刻再重试.在重试10次之后放弃并结束该job.类似使用循环解决这类问题.  该演示样例job演示了这样 ...

  6. 大数据(2) - Hadoop完全分布式的部署

    apache hadoop 官方文档 ** Hadoop介绍 ** HDFS:分布式存储文件 角色:NameNode和DataNode ** YARN:分布式资源调度框架(Hadoop2.x以上才引用 ...

  7. ThinkPHP 模板 Volist 标签嵌套循环输出多维数组

    ThinkPHP 中对 volist 标签嵌套使用可实现多维数组的输出. volist 嵌套使用 一般的二维数组,可以用 volist 标签直接循环输出.对于多维数组,则需要对其中的数组成员再次使用 ...

  8. Spring中HttpInvoker远程方法调用总结

    Spring为各种远程訪问技术的集成提供了工具类.Spring远程支持是由普通(Spring)POJO实现的,这使得开发具有远程訪问功能的服务变得相当easy. 眼下,Spring支持四种远程技术: ...

  9. js indexof用法indexOf()定义和用法

    indexOf()定义和用法 indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置. 语法 stringObject.indexOf(searchvalue,fromindex) ...

  10. python数据表的合并(python pandas join() 、merge()和concat()的用法)

    merage# pandas提供了一个类似于关系数据库的连接(join)操作的方法<Strong>merage</Strong>,可以根据一个或多个键将不同DataFrame中 ...