代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
Java
】
爬虫程序
作者:
文杰
/ 发布于
2015/11/16
/
676
网络爬虫,是一种自动获取网页内容的程序。是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上就是针对爬虫而做出的优化。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SearchCrawler implements Runnable { // disallowListCache缓存robot不允许搜索的URL private HashMap<String, ArrayList<String>> disallowListCache = new HashMap<String, ArrayList<String>>(); ArrayList<String> errorList = new ArrayList<String>();// 错误信息 ArrayList<String> result = new ArrayList<String>(); // 搜索到的结果 String startUrl;// 开始搜索的起点 int maxUrl;// 最大处理的url数 String searchString;// 要搜索的字符串 boolean caseSensitive = false;// 是否区分大小写 boolean limitHost = false;// 是否在限制的主机内搜索 public SearchCrawler(String startUrl, int maxUrl, String searchString) { this.startUrl = startUrl; this.maxUrl = maxUrl; this.searchString = searchString; } public ArrayList<String> getResult() { return result; } public void run() {// 启动搜索线程 crawl(startUrl, maxUrl, searchString, limitHost, caseSensitive); } /** * 检测URL格式返回URL 类型的连接 * @param url * @return */ private URL verifyUrl(String url) { // 只处理HTTP URLs. if (!url.toLowerCase().startsWith("http://")){ return null; } URL verifiedUrl = null; try { verifiedUrl = new URL(url); } catch (Exception e) { return null; } return verifiedUrl; } /** * 检测URL.在robot文件中是否被允许抓取 * @param urlToCheck * @return */ private boolean isRobotAllowed(URL urlToCheck) { String host = urlToCheck.getHost().toLowerCase();// 获取给出RUL的主机 // 获取主机不允许搜索的URL缓存 ArrayList<String> disallowList = disallowListCache.get(host); // 如果还没有缓存,下载robots.txt并缓存。 if (disallowList == null) { disallowList = new ArrayList<String>(); try { URL robotsFileUrl = new URL("http://" + host + "/robots.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(robotsFileUrl.openStream())); // 读robot文件,创建不允许访问的路径列表。 String line; while ((line = reader.readLine()) != null) { if (line.indexOf("Disallow:") == 0) {//是否包含"Disallow:" String disallowPath = line.substring("Disallow:".length());// 获取不允许访问路径 // 检查是否有注释。 int commentIndex = disallowPath.indexOf("#"); if (commentIndex != -1) { disallowPath = disallowPath.substring(0,commentIndex);// 去掉注释 } disallowPath = disallowPath.trim(); disallowList.add(disallowPath); } } // 缓存此主机不允许访问的路径。 disallowListCache.put(host, disallowList); } catch (Exception e) { return true; // web站点根目录下没有robots.txt文件,返回真 } } String file = urlToCheck.getFile(); //如果是robots.txt中不允许抓取的连接,返回false for (int i = 0; i < disallowList.size(); i++) { String disallow = disallowList.get(i); if (file.startsWith(disallow)) { return false; } } return true; } /** * 下载url内容 * @param pageUrl * @return */ private String downloadPage(URL pageUrl) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(pageUrl.openStream(), "UTF-8")); String line; StringBuffer pageBuffer = new StringBuffer(); while ((line = reader.readLine()) != null) { pageBuffer.append(line); } return pageBuffer.toString(); } catch (Exception e) { } return null; } /** * 从URL中去掉"www" * @param url * @return */ private String removeWwwFromUrl(String url) { int index = url.indexOf("://www."); if (index != -1) { return url.substring(0, index + 3) + url.substring(index + 7); } return (url); } /** * 解析页面并找出链接 * @param pageUrl 连接地址 * @param pageContents 页面内容 * @param crawledList 已处理过的连接 * @param limitHost 是否在限制的主机内搜索 * @return */ private ArrayList<String> retrieveLinks(URL pageUrl, String pageContents,HashSet crawledList, boolean limitHost) { // 用正则表达式编译链接的匹配模式。 Pattern p = Pattern.compile("<a\\s+href\\s*=\\s*\"?(.*?)[\"|>]",Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(pageContents); ArrayList<String> linkList = new ArrayList<String>(); while (m.find()) { String link = m.group(1).trim(); if (link.length() < 1) { continue; } // 跳过链到本页面内链接。 if (link.charAt(0) == '#') { continue; } // 跳过邮件地址 if (link.indexOf("mailto:") != -1) { continue; } //跳过javascript连接 if (link.toLowerCase().indexOf("javascript") != -1) { continue; } if (link.indexOf("://") == -1) { if (link.charAt(0) == '/') {// 处理绝对地 link = "http://" + pageUrl.getHost() + ":" + pageUrl.getPort() + link; } else { String file = pageUrl.getFile(); if (file.indexOf('/') == -1) {// 处理相对地址 link = "http://" + pageUrl.getHost() + ":" + pageUrl.getPort() + "/" + link; } else { String path = file.substring(0,file.lastIndexOf('/') + 1); link = "http://" + pageUrl.getHost() + ":" + pageUrl.getPort() + path + link; } } } //去掉#后边的东西 int index = link.indexOf('#'); if (index != -1) { link = link.substring(0, index); } link = removeWwwFromUrl(link); URL verifiedLink = verifyUrl(link); if (verifiedLink == null) { continue; } /* 如果限定主机,排除那些不合条件的URL */ if (limitHost&& !pageUrl.getHost().toLowerCase().equals(verifiedLink.getHost().toLowerCase())) { continue; } // 跳过那些已经处理的链接. if (crawledList.contains(link)) { continue; } linkList.add(link); } return (linkList); } /** * 判断在该页面内有没有指定的搜索字符串 * @param pageContents 页面内容 * @param searchString 搜索字符串 * @param caseSensitive 是否去区分大小写 * @return */ private boolean searchStringMatches(String pageContents,String searchString, boolean caseSensitive) { pageContents = Html2Text(pageContents); String searchContents = pageContents; if (!caseSensitive) {// 如果不区分大小写 searchContents = pageContents.toLowerCase(); } Pattern p = Pattern.compile("[\\s]+"); String[] terms = p.split(searchString); for (int i = 0; i < terms.length; i++) { if (caseSensitive) { if (searchContents.indexOf(terms[i]) == -1) { return false; } } else { if (searchContents.indexOf(terms[i].toLowerCase()) == -1) { return false; } } } return true; } // 执行实际的搜索操作 public ArrayList<String> crawl(String startUrl, int maxUrls,String searchString, boolean limithost, boolean caseSensitive) { System.out.println("searchString=" + searchString); HashSet<String> crawledList = new HashSet<String>(); LinkedHashSet<String> toCrawlList = new LinkedHashSet<String>(); if (maxUrls < 1) { errorList.add("Invalid Max URLs value."); System.out.println("Invalid Max URLs value."); } if (searchString.length() < 1) { errorList.add("Missing Search String."); System.out.println("Missing search String"); } if (errorList.size() > 0) { System.out.println("err!!!"); return errorList; } // 从开始URL中移出www startUrl = removeWwwFromUrl(startUrl); toCrawlList.add(startUrl); while (toCrawlList.size() > 0) { if (maxUrls != -1) { if (crawledList.size() == maxUrls) { break; } } String url = toCrawlList.iterator().next(); toCrawlList.remove(url); URL verifiedUrl = verifyUrl(url); if (!isRobotAllowed(verifiedUrl)) { continue; } // 增加已处理的URL到crawledList crawledList.add(url); String pageContents = downloadPage(verifiedUrl); if (pageContents != null && pageContents.length() > 0) { // 从页面中获取有效的链接 ArrayList<String> links = retrieveLinks(verifiedUrl,pageContents, crawledList, limitHost); toCrawlList.addAll(links); if (searchStringMatches(pageContents, searchString,caseSensitive)) { result.add(url); System.out.println(url); } } } return result; } /** * 去掉html标签 */ public static String Html2Text(String inputString) { String htmlStr = inputString; // 含html标签的字符串 String textStr = ""; java.util.regex.Pattern p_script; java.util.regex.Matcher m_script; java.util.regex.Pattern p_style; java.util.regex.Matcher m_style; java.util.regex.Pattern p_html; java.util.regex.Matcher m_html; java.util.regex.Pattern p_html1; java.util.regex.Matcher m_html1; try { String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script> String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style> String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式 String regEx_html1 = "<[^>]+"; p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE); m_script = p_script.matcher(htmlStr); htmlStr = m_script.replaceAll(""); // 过滤script标签 p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE); m_style = p_style.matcher(htmlStr); htmlStr = m_style.replaceAll(""); // 过滤style标签 p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE); m_html = p_html.matcher(htmlStr); htmlStr = m_html.replaceAll(""); // 过滤html标签 p_html1 = Pattern.compile(regEx_html1, Pattern.CASE_INSENSITIVE); m_html1 = p_html1.matcher(htmlStr); htmlStr = m_html1.replaceAll(""); // 过滤html标签 textStr = htmlStr; } catch (Exception e) { System.err.println("Html2Text: " + e.getMessage()); } return textStr;// 返回文本字符串 } // 主函数 public static void main(String[] args) { String url = "http://www.nontrace.com"; int max = 20; String str = "无痕"; SearchCrawler crawler = new SearchCrawler(url, max, str); Thread search = new Thread(crawler); System.out.println("Start searching..."); System.out.println("result:"); search.start(); } }
试试其它关键字
爬虫程序
同语言下
.
List 切割成几份 工具类
.
一行一行读取txt的内容
.
Java PDF转换成图片并输出给前台展示
.
java 多线程框架
.
double类型如果小数点后为零则显示整数否则保留两位小
.
将图片转换为Base64字符串公共类抽取
.
sqlParser 处理SQL(增删改查) 替换schema 用于多租户
.
JAVA 月份中的第几周处理 1-7属于第一周 依次类推 29-
.
java计算两个经纬度之间的距离
.
输入时间参数计算年龄
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
文杰
贡献的其它代码
(
20
)
.
身份证验证与获取身份有用信息
.
mybatis模糊查询
.
使用DWZ.CN生成短网址
.
MapReduce实现共同朋友问题
.
检查一个字符是否在一段字符串中
.
IE6 Fixed
.
判断字符串是否能转换为数字
.
检查邮箱是否有新邮件+线程池
.
生成高品质小空间的缩略图
.
用图作提交按钮或超连接
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3