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

Posted sutao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了采集baidu搜索信息的java源代码实现(大部分转发,少量自己修改)(使用了htmlunit和Jsoup)(转发:https://blog.csdn.net/zhaohang_1/article/d相关的知识,希望对你有一定的参考价值。

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


第二部分(提取可能有用的文本):
  1. package bdsearch;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.ByteArrayInputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.io.InputStreamReader;  
  8. import java.net.ConnectException;  
  9. import java.net.MalformedURLException;  
  10. import java.util.ArrayList;  
  11. import java.util.regex.Matcher;  
  12. import java.util.regex.Pattern;  
  13.   
  14. import com.gargoylesoftware.htmlunit.BrowserVersion;  
  15. import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;  
  16. import com.gargoylesoftware.htmlunit.WebClient;  
  17. import com.gargoylesoftware.htmlunit.html.HtmlPage;  
  18.   
  19. public class transURLtoINFO {  
  20.     /* 
  21.      * 匹配消除html元素 
  22.      */  
  23.     // 定义script的正则表达式  
  24.     private static final String regEx_script = "<script[^>]*?>[\\\\s\\\\S]*?<\\\\/script>";  
  25.     // 定义style的正则表达式  
  26.     private static final String regEx_style = "<style[^>]*?>[\\\\s\\\\S]*?<\\\\/style>";  
  27.     // 定义HTML标签的正则表达式  
  28.     private static final String regEx_html = "<[^>]+>";  
  29.     // 定义空格回车换行符  
  30.     private static final String regEx_space = "\\\\s*|\\t|\\r|\\n";  
  31.   
  32.     public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {  
  33.         String temp = null;  
  34.         trans("http://www.baidu.com/", temp);  
  35.         System.out.println("over");  
  36.     }  
  37.   
  38.     public static String trans(String url, String info) throws FailingHttpStatusCodeException, MalformedURLException, IOException {  
  39.   
  40.         ArrayList<String> hrefList = new ArrayList<String>();  
  41.         WebClient webClient = new WebClient(BrowserVersion.CHROME);  
  42.         webClient.getOptions().setJavaScriptEnabled(false);  
  43.         webClient.getOptions().setCssEnabled(false);  
  44.         try {  
  45.             HtmlPage page = null;  
  46.             try {  
  47.                 page = (HtmlPage) webClient.getPage(url);  
  48.             } catch (ConnectException e) {  
  49.             }  
  50.             InputStream temp = new ByteArrayInputStream(page.asText().getBytes());  
  51.             InputStreamReader isr = new InputStreamReader(temp);  
  52.             BufferedReader br = new BufferedReader(isr);  
  53.             String str = null, rs = null;  
  54.             while ((str = br.readLine()) != null) {  
  55.                 rs = str;  
  56.                 if (rs != null)  
  57.                     hrefList.add(rs);  
  58.             }  
  59.             System.out.println("从该网址" + url + "查找的可能相关文本如下:");  
  60.             for (int i = 0; i < hrefList.size(); i++) {  
  61.                 String string = hrefList.get(i);  
  62.                 string = getTextFromHtml(string);  
  63.                 if (string.length() >= 50) {  
  64.                     info += "\\n" + string;  
  65.                     System.out.println(string);  
  66.                 }  
  67.             }  
  68.         } catch (IOException e) {  
  69.         }  
  70.         return info;  
  71.     }  
  72.   
  73.     /* 
  74.      * 从一行开始清除标签 
  75.      *  
  76.      * @return 
  77.      */  
  78.     public static String delHTMLTag(String htmlStr) {  
  79.   
  80.         Pattern p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE);  
  81.         Matcher m_space = p_space.matcher(htmlStr);  
  82.         htmlStr = m_space.replaceAll(""); // 过滤空格回车标签  
  83.   
  84.         Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);  
  85.         Matcher m_script = p_script.matcher(htmlStr);  
  86.         htmlStr = m_script.replaceAll(""); // 过滤script标签  
  87.   
  88.         Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);  
  89.         Matcher m_style = p_style.matcher(htmlStr);  
  90.         htmlStr = m_style.replaceAll(""); // 过滤style标签  
  91.   
  92.         Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);  
  93.         Matcher m_html = p_html.matcher(htmlStr);  
  94.         htmlStr = m_html.replaceAll(""); // 过滤html标签  
  95.   
  96.         return htmlStr.trim(); // 返回文本字符串  
  97.     }  
  98.   
  99.     public static String getTextFromHtml(String htmlStr) {  
  100.         htmlStr = delHTMLTag(htmlStr);  
  101.         htmlStr = htmlStr.replaceAll(" ", "");  
  102.         return htmlStr;  
  103.     }  
  104. }  


 
运行结果:
技术分享图片
 
同时可以输出了所有链接,有需要的可以用此方法专门搜集链接:
技术分享图片
 
如果取消注释输出的文本如下:
技术分享图片








以上是关于采集baidu搜索信息的java源代码实现(大部分转发,少量自己修改)(使用了htmlunit和Jsoup)(转发:https://blog.csdn.net/zhaohang_1/article/d的主要内容,如果未能解决你的问题,请参考以下文章

爬虫基础

Luence——代码实现索引及搜索

python学习之爬虫理论总结

通用爬虫和聚焦爬虫的概念

webmagic

Lucene架构