国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

基于Java HttpClient和Htmlparser實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲代碼

2020-03-24 16:04:22
字體:
供稿:網(wǎng)友
開發(fā)環(huán)境的搭建,在工程的 Build Path 中導(dǎo)入下載的Commons-httpClient3.1.Jar,htmllexer.jar 以及 htmlparser.jar 文件。圖 1. 開發(fā)環(huán)境搭建 HttpClient 基本類庫使用HttpClinet 提供了幾個(gè)類來支持 HTTP 訪問。下面我們通過一些示例代碼來熟悉和說明這些類的功能和使用。 HttpClient 提供的 HTTP 的訪問主要是通過 GetMethod 類和 PostMethod 類來實(shí)現(xiàn)的,他們分別對應(yīng)了 HTTP Get 請求與 Http Post 請求。GetMethod使用 GetMethod 來訪問一個(gè) URL 對應(yīng)的網(wǎng)頁,需要如下一些步驟。
生成一個(gè) HttpClinet 對象并設(shè)置相應(yīng)的參數(shù)。
生成一個(gè) GetMethod 對象并設(shè)置響應(yīng)的參數(shù)。
用 HttpClinet 生成的對象來執(zhí)行 GetMethod 生成的 Get 方法。
處理響應(yīng)狀態(tài)碼。
若響應(yīng)正常,處理 HTTP 響應(yīng)內(nèi)容。
釋放連接。清單 1 的代碼展示了這些步驟,其中的注釋對代碼進(jìn)行了較詳細(xì)的說明。清單 1./* 1 生成 HttpClinet 對象并設(shè)置參數(shù)*/ HttpClient httpClient=new HttpClient(); //設(shè)置 Http 連接超時(shí)為5秒httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000); /*2 生成 GetMethod 對象并設(shè)置參數(shù)*/ GetMethod getMethod=new GetMethod(url); //設(shè)置 get 請求超時(shí)為 5 秒getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000); //設(shè)置請求重試處理,用的是默認(rèn)的重試處理:請求三次getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); /*3 執(zhí)行 HTTP GET 請求*/ try{ int statusCode = httpClient.executeMethod(getMethod); /*4 判斷訪問的狀態(tài)碼*/ if (statusCode != HttpStatus.SC_OK) System.err.println("Method failed: "+ getMethod.getStatusLine()); /*5 處理 HTTP 響應(yīng)內(nèi)容*/ //HTTP響應(yīng)頭部信息,這里簡單打印 Header[] headers=getMethod.getResponseHeaders(); for(Header h: headers) System.out.println(h.getName()+" "+h.getValue());*/ //讀取 HTTP 響應(yīng)內(nèi)容,這里簡單打印網(wǎng)頁內(nèi)容 byte[] responseBody = getMethod.getResponseBody();//讀取為字節(jié)數(shù)組System.out.println(new String(responseBody)); //讀取為 InputStream,在網(wǎng)頁內(nèi)容數(shù)據(jù)量大時(shí)候推薦使用 InputStream response = getMethod.getResponseBodyAsStream();//catch (HttpException e) // 發(fā)生致命的異常,可能是協(xié)議不對或者返回的內(nèi)容有問題 System.out.println("Please check your provided http address!");e.printStackTrace();catch (IOException e) // 發(fā)生網(wǎng)絡(luò)異常 e.printStackTrace(); } finally { /*6 .釋放連接*/ getMethod.releaseConnection(); } 這里值得注意的幾個(gè)地方是:設(shè)置連接超時(shí)和請求超時(shí),這兩個(gè)超時(shí)的意義不同,需要分別設(shè)置。
響應(yīng)狀態(tài)碼的處理。返回的結(jié)果可以為字節(jié)數(shù)組,也可以為 InputStream,而后者在網(wǎng)頁內(nèi)容數(shù)據(jù)量較大的時(shí)候推薦使用。
在處理返回結(jié)果的時(shí)候可以根據(jù)自己的需要,進(jìn)行相應(yīng)的處理。如筆者是需要保存網(wǎng)頁
到本地,因此就可以寫一個(gè) saveToLocaleFile(byte[] data, String filePath) 的方法,將字節(jié)數(shù)組保存成本地文件。后續(xù)的簡易爬蟲部分會有相應(yīng)的介紹。PostMethod PostMethod 方法與 GetMethod 方法的使用步驟大體相同。但是由于 PostMethod 使用的是HTTP 的 Post 請求,因而請求參數(shù)的設(shè)置與 GetMethod 有所不同。在 GetMethod 中,請求的參數(shù)直接寫在 URL 里,一般以這樣形式出現(xiàn):http://hostname:port//file name1=value1&name2=value …。請求參數(shù)是 name,value 對。比如我想得到百度搜索“Thinking In Java”的結(jié)果網(wǎng)頁,就可以使 GetMethod 的構(gòu)造方法中的 url 為:http://www.baidu.com/s wd=Thinking+In+Java 。而 PostMethod 則可以模擬網(wǎng)頁里表單提交的過程,通過設(shè)置表單里 post 請求參數(shù)的值,來動態(tài)的獲得返回的網(wǎng)頁結(jié)果。清單 2 中的代碼展示了如何創(chuàng)建一個(gè) Post 對象,并設(shè)置相應(yīng)的請求參數(shù)。清單2PostMethod postMethod = new PostMethod("http://dict.cn/");postMethod.setRequestBody(new NameValuePair[]{new NameValuePair("q","java")}); HtmlParser 基本類庫使用HtmlParser 提供了強(qiáng)大的類庫來處理 Internet 上的網(wǎng)頁,可以實(shí)現(xiàn)對網(wǎng)頁特定內(nèi)容的提取和修改。下面通過幾個(gè)例子來介紹 HtmlParser 的一些使用。這些例子其中的代碼,有部分用在了后面介紹的簡易爬蟲中。以下所有的代碼和方法都在在類 HtmlParser.Test.java 里,這是筆者編寫的一個(gè)用來測試 HtmlParser 用法的類。迭代遍歷網(wǎng)頁所有節(jié)點(diǎn)網(wǎng)頁是一個(gè)半結(jié)構(gòu)化的嵌套文本文件,有類似 XML 文件的樹形嵌套結(jié)構(gòu)。使用HtmlParser 可以讓我們輕易的迭代遍歷網(wǎng)頁的所有節(jié)點(diǎn)。清單 3 展示了如何來實(shí)現(xiàn)這個(gè)功能。
清單 3
// 循環(huán)訪問所有節(jié)點(diǎn),輸出包含關(guān)鍵字的值節(jié)點(diǎn)public static void extractKeyWordText(String url, String keyword) { try { //生成一個(gè)解析器對象,用網(wǎng)頁的 url 作為參數(shù) Parser parser = new Parser(url); //設(shè)置網(wǎng)頁的編碼,這里只是請求了一個(gè) gb2312 編碼網(wǎng)頁 parser.setEncoding("gb2312"); //迭代所有節(jié)點(diǎn), null 表示不使用 NodeFilter NodeList list = parser.parse(null); //從初始的節(jié)點(diǎn)列表跌倒所有的節(jié)點(diǎn) processNodeList(list, keyword); } catch (ParserException e) { e.printStackTrace(); private static void processNodeList(NodeList list, String keyword) { //迭代開始 SimpleNodeIterator iterator = list.elements(); while (iterator.hasMoreNodes()) { Node node = iterator.nextNode(); //得到該節(jié)點(diǎn)的子節(jié)點(diǎn)列表 NodeList childList = node.getChildren(); //孩子節(jié)點(diǎn)為空,說明是值節(jié)點(diǎn) if (null == childList) //得到值節(jié)點(diǎn)的值 String result = node.toPlainTextString(); //若包含關(guān)鍵字,則簡單打印出來文本 if (result.indexOf(keyword) != -1) System.out.println(result); } //end if //孩子節(jié)點(diǎn)不為空,繼續(xù)迭代該孩子節(jié)點(diǎn) else processNodeList(childList, keyword); }//end else }//end wile } 上面的中有兩個(gè)方法:
private static void processNodeList(NodeList list, String keyword) 該方法是用類似深度優(yōu)先的方法來迭代遍歷整個(gè)網(wǎng)頁節(jié)點(diǎn),將那些包含了某個(gè)關(guān)鍵字的值節(jié)點(diǎn)的值打印出來。
public static void extractKeyWordText(String url, String keyword) 該方法生成針對 String 類型的 url 變量代表的某個(gè)特定網(wǎng)頁的解析器,調(diào)用 1中的方法實(shí)現(xiàn)簡單的遍歷。清單 3 的代碼展示了如何迭代所有的網(wǎng)頁,更多的工作可以在此基礎(chǔ)上展開。比如找到某個(gè)特定的網(wǎng)頁內(nèi)部節(jié)點(diǎn),其實(shí)就可以在遍歷所有的節(jié)點(diǎn)基礎(chǔ)上來判斷,看被迭代的節(jié)點(diǎn)是否滿足特定的需要。使用 NodeFilterNodeFilter 是一個(gè)接口,任何一個(gè)自定義的 Filter 都需要實(shí)現(xiàn)這個(gè)接口中的 boolean accept() 方法。如果希望迭代網(wǎng)頁節(jié)點(diǎn)的時(shí)候保留當(dāng)前節(jié)點(diǎn),則在節(jié)點(diǎn)條件滿足的情況下返回 true;否則返回 false。HtmlParse 里提供了很多實(shí)現(xiàn)了 NodeFilter 接口的類,下面就一些筆者所用到的,以及常用的 Filter 做一些介紹:對 Filter 做邏輯操作的 Fitler 有:AndFilter,NotFilter ,OrFilter,XorFilter。
這些 Filter 來組合不同的 Filter,形成滿足兩個(gè) Filter 邏輯關(guān)系結(jié)果的 Filter。判斷節(jié)點(diǎn)的孩子,兄弟,以及父親節(jié)點(diǎn)情況的 Filter 有:HasChildFilterHasParentFilter,HasSiblingFilter。
判斷節(jié)點(diǎn)本身情況的 Filter 有 HasAttributeFilter:判讀節(jié)點(diǎn)是否有特定屬性;LinkStringFilter:判斷節(jié)點(diǎn)是否是具有特定模式 (pattern) url 的節(jié)點(diǎn);
TagNameFilter:判斷節(jié)點(diǎn)是否具有特定的名字;NodeClassFilter:判讀節(jié)點(diǎn)是否是某個(gè) HtmlParser 定義好的 Tag 類型。在 org.htmlparser.tags 包下有對應(yīng) Html標(biāo)簽的各種 Tag,例如 LinkTag,ImgeTag 等。還有其他的一些 Filter 在這里不一一列舉了,可以在 org.htmlparser.filters 下找到。清單 4 展示了如何使用上面提到過的一些 filter 來抽取網(wǎng)頁中的 a 標(biāo)簽里的 href屬性值, img 標(biāo)簽里的 src 屬性值,以及 frame 標(biāo)簽里的 src 的屬性值。清單4// 獲取一個(gè)網(wǎng)頁上所有的鏈接和圖片鏈接public static void extracLinks(String url) { try { Parser parser = new Parser(url); parser.setEncoding("gb2312");//過濾 frame 標(biāo)簽的 filter,用來提取 frame 標(biāo)簽里的 src 屬性所、表示的鏈接 NodeFilter frameFilter = new NodeFilter() { public boolean accept(Node node) { if (node.getText().startsWith("frame src=")) { return true; } else { return false; //OrFilter 來設(shè)置過濾 a 標(biāo)簽, img 標(biāo)簽和 frame 標(biāo)簽,三個(gè)標(biāo)簽是 or 的關(guān)系 OrFilte rorFilter = new OrFilter(new NodeClassFilter(LinkTag.class), newNodeClassFilter(ImageTag.class)); OrFilter linkFilter = new OrFilter(orFilter, frameFilter); //得到所有經(jīng)過過濾的標(biāo)簽 NodeList list = parser.extractAllNodesThatMatch(linkFilter); for (int i = 0; i list.size(); i++) { Node tag = list.elementAt(i); if (tag instanceof LinkTag)// a 標(biāo)簽 LinkTag link = (LinkTag) tag; String linkUrl = link.getLink();//url String text = link.getLinkText();//鏈接文字 System.out.println(linkUrl + "**********" + text); else if (tag instanceof ImageTag)// img 標(biāo)簽 ImageTag image = (ImageTag) list.elementAt(i); System.out.print(image.getImageURL() + "********");//圖片地址 System.out.println(image.getText());//圖片文字 else// frame 標(biāo)簽//提取 frame 里 src 屬性的鏈接如 frame src="test.html"/ String frame = tag.getText(); int start = frame.indexOf("src="); frame = frame.substring(start); int end = frame.indexOf(" "); if (end == -1) end = frame.indexOf(" frame = frame.substring(5, end - 1); System.out.println(frame);} catch (ParserException e) { e.printStackTrace();} 簡單強(qiáng)大的 StringBean
如果你想要網(wǎng)頁中去掉所有的標(biāo)簽后剩下的文本,那就是用 StringBean 吧。以下簡單的代碼可以幫你解決這樣的問題:清單5StringBean sb = new StringBean();sb.setLinks(false);//設(shè)置結(jié)果中去點(diǎn)鏈接sb.setURL(url);//設(shè)置你所需要濾掉網(wǎng)頁標(biāo)簽的頁面 url System.out.println(sb.getStrings());//打印結(jié)果 HtmlParser 提供了強(qiáng)大的類庫來處理網(wǎng)頁,由于本文旨在簡單的介紹,因此只是將與筆者后續(xù)爬蟲部分有關(guān)的關(guān)鍵類庫進(jìn)行了示例說明。感興趣的讀者可以專門來研究一下 HtmlParser 更為強(qiáng)大的類庫。簡易爬蟲的實(shí)現(xiàn) HttpClient 提供了便利的 HTTP 協(xié)議訪問,使得我們可以很容易的得到某個(gè)網(wǎng)頁的源碼并保存在本地;HtmlParser 提供了如此簡便靈巧的類庫,可以從網(wǎng)頁中便捷的提取出指向其他網(wǎng)頁的超鏈接。筆者結(jié)合這兩個(gè)開源包,構(gòu)建了一個(gè)簡易的網(wǎng)絡(luò)爬蟲。
爬蟲 (Crawler) 原理 學(xué)過數(shù)據(jù)結(jié)構(gòu)的讀者都知道有向圖這種數(shù)據(jù)結(jié)構(gòu)。如下圖所示,如果將網(wǎng)頁看成是圖中的某一個(gè)節(jié)點(diǎn),而將網(wǎng)頁中指向其他網(wǎng)頁的鏈接看成是這個(gè)節(jié)點(diǎn)指向其他節(jié)點(diǎn)的邊,那么我們很容易將整個(gè) Internet 上的網(wǎng)頁建模成一個(gè)有向圖。理論上,通過遍歷算法遍歷該圖,可以訪問到Internet 上的幾乎所有的網(wǎng)頁。最簡單的遍歷就是寬度優(yōu)先以及深度優(yōu)先。以下筆者實(shí)現(xiàn)的簡易爬蟲就是使用了寬度優(yōu)先的爬行策略
圖 2. 網(wǎng)頁關(guān)系的建模圖 簡易爬蟲實(shí)現(xiàn)流程 在看簡易爬蟲的實(shí)現(xiàn)代碼之前,先介紹一下簡易爬蟲爬取網(wǎng)頁的流程。圖 3. 爬蟲流程圖 各個(gè)類的源碼以及說明對應(yīng)上面的流程圖,簡易爬蟲由下面幾個(gè)類組成,各個(gè)類職責(zé)如下:Crawler.java:爬蟲的主方法入口所在的類,實(shí)現(xiàn)爬取的主要流程。LinkDb.java:用來保存已經(jīng)訪問的 url 和待爬取的 url 的類,提供url出對入隊(duì)操作。Queue.java: 實(shí)現(xiàn)了一個(gè)簡單的隊(duì)列,在 LinkDb.java 中使用了此類。FileDownloader.java:用來下載 url 所指向的網(wǎng)頁。HtmlParserTool.java: 用來抽取出網(wǎng)頁中的鏈接。LinkFilter.java:一個(gè)接口,實(shí)現(xiàn)其 accept() 方法用來對抽取的鏈接進(jìn)行過濾。下面是各個(gè)類的源碼,代碼中的注釋有比較詳細(xì)的說明。清單6 Crawler.javapackage com.ie; import java.util.Set;public class Crawler { /* 使用種子 url 初始化 URL 隊(duì)列*/ private void initCrawlerWithSeeds(String[] seeds) for(int i=0;i seeds.length;i++) LinkDB.addUnvisitedUrl(seeds[i]); /* 爬取方法*/ public void crawling(String[] seeds) LinkFilter filter = new LinkFilter(){ //提取以 http://www.twt.edu.cn 開頭的鏈接 public boolean accept(String url) { if(url.startsWith("http://www.twt.edu.cn")) return true; else return false; //初始化 URL 隊(duì)列 initCrawlerWithSeeds(seeds); //循環(huán)條件:待抓取的鏈接不空且抓取的網(wǎng)頁不多于 1000 while(!LinkDB.unVisitedUrlsEmpty()&&LinkDB.getVisitedUrlNum() =1000) //隊(duì)頭 URL 出對 String visitUrl=LinkDB.unVisitedUrlDeQueue(); if(visitUrl==null) continue; FileDownLoader downLoader=new FileDownLoader(); //下載網(wǎng)頁 downLoader.downloadFile(visitUrl); //該 url 放入到已訪問的 URL 中 LinkDB.addVisitedUrl(visitUrl); //提取出下載網(wǎng)頁中的 URL Set String links=HtmlParserTool.extracLinks(visitUrl,filter); //新的未訪問的 URL 入隊(duì) for(String link:links) LinkDB.addUnvisitedUrl(link); //main 方法入口 public static void main(String[]args) Crawler crawler = new Crawler(); crawler.crawling(new String[]{"http://www.twt.edu.cn"});}清單7 LinkDb.javapackage com.ie;import java.util.HashSet;import java.util.Set; * 用來保存已經(jīng)訪問過 Url 和待訪問的 Url 的類public class LinkDB { //已訪問的 url 集合 private static Set String visitedUrl = new HashSet String //待訪問的 url 集合 private static Queue String unVisitedUrl = new Queue String public static Queue String getUnVisitedUrl() { return unVisitedUrl; public static void addVisitedUrl(String url) { visitedUrl.add(url); public static void removeVisitedUrl(String url) { visitedUrl.remove(url); public static String unVisitedUrlDeQueue() { return unVisitedUrl.deQueue(); // 保證每個(gè) url 只被訪問一次 public static void addUnvisitedUrl(String url) { if (url != null && !url.trim().equals("") && !visitedUrl.contains(url) && !unVisitedUrl.contians(url)) unVisitedUrl.enQueue(url); public static int getVisitedUrlNum() { return visitedUrl.size(); public static boolean unVisitedUrlsEmpty() { return unVisitedUrl.empty();清單8 Queue.java
package com.ie;import java.util.LinkedList; * 數(shù)據(jù)結(jié)構(gòu)隊(duì)列public class Queue T { private LinkedList T queue=new LinkedList T public void enQueue(T t) queue.addLast(t); public T deQueue() return queue.removeFirst(); public boolean isQueueEmpty() return queue.isEmpty(); public boolean contians(T t) return queue.contains(t); public boolean empty() return queue.isEmpty();} 清單 9 FileDownLoader.java
package com.ie;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpException;import org.apache.commons.httpclient.HttpStatus;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.params.HttpMethodParams;public class FileDownLoader { /**根據(jù) url 和網(wǎng)頁類型生成需要保存的網(wǎng)頁的文件名 *去除掉 url 中非文件名字符 public String getFileNameByUrl(String url,String contentType) url=url.substring(7);//remove http:// if(contentType.indexOf("html")!=-1)//text/html url= url.replaceAll("[// /:*| /"]", "_")+".html"; return url; else//如application/pdfreturn url.replaceAll("[// /:*| /"]", "_")+"."+ / contentType.substring(contentType.lastIndexOf("/")+1); /**保存網(wǎng)頁字節(jié)數(shù)組到本地文件 * filePath 為要保存的文件的相對地址 private void saveToLocal(byte[] data,String filePath) try { DataOutputStream out=new DataOutputStream(new FileOutputStream(new File(filePath))); for(int i=0;i data.length;i++) out.write(data[i]); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); /*下載 url 指向的網(wǎng)頁*/ public String downloadFile(String url) String filePath=null; /* 1.生成 HttpClinet 對象并設(shè)置參數(shù)*/ HttpClient httpClient=new HttpClient(); //設(shè)置 Http 連接超時(shí) 5s httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000); /*2.生成 GetMethod 對象并設(shè)置參數(shù)*/ GetMethod getMethod=new GetMethod(url); //設(shè)置 get 請求超時(shí) 5s getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000); //設(shè)置請求重試處理 getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); /*3.執(zhí)行 HTTP GET 請求*/ try{ int statusCode = httpClient.executeMethod(getMethod); //判斷訪問的狀態(tài)碼 if (statusCode != HttpStatus.SC_OK) System.err.println("Method failed: "+ getMethod.getStatusLine()); filePath=null; /*4.處理 HTTP 響應(yīng)內(nèi)容*/ byte[] responseBody = getMethod.getResponseBody();//讀取為字節(jié)數(shù)組 //根據(jù)網(wǎng)頁 url 生成保存時(shí)的文件名filePath="temp//"+getFileNameByUrl(url, getMethod.getResponseHeader("Content-Type").getValue()); saveToLocal(responseBody,filePath); } catch (HttpException e) { // 發(fā)生致命的異常,可能是協(xié)議不對或者返回的內(nèi)容有問題 System.out.println("Please check your provided http address!"); e.printStackTrace(); } catch (IOException e) { // 發(fā)生網(wǎng)絡(luò)異常 e.printStackTrace(); } finally { // 釋放連接 getMethod.releaseConnection(); return filePath; //測試的 main 方法 public static void main(String[]args) FileDownLoader downLoader = new FileDownLoader(); downLoader.downloadFile("http://www.twt.edu.cn");} 清單 10 HtmlParserTool.javapackage com.ie;import java.util.HashSet;import java.util.Set;import org.htmlparser.Node;import org.htmlparser.NodeFilter;import org.htmlparser.Parser;import org.htmlparser.filters.NodeClassFilter;import org.htmlparser.filters.OrFilter;import org.htmlparser.tags.LinkTag;import org.htmlparser.util.NodeList;import org.htmlparser.util.ParserException;public class HtmlParserTool { // 獲取一個(gè)網(wǎng)站上的鏈接,filter 用來過濾鏈接 public static Set String extracLinks(String url,LinkFilter filter) { Set String links = new HashSet String try { Parser parser = new Parser(url); parser.setEncoding("gb2312"); // 過濾 frame 標(biāo)簽的 filter,用來提取 frame 標(biāo)簽里的 src 屬性所表示的鏈接 NodeFilter frameFilter = new NodeFilter() { public boolean accept(Node node) { if (node.getText().startsWith("frame src=")) { return true; } else { return false; // OrFilter 來設(shè)置過濾 a 標(biāo)簽,和 frame 標(biāo)簽 OrFilter linkFilter = new OrFilter(new NodeClassFilter( LinkTag.class), frameFilter); // 得到所有經(jīng)過過濾的標(biāo)簽 NodeList list = parser.extractAllNodesThatMatch(linkFilter); for (int i = 0; i list.size(); i++) { Node tag = list.elementAt(i); if (tag instanceof LinkTag)// a 標(biāo)簽 LinkTag link = (LinkTag) tag; String linkUrl = link.getLink();// url if(filter.accept(linkUrl)) links.add(linkUrl); } else// frame 標(biāo)簽 // 提取 frame 里 src 屬性的鏈接如 frame src="test.html"/ String frame = tag.getText(); int start = frame.indexOf("src="); frame = frame.substring(start); int end = frame.indexOf(" "); if (end == -1) end = frame.indexOf(" String frameUrl = frame.substring(5, end - 1); if(filter.accept(frameUrl)) links.add(frameUrl); } catch (ParserException e) { e.printStackTrace(); return links; //測試的 main 方法 public static void main(String[]args)Set String links = HtmlParserTool.extracLinks("http://www.twt.edu.cn",new LinkFilter() //提取以 http://www.twt.edu.cn 開頭的鏈接 public boolean accept(String url) { if(url.startsWith("http://www.twt.edu.cn")) return true; else return false; for(String link : links) System.out.println(link);} 清單11 LinkFilter.javapackage com.ie;public interface LinkFilter { public boolean accept(String url);} 這些代碼中關(guān)鍵的部分都在 HttpClient 和 HtmlParser 介紹中說明過了,其他部分也比較容易,請感興趣的讀者自行理解。
更多編程語言

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 喀什市| 张北县| 阿拉尔市| 丰城市| 峡江县| 吉安市| 临潭县| 龙口市| 大理市| 镇沅| 冀州市| 哈尔滨市| 襄城县| 剑阁县| 石屏县| 大渡口区| 山阴县| 循化| 新巴尔虎右旗| 界首市| 且末县| 青冈县| 独山县| 阜城县| 沾化县| 荔浦县| 蛟河市| 横峰县| 洪雅县| 岳普湖县| 特克斯县| 彰化市| 南溪县| 张家港市| 林甸县| 墨脱县| 昔阳县| 东宁县| 新乡县| 东阿县| 福泉市|