<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Heck's  Blog]]></title> 
<link>https://www.heckjj.com/index.php</link> 
<description><![CDATA[一瞬间的决定，往往可以改变很多，事实上，让自己成功的往往不是知识，是精神！ 如果你总是为自己找借口，那只好让成功推迟。执行力，今天！]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Heck's  Blog]]></copyright>
<item>
<link>https://www.heckjj.com/java-web-search-spider-html/</link>
<title><![CDATA[一个Java Web搜索程序类似网页下载之类的“爬虫”]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[编程杂谈]]></category>
<pubDate>Mon, 25 Oct 2010 12:02:39 +0000</pubDate> 
<guid>https://www.heckjj.com/java-web-search-spider-html/</guid> 
<description>
<![CDATA[ 
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-family: 微软雅黑;">其实这是一个web搜索的基本程序，从命令行输入搜索条件，起始的URL、处理url的最大数、要搜索的字符串，它就会逐个对Internet上的URL进行实时搜索,查找并输出匹配搜索条件的页面。 这个程序的原型来自《java编程艺术》，为了更好的分析，Heck去掉了其中的GUI部分，并稍作修改以适用jdk1.5。以这个程序为基础，可以写出在互联网上搜索诸如图像、邮件、网页下载之类的“爬虫”。<br/><br/>先请看程序运行的过程： <br/><br/>D:&#92;java&gt;javac&nbsp;&nbsp;SearchCrawler.java <br/><br/>D:&#92;java&gt;java&nbsp;&nbsp; SearchCrawler http://127.0.0.1:8080/webhome/index.jsp 20 java <br/><br/>Start searching... <br/>result: <br/>searchString=java <br/>http://127.0.0.1:8080/webhome/index.jsp <br/>http://127.0.0.1:8080/webhome/reply.jsp <br/>http://127.0.0.1:8080/webhome/learn.jsp <br/>http://127.0.0.1:8080/webhome/download.jsp <br/>http://127.0.0.1:8080/webhome/article.jsp <br/>http://127.0.0.1:8080/webhome/HeckGUIOverview.htm <br/>http://127.0.0.1:8080/webhome/myexample/Proxooldoc/index.html <br/>http://127.0.0.1:8080/webhome/view.jsp?id=301 <br/>http://127.0.0.1:8080/webhome/view.jsp?id=297 <br/>http://127.0.0.1:8080/webhome/view.jsp?id=291 <br/>http://127.0.0.1:8080/webhome/view.jsp?id=286 <br/>http://127.0.0.1:8080/webhome/view.jsp?id=285 <br/>http://127.0.0.1:8080/webhome/view.jsp?id=284 <br/>http://127.0.0.1:8080/webhome/view.jsp?id=276 <br/>http://127.0.0.1:8080/webhome/view.jsp?id=272&nbsp;&nbsp;</span><span style="font-family: 微软雅黑;"><br/><br/>又如： <br/>D:&#92;java&gt;java&nbsp;&nbsp;&nbsp;&nbsp;SearchCrawler http://www.sina.com&nbsp;&nbsp;20 java <br/>Start searching... <br/>result: <br/>searchString=java <br/>http://sina.com <br/>http://redirect.sina.com/WWW/sinaCN/www.sina.com.cn class=a2 <br/>http://redirect.sina.com/WWW/sinaCN/www.sina.com.cn class=a8 <br/>http://redirect.sina.com/WWW/sinaHK/www.sina.com.hk class=a2 <br/>http://redirect.sina.com/WWW/sinaTW/www.sina.com.tw class=a8 <br/>http://redirect.sina.com/WWW/sinaUS/home.sina.com class=a8 <br/>http://redirect.sina.com/WWW/smsCN/sms.sina.com.cn/ class=a2 <br/>http://redirect.sina.com/WWW/smsCN/sms.sina.com.cn/ class=a3 <br/>http://redirect.sina.com/WWW/sinaNet/www.sina.net/ class=a3 <br/><br/>D:&#92;java&gt; <br/>下面是这个程序的源码 </span><br/><textarea name="code" class="java" rows="15" cols="100">
import java.util.*;
import java.net.*;
import java.io.*;
import java.util.regex.*;
// 搜索Web爬行者
public class SearchCrawler implements Runnable&#123;
 
/* disallowListCache缓存robot不允许搜索的URL。 Robot协议在Web站点的根目录下设置一个robots.txt文件,
&nbsp;&nbsp;*规定站点上的哪些页面是限制搜索的。 搜索程序应该在搜索过程中跳过这些区域,下面是robots.txt的一个例子:
 # robots.txt for http://idcpw.com/
&nbsp;&nbsp; User-agent: *
&nbsp;&nbsp; Disallow: /cgi-bin/
&nbsp;&nbsp; Disallow: /registration # /Disallow robots on registration page
&nbsp;&nbsp; Disallow: /login
&nbsp;&nbsp;*/
&nbsp;&nbsp;private HashMap&lt; String,ArrayList&lt; String&gt;&gt; disallowListCache = new HashMap&lt; String,ArrayList&lt; String&gt;&gt;(); 
&nbsp;&nbsp;ArrayList&lt; String&gt; errorList= new ArrayList&lt; String&gt;();//错误信息 
&nbsp;&nbsp;ArrayList&lt; String&gt; result=new ArrayList&lt; String&gt;(); //搜索到的结果 
&nbsp;&nbsp;String startUrl;//开始搜索的起点
&nbsp;&nbsp;int maxUrl;//最大处理的url数
&nbsp;&nbsp;String searchString;//要搜索的字符串(英文)
&nbsp;&nbsp;boolean caseSensitive=false;//是否区分大小写
&nbsp;&nbsp;boolean limitHost=false;//是否在限制的主机内搜索
&nbsp;&nbsp;
&nbsp;&nbsp;public SearchCrawler(String startUrl,int maxUrl,String searchString)&#123;
&nbsp;&nbsp; this.startUrl=startUrl;
&nbsp;&nbsp; this.maxUrl=maxUrl;
&nbsp;&nbsp; this.searchString=searchString;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp; public ArrayList&lt; String&gt; getResult()&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;
&nbsp;&nbsp; &#125;
&nbsp;&nbsp;public void run()&#123;//启动搜索线程
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; crawl(startUrl,maxUrl, searchString,limitHost,caseSensitive);
&nbsp;&nbsp;&#125;
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;//检测URL格式
&nbsp;&nbsp;private URL verifyUrl(String url) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;// 只处理HTTP URLs.
&nbsp;&nbsp;&nbsp;&nbsp;if (!url.toLowerCase().startsWith(&quot;http://&quot;))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;
&nbsp;&nbsp;&nbsp;&nbsp;URL verifiedUrl = null;
&nbsp;&nbsp;&nbsp;&nbsp;try &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;verifiedUrl = new URL(url);
&nbsp;&nbsp;&nbsp;&nbsp;&#125; catch (Exception e) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;return verifiedUrl;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;// 检测robot是否允许访问给出的URL.
 private boolean isRobotAllowed(URL urlToCheck) &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;String host = urlToCheck.getHost().toLowerCase();//获取给出RUL的主机 
&nbsp;&nbsp;&nbsp;&nbsp;//System.out.println(&quot;主机=&quot;+host);
&nbsp;&nbsp;&nbsp;&nbsp;// 获取主机不允许搜索的URL缓存 
&nbsp;&nbsp;&nbsp;&nbsp;ArrayList&lt; String&gt; disallowList =disallowListCache.get(host); 
&nbsp;&nbsp;&nbsp;&nbsp;// 如果还没有缓存,下载并缓存。 
&nbsp;&nbsp;&nbsp;&nbsp;if (disallowList == null) &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disallowList = new ArrayList&lt; String&gt;(); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL robotsFileUrl =new URL(&quot;http://&quot; + host + &quot;/robots.txt&quot;); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedReader reader =new BufferedReader(new InputStreamReader(robotsFileUrl.openStream())); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 读robot文件，创建不允许访问的路径列表。 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String line; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ((line = reader.readLine()) != null) &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (line.indexOf(&quot;Disallow:&quot;) == 0) &#123;//是否包含&quot;Disallow:&quot; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String disallowPath =line.substring(&quot;Disallow:&quot;.length());//获取不允许访问路径 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 检查是否有注释。 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int commentIndex = disallowPath.indexOf(&quot;#&quot;); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (commentIndex != - 1) &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disallowPath =disallowPath.substring(0, commentIndex);//去掉注释 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disallowPath = disallowPath.trim(); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disallowList.add(disallowPath); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 缓存此主机不允许访问的路径。 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disallowListCache.put(host, disallowList); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; catch (Exception e) &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true; //web站点根目录下没有robots.txt文件,返回真
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; 
&nbsp;&nbsp;&nbsp;&nbsp;&#125; 
&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;String file = urlToCheck.getFile(); 
&nbsp;&nbsp;&nbsp;&nbsp;//System.out.println(&quot;文件getFile()=&quot;+file);
&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; disallowList.size(); i++) &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String disallow = disallowList.get(i); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (file.startsWith(disallow)) &#123; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; 
&nbsp;&nbsp;&nbsp;&nbsp;&#125; 
&nbsp;&nbsp;&nbsp;&nbsp;return true; 
&nbsp;&nbsp;&#125; 
 
&nbsp;&nbsp;private String downloadPage(URL pageUrl) &#123;
&nbsp;&nbsp;&nbsp;&nbsp; try &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Open connection to URL for reading.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedReader reader =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new BufferedReader(new InputStreamReader(pageUrl.openStream()));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Read page into buffer.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String line;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuffer pageBuffer = new StringBuffer();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ((line = reader.readLine()) != null) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pageBuffer.append(line);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return pageBuffer.toString();
&nbsp;&nbsp;&nbsp;&nbsp; &#125; catch (Exception e) &#123;
&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp; return null;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;// 从URL中去掉&quot;www&quot;
&nbsp;&nbsp;private String removeWwwFromUrl(String url) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;int index = url.indexOf(&quot;://www.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;if (index != -1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return url.substring(0, index + 3) +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url.substring(index + 7);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;return (url);
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;// 解析页面并找出链接
&nbsp;&nbsp;private ArrayList&lt; String&gt; retrieveLinks(URL pageUrl, String pageContents, HashSet crawledList,
&nbsp;&nbsp;&nbsp;&nbsp;boolean limitHost)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;// 用正则表达式编译链接的匹配模式。
&nbsp;&nbsp;&nbsp;&nbsp;Pattern p =Pattern.compile(&quot;&lt; a&#92;&#92;s+href&#92;&#92;s*=&#92;&#92;s*&#92;&quot;?(.*?)[&#92;&quot;&#124;&gt;]&quot;,Pattern.CASE_INSENSITIVE);
&nbsp;&nbsp;&nbsp;&nbsp;Matcher m = p.matcher(pageContents);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;ArrayList&lt; String&gt; linkList = new ArrayList&lt; String&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;while (m.find()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String link = m.group(1).trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (link.length() &lt; 1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 跳过链到本页面内链接。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (link.charAt(0) == &#039;#&#039;) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (link.indexOf(&quot;mailto:&quot;) != -1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (link.toLowerCase().indexOf(&quot;javascript&quot;) != -1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (link.indexOf(&quot;://&quot;) == -1)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (link.charAt(0) == &#039;/&#039;) &#123;//处理绝对地&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link = &quot;http://&quot; + pageUrl.getHost()+&quot;:&quot;+pageUrl.getPort()+ link;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String file = pageUrl.getFile();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (file.indexOf(&#039;/&#039;) == -1) &#123;//处理相对地址
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link = &quot;http://&quot; + pageUrl.getHost()+&quot;:&quot;+pageUrl.getPort() + &quot;/&quot; + link;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String path =file.substring(0, file.lastIndexOf(&#039;/&#039;) + 1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link = &quot;http://&quot; + pageUrl.getHost() +&quot;:&quot;+pageUrl.getPort()+ path + link;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int index = link.indexOf(&#039;#&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (index != -1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link = link.substring(0, index);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link = removeWwwFromUrl(link);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL verifiedLink = verifyUrl(link);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (verifiedLink == null) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 如果限定主机，排除那些不合条件的URL*/
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (limitHost &amp;&amp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!pageUrl.getHost().toLowerCase().equals(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;verifiedLink.getHost().toLowerCase()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 跳过那些已经处理的链接.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (crawledList.contains(link)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; linkList.add(link);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp; return (linkList);
&nbsp;&nbsp;&#125;
 // 搜索下载Web页面的内容，判断在该页面内有没有指定的搜索字符串
&nbsp;&nbsp;private boolean searchStringMatches(String pageContents, String searchString, boolean caseSensitive)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String searchContents = pageContents; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!caseSensitive) &#123;//如果不区分大小写
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchContents = pageContents.toLowerCase();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Pattern p = Pattern.compile(&quot;[&#92;&#92;s]+&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;String[] terms = p.split(searchString);
&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; terms.length; i++) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (caseSensitive) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (searchContents.indexOf(terms[i]) == -1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (searchContents.indexOf(terms[i].toLowerCase()) == -1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;return true;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;//执行实际的搜索操作
&nbsp;&nbsp;public ArrayList&lt; String&gt; crawl(String startUrl, int maxUrls, String searchString,boolean limithost,boolean caseSensitive )
&nbsp;&nbsp;&#123; 
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;searchString=&quot;+searchString);
&nbsp;&nbsp;&nbsp;&nbsp;HashSet&lt; String&gt; crawledList = new HashSet&lt; String&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;LinkedHashSet&lt; String&gt; toCrawlList = new LinkedHashSet&lt; String&gt;();
&nbsp;&nbsp;&nbsp;&nbsp; if (maxUrls &lt; 1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorList.add(&quot;Invalid Max URLs value.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;Invalid Max URLs value.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if (searchString.length() &lt; 1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorList.add(&quot;Missing Search String.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;Missing search String&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if (errorList.size() &gt; 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;err!!!&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return errorList;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;// 从开始URL中移出www
&nbsp;&nbsp;&nbsp;&nbsp;startUrl = removeWwwFromUrl(startUrl);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;toCrawlList.add(startUrl);
&nbsp;&nbsp;&nbsp;&nbsp;while (toCrawlList.size() &gt; 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (maxUrls != -1) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (crawledList.size() == maxUrls) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Get URL at bottom of the list.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String url =&nbsp;&nbsp;toCrawlList.iterator().next();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Remove URL from the to crawl list.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toCrawlList.remove(url);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Convert string url to URL object.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL verifiedUrl = verifyUrl(url);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Skip URL if robots are not allowed to access it.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!isRobotAllowed(verifiedUrl)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 增加已处理的URL到crawledList
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crawledList.add(url);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String pageContents = downloadPage(verifiedUrl);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pageContents != null &amp;&amp; pageContents.length() &gt; 0)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 从页面中获取有效的链接
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayList&lt; String&gt; links =retrieveLinks(verifiedUrl, pageContents, crawledList,limitHost);
&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toCrawlList.addAll(links);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (searchStringMatches(pageContents, searchString,caseSensitive))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.add(url);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(url);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp; return result;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;// 主函数
&nbsp;&nbsp;public static void main(String[] args) &#123;
&nbsp;&nbsp;&nbsp;&nbsp; if(args.length!=3)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;Usage:java SearchCrawler startUrl maxUrl searchString&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;int max=Integer.parseInt(args[1]);
&nbsp;&nbsp;&nbsp;&nbsp;SearchCrawler crawler = new SearchCrawler(args[0],max,args[2]);
&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;&nbsp;search=new Thread(crawler);
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;Start searching...&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;result:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;search.start();
&nbsp;&nbsp; 
&nbsp;&nbsp;&#125;
&#125;</textarea><br/>Tags - <a href="https://www.heckjj.com/tags/java/" rel="tag">java</a> , <a href="https://www.heckjj.com/tags/web/" rel="tag">web</a> , <a href="https://www.heckjj.com/tags/%25E6%2590%259C%25E7%25B4%25A2%25E7%25A8%258B%25E5%25BA%258F/" rel="tag">搜索程序</a> , <a href="https://www.heckjj.com/tags/%25E5%259B%25BE%25E5%2583%258F/" rel="tag">图像</a> , <a href="https://www.heckjj.com/tags/%25E9%2582%25AE%25E4%25BB%25B6/" rel="tag">邮件</a> , <a href="https://www.heckjj.com/tags/%25E7%25BD%2591%25E9%25A1%25B5%25E4%25B8%258B%25E8%25BD%25BD/" rel="tag">网页下载</a> , <a href="https://www.heckjj.com/tags/%25E7%2588%25AC%25E8%2599%25AB/" rel="tag">爬虫</a>
]]>
</description>
</item><item>
<link>https://www.heckjj.com/java-web-search-spider-html/#blogcomment</link>
<title><![CDATA[[评论] 一个Java Web搜索程序类似网页下载之类的“爬虫”]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>https://www.heckjj.com/java-web-search-spider-html/#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>