爬蟲任務二:爬取(用到htmlunit和jsoup)通過百度搜索引擎關鍵字搜取到的新聞標題和url,並保存在本地文件中(主體借鑒了網上的資料)
阿新 • • 發佈:2018-05-09
標題 code rgs aps snap one reader url 預處理
采用maven工程,免著到處找依賴jar包
<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>
直接上代碼RenWu.class:
package com.zhaowu.renwu2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlInput; import com.gargoylesoftware.htmlunit.html.HtmlPage; public class RenWu { // 搜索頁數 private static int N = 6; // 搜索關鍵詞 private static String keyWord = "爬蟲"; // 第一頁搜索結果 private static HtmlPage firstBaiduPage; // Baidu對應每個搜索結果的第一頁第二頁第三頁等等其中包含“&pn=1”,“&pn=2”,“&pn=3”等等, // 提取該鏈接並處理可以獲取到一個模板,用於定位某頁搜索結果 private static String template = ""; public static void main(String[] args) { goSearch(N, keyWord); } private static void goSearch(final int n, final String keyWord) { Thread thread = new Thread(new Runnable() { public void run() { // 頁數 int x = n; System.out.println("爬取百度關於關鍵字“" + keyWord + "”搜索結果的前" + x + "頁"); FileUtil.toFile("爬取百度關於關鍵字“" + keyWord + "”搜索結果的前" + x + "頁\n"); //1.獲取並輸出第一頁百度查詢內容 Elements firstElementsLink = null; try { firstElementsLink = getFirstPage(keyWord); } catch (Exception e) { e.printStackTrace(); } for (Element link : firstElementsLink) { // 鏈接url String linkHref = link.attr("href"); // 鏈接標題 String linkText = link.text(); if(linkHref.length() > 13 & linkText.length() > 4) { String content = "鏈接url: " + linkHref + "\n\t鏈接標題: " + linkText + "\n"; System.out.println(content); FileUtil.toFile(content); } } //2.讀取第二頁及之後頁面預處理 // 以firstBaiduPage作為參數,定義template,即網頁格式。 nextHref(firstBaiduPage); //3.獲取百度第一頁之後的搜索結果 for(int i = 1; i< x; i++) { System.out.println("\n---------百度搜索關鍵字“" + keyWord + "”第" + (i + 1) + "頁結果------"); FileUtil.toFile("\n---------百度搜索關鍵字“" + keyWord + "”第" + (i + 1) + "頁結果------" + "\n"); // 根據已知格式修改生成新的一頁的鏈接 String tempURL = template.replaceAll("&pn=1", "&pn=" + i + ""); // 顯示該搜索模板 System.out.println("\t該頁地址為:" + tempURL); RenWu renWu = new RenWu(); // 實現摘取網頁源碼 String htmls = renWu.getPageSource(tempURL, "utf-8"); // 網頁信息轉換為jsoup可識別的doc模式 Document doc = Jsoup.parse(htmls); // 摘取該頁搜索鏈接 Elements links = doc.select("a[data-click]"); // 該處同上getFirstPage的相關實現 for (Element link : links) { // 鏈接url String linkHref = link.attr("href"); // 鏈接標題 String linkText = link.text(); if(linkHref.length() > 13 & linkText.length() > 4) { String content = "鏈接url: " + linkHref + "\n\t鏈接標題: " + linkText + "\n"; System.out.println(content); FileUtil.toFile(content); } } } } }); thread.start(); } public String getPageSource(String pageURL, String encoding) { // 輸入:url鏈接&編碼格式 // 輸出:該網頁內容 StringBuffer sb = new StringBuffer(); try { // 構建一URL對象 URL url = new URL(pageURL); // 使用openStream得到一輸入流並由此構造一個BufferedReader對象 InputStream in = url.openStream(); InputStreamReader ir = new InputStreamReader(in); BufferedReader br = new BufferedReader(ir); String line; while((line = br.readLine()) != null) { sb.append(line); sb.append("\n"); } br.close(); } catch (Exception e) { e.printStackTrace(); } return sb.toString(); } /* * 獲取百度搜索第一頁內容 */ public static Elements getFirstPage(String keyWord) throws FailingHttpStatusCodeException, MalformedURLException, IOException { //設置瀏覽器的User-Agent WebClient webClient = new WebClient(BrowserVersion.FIREFOX_52); // HtmlUnit對JavaScript的支持不好,關閉之 webClient.getOptions().setJavaScriptEnabled(false); // HtmlUnit對CSS的支持不好,關閉之 webClient.getOptions().setCssEnabled(false); // 百度搜索首頁頁面 HtmlPage htmlPage = webClient.getPage("http://www.baidu.com/"); // 獲取搜索輸入框並提交搜索內容(查看源碼獲取元素名稱) HtmlInput input = htmlPage.getHtmlElementById("kw"); // 將搜索詞模擬填進百度輸入框(元素ID如上) input.setValueAttribute(keyWord); // 獲取搜索按鈕並點擊 HtmlInput btn = htmlPage.getHtmlElementById("su"); // 模擬搜索按鈕事件,獲取第一頁的html內容 firstBaiduPage = btn.click(); // 將獲取到的百度搜索的第一頁信息輸出 // 通過page.asXml()來獲取百度首頁的源代碼, // 通過page.asTest()來獲取頁面的文字 String content = firstBaiduPage.asXml().toString(); // 轉換為Jsoup識別的doc格式 Document doc = Jsoup.parse(content); System.out.println("---------百度搜索關鍵字“" + keyWord + "”第1頁結果--------"); FileUtil.toFile("---------百度搜索關鍵字“" + keyWord + "”第1頁結果--------" + "\n"); // 返回包含類似<a......data-click=" "......>等的元素 Elements firstElementsLink = doc.select("a[data-click]"); // 返回此類鏈接,即第一頁的百度搜素鏈接 return firstElementsLink; } /* * 獲取下一頁地址 */ public static void nextHref(HtmlPage firstBaiduPage) { WebClient webClient = new WebClient(BrowserVersion.FIREFOX_52); webClient.getOptions().setJavaScriptEnabled(false); webClient.getOptions().setCssEnabled(false); // 獲取到百度第一頁搜索的底端的頁碼的html代碼 String morelinks = firstBaiduPage.getElementById("page").asXml(); // 轉換為Jsoup識別的doc格式 Document doc = Jsoup.parse(morelinks); // 提取這個html中的包含<a href=""....>的部分 Elements links = doc.select("a[href]"); // 設置只取一次每頁鏈接的模板格式 boolean getTemplate = true; for (Element e : links) { // 將提取出來的<a>標簽中的鏈接取出 String linkHref = e.attr("href"); if(getTemplate) { // 補全模板格式 template = "http://www.baidu.com" + linkHref; getTemplate = false; } } } }
導出到本地文件(末尾追加)的封裝方發類FileUtil.class:
package com.zhaowu.renwu2; import java.io.File; import java.io.FileWriter; import java.io.IOException; public class FileUtil { public static void toFile (String content) { File file = null; FileWriter fw = null; file = new File("/home/acer/桌面/aaa"); try { if (!file.exists()) { file.createNewFile(); } fw = new FileWriter(file,true); fw.write(content);//向文件中復制內容 fw.flush(); } catch (IOException e) { e.printStackTrace(); }finally{ if(fw != null){ try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
爬蟲任務二:爬取(用到htmlunit和jsoup)通過百度搜索引擎關鍵字搜取到的新聞標題和url,並保存在本地文件中(主體借鑒了網上的資料)