package com;
/*
以下是一个Java爬虫程序,它能从指定主页开始,按照指定的深度抓取该站点域名下的网页并维护简单索引。
参数:private static int webDepth = 2;//爬虫深度。主页的深度为1,设置深度后超过该深度的网页不会抓取。
private int intThreadNum = 10;//线程数。开启的线程数。
抓取时也会在程序源文件目录下生成一个report.txt文件记录爬虫的运行情况,并在抓取结束后生成一个fileindex.txt
文件维护网页文件索引。
本程序用到了多线程(静态变量和同步),泛型,文件操作,URL类和连接,Hashtable类关联数组,正则表达式及其相关类。
运行时需使用命令行参数,第一个参数应使用http://开头的有效URL字符串作为爬虫的主页,第二个参数(可选)
应输入可转换为int型的字符串(用Integer.parseInt(String s)静态方法可以转换的字符串,如3)作为爬虫深度,
如果没有,则默认深度为2。
本程序的不足之处是:只考虑了href= href=' href="后加绝对url的这三种情况(由于url地址在网页源文件中情况比
较复杂,有时处理也会出现错误),还有相对url和window.open('的情况没有考虑。异常处理程序也只是简单处理。
附上源代码如下(保存名为GetWeb.java):
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GetWeb {
private int webDepth = 2;// 爬虫深度
private int intThreadNum = 10;// 线程数
private String strHomePage = "";// 主页地址
private String myDomain;// 域名
private String fPath = "web";// 储存网页文件的目录名
private ArrayList<String> arrUrls = new ArrayList<String>();// 存储未处理URL
private ArrayList<String> arrUrl = new ArrayList<String>();// 存储所有URL供建立索引
private Hashtable<String, Integer> allUrls = new Hashtable<String, Integer>();// 存储所有URL的网页号
private Hashtable<String, Integer> deepUrls = new Hashtable<String, Integer>();// 存储所有URL深度
private int intWebIndex = 0;// 网页对应文件下标,从0开始
private String charset = "GB2312";
private String report = "";
private long startTime;
private int webSuccessed = 0;
private int webFailed = 0;
public GetWeb(String s) {
this.strHomePage = s;
}
public GetWeb(String s, int i) {
this.strHomePage = s;
this.webDepth = i;
}
public synchronized void addWebSuccessed() {
webSuccessed++;
}
public synchronized void addWebFailed() {
webFailed++;
}
public synchronized void addReport(String s) {
try {
report += s;
PrintWriter pwReport = new PrintWriter(new FileOutputStream(
"report.txt"));
pwReport.println(report);
pwReport.close();
} catch (Exception e) {
System.out.println("生成报告文件失败!");
}
}
public synchronized String getAUrl() {
String tmpAUrl = arrUrls.get(0);
arrUrls.remove(0);
return tmpAUrl;
}
public synchronized String getUrl() {
String tmpUrl = arrUrl.get(0);
arrUrl.remove(0);
return tmpUrl;
}
public synchronized Integer getIntWebIndex() {
intWebIndex++;
return intWebIndex;
}
/**
* @param args
*/
public static void main(String[] args) {
/*if (args.length == 0 || args[0].equals("")) {
System.out.println("No input!");
System.exit(1);
} else if (args.length == 1) {
GetWeb gw = new GetWeb(args[0]);
gw.getWebByHomePage();
} else {
GetWeb gw = new GetWeb(args[0], Integer.parseInt(args[1]));
gw.getWebByHomePage();
}*/
Scanner cin=new Scanner(System.in);
String url = cin.next();
int webDepth = cin.nextInt();
GetWeb gw = new GetWeb(url, webDepth);
gw.getWebByHomePage();
}
public void getWebByHomePage() {
startTime = System.currentTimeMillis();
this.myDomain = getDomain();
if (myDomain == null) {
System.out.println("Wrong input!");
// System.exit(1);
return;
}
System.out.println("Homepage = " + strHomePage);
addReport("Homepage = " + strHomePage + "!\n");
System.out.println("Domain = " + myDomain);
addReport("Domain = " + myDomain + "!\n");
arrUrls.add(strHomePage);
arrUrl.add(strHomePage);
allUrls.put(strHomePage, 0);
deepUrls.put(strHomePage, 1);
File fDir = new File(fPath);
if (!fDir.exists()) {
fDir.mkdir();
}
System.out.println("Start!");
this.addReport("Start!\n");
String tmp = getAUrl();
this.getWebByUrl(tmp, charset, allUrls.get(tmp) + "");
int i = 0;
for (i = 0; i < intThreadNum; i++) {
new Thread(new Processer(this)).start();
}
while (true) {
if (arrUrls.isEmpty() && Thread.activeCount() == 1) {
long finishTime = System.currentTimeMillis();
long costTime = finishTime - startTime;
System.out.println("\n\n\n\n\nFinished!");
addReport("\n\n\n\n\nFinished!\n");
System.out.println("Start time = " + startTime + " "
+ "Finish time = " + finishTime + " "
+ "Cost time = " + costTime + "ms");
addReport("Start time = " + startTime + " "
+ "Finish time = " + finishTime + " "
+ "Cost time = " + costTime + "ms" + "\n");
System.out.println("Total url number = "
+ (webSuccessed + webFailed) + " Successed: "
+ webSuccessed + " Failed: " + webFailed);
addReport("Total url number = " + (webSuccessed + webFailed)
+ " Successed: " + webSuccessed + " Failed: "
+ webFailed + "\n");
String strIndex = "";
String tmpUrl = "";
while (!arrUrl.isEmpty()) {
tmpUrl = getUrl();
strIndex += "Web depth:" + deepUrls.get(tmpUrl)
+ " Filepath: " + fPath + "/web"
+ allUrls.get(tmpUrl) + ".htm" + " url:" + tmpUrl
+ "\n\n";
}
System.out.println(strIndex);
try {
PrintWriter pwIndex = new PrintWriter(new FileOutputStream(
"fileindex.txt"));
pwIndex.println(strIndex);
pwIndex.close();
} catch (Exception e) {
System.out.println("生成索引文件失败!");
}
break;
}
}
}
public void getWebByUrl(String strUrl, String charset, String fileIndex) {
try {
// if(charset==null||"".equals(charset))charset="utf-8";
System.out.println("Getting web by url: " + strUrl);
addReport("Getting web by url: " + strUrl + "\n");
URL url = new URL(strUrl);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
InputStream is = null;
is = url.openStream();
String filePath = fPath + "/web" + fileIndex + ".htm";
PrintWriter pw = null;
FileOutputStream fos = new FileOutputStream(filePath);
OutputStreamWriter writer = new OutputStreamWriter(fos);
pw = new PrintWriter(writer);
BufferedReader bReader = new BufferedReader(new InputStreamReader(
is));
StringBuffer sb = new StringBuffer();
String rLine = null;
String tmp_rLine = null;
while ((rLine = bReader.readLine()) != null) {
tmp_rLine = rLine;
int str_len = tmp_rLine.length();
if (str_len > 0) {
sb.append("\n" + tmp_rLine);
pw.println(tmp_rLine);
pw.flush();
if (deepUrls.get(strUrl) < webDepth)
getUrlByString(tmp_rLine, strUrl);
}
tmp_rLine = null;
}
is.close();
pw.close();
System.out.println("Get web successfully! " + strUrl);
addReport("Get web successfully! " + strUrl + "\n");
addWebSuccessed();
} catch (Exception e) {
System.out.println("Get web failed! " + strUrl);
addReport("Get web failed! " + strUrl + "\n");
addWebFailed();
}
}
public String getDomain() {
String reg = "(?<=http\\://[a-zA-Z0-9]{0,100}[.]{0,1})[^.\\s]*?\\.(com|cn|net|org|biz|info|cc|tv)";
Pattern p = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(strHomePage);
boolean blnp = m.find();
if (blnp == true) {
return m.group(0);
}
return null;
}
public void getUrlByString(String inputArgs, String strUrl) {
String tmpStr = inputArgs;
String regUrl = "(?<=(href=)[\"]?[\']?)[http://][^\\s\"\'\\?]*("
+ myDomain + ")[^\\s\"\'>]*";
Pattern p = Pattern.compile(regUrl, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(tmpStr);
boolean blnp = m.find();
// int i = 0;
while (blnp == true) {
if (!allUrls.containsKey(m.group(0))) {
System.out.println("Find a new url,depth:"
+ (deepUrls.get(strUrl) + 1) + " " + m.group(0));
addReport("Find a new url,depth:" + (deepUrls.get(strUrl) + 1)
+ " " + m.group(0) + "\n");
arrUrls.add(m.group(0));
arrUrl.add(m.group(0));
allUrls.put(m.group(0), getIntWebIndex());
deepUrls.put(m.group(0), (deepUrls.get(strUrl) + 1));
}
tmpStr = tmpStr.substring(m.end(), tmpStr.length());
m = p.matcher(tmpStr);
blnp = m.find();
}
}
class Processer implements Runnable {
GetWeb gw;
public Processer(GetWeb g) {
this.gw = g;
}
public void run() {
// Thread.sleep(5000);
while (!arrUrls.isEmpty()) {
String tmp = getAUrl();
getWebByUrl(tmp, charset, allUrls.get(tmp) + "");
}
}
}
}
转载至:http://hi.baidu.com/yxh265/blog/item/27820203ece6d4074bfb51a1.html
分享到:
相关推荐
2. **制作高质量的Sitemap**:Sitemap是一个列出网站所有页面的XML文件,便于搜索引擎了解网站结构。创建并提交Sitemap可以加速搜索引擎对网站内容的抓取。 3. **优化网站内容**:内容是王道。确保你的网站提供独特...
手撕包菜一开始只是为了纯粹的技术研究,没有去想这个搜索引擎能给网民带来什么样的福利。当时采集了大量的数据,发现有一半以上的资源为限级内容,于是试图去对资源进行分类并且做了很多这方面的工作。譬如,基本...
- 爬虫协议(robots.txt)是一个网站用以通知搜索引擎哪些页面可以被抓取,哪些不可以的标准。 - 查看爬虫协议的方法是在网站根目录下访问/robots.txt。 - User-agent指的是搜索引擎种类,而disallow指令指明了...
- **目标**:确保网站结构清晰、导航便捷,有助于搜索引擎爬虫抓取所有重要页面。 - **实现方法**: - 建立网站地图(sitemap),提交至搜索引擎,帮助快速索引。 - 使用面包屑导航,提升用户体验。 - 减少死链,...
Heritrix的设计初衷是为了满足大规模网页归档的需求,但因其灵活的架构和丰富的API,也被广泛应用于数据挖掘、搜索引擎优化等领域。 #### 二、Heritrix下载、安装与配置 ##### 2.1 下载 - **下载地址**: 通常可以从...
了解和跟踪这些爬虫的行为对优化网站的可见性和搜索引擎表现至关重要。 【描述】:“亲测源码 可商用运营”表明这个压缩包包含的源代码是经过测试的,可以用于商业运营。这意味着源代码是可靠的,并且经过了实际...
网络爬虫技术是搜索引擎的核心组成部分,它能自动发现、下载并存储网络内容。在山东建筑大学的课程设计中,学生将面临一个具体的任务:从一个起始网页开始,利用网络爬虫程序以广度优先的策略抓取相关网页的标题和...
本项目旨在设计并开发一个简单的搜索引擎,该搜索引擎能够实现基本的全文检索功能。用户可以在特定的网页上输入关键词查询所需信息,搜索引擎则会返回相关的网页链接及其内容摘要。此外,用户还可以直接点击链接访问...
对于初次接触advertools的开发者来说,这是一个非常重要的资源,可以帮助他们快速上手并了解库的各种功能。 advertools库的核心功能包括: 1. **广告平台数据解析**:它可以解析Google AdWords和AdSense的报告,使...
- 自动生成XML网站地图,方便搜索引擎爬虫抓取网站内容。 - robots.txt编辑器,控制搜索引擎对网站的索引策略,避免无效或敏感页面被抓取。 5. **搜索查询优化**: - 搜索分析:跟踪和分析用户的搜索行为,识别...
- 包括向搜索引擎爬虫提交以及向分类目录提交,从而提高网站被搜索引擎收录的可能性。 通过综合运用上述策略,可以有效地提升网站的知名度和访问量,最终实现将访问者转化为忠实客户的终极目标。
采用清晰的网站结构,如扁平化的物理结构,便于搜索引擎爬虫的索引。 其次,网站内容的构建需注重可读性和相关性。百度蜘蛛就像普通用户一样,无法解析Flash和图片中的信息,因此应以文字为主。每个页面都应该至少...
它通常包含网站上所有页面的链接,使搜索引擎爬虫可以快速找到并抓取这些页面。"sitemap 网站地图工具"是一个专门用于生成网站地图的程序,能够自动化地整理和创建XML或者HTML格式的网站地图文件。 XML网站地图主要...
它通常包含了网站上所有页面的链接,使得搜索引擎的爬虫能够快速找到并抓取这些页面,从而提高网站的搜索引擎优化(SEO)效果。"网站地图生成工具"就是专门用于自动化这一过程的软件或在线服务。 该描述提到的“SEO...
- **搜索引擎友好**:软件应考虑搜索引擎的爬虫算法,生成的标题需包含利于SEO的元素,如关键词位置、标题长度等。 - **测试与调整**:使用软件生成的标题可能需要经过多次测试和微调,以找到最佳的标题组合,提高...
通过这个工具,用户可以轻松获取关于搜索引擎爬虫活动的详细报告,包括但不限于关键词分析、爬虫访问频率、抓取深度、页面停留时间等。此外,它还能提供关于网站性能的见解,如页面加载速度、URL结构和内部链接健康...
- 建立内部链接结构,引导搜索引擎爬虫更好地抓取网站内容。 6. **博客运营与维护** - 定期更新内容,保持网站活跃度。 - 互动与回应读者评论,建立社区氛围。 - 监控网站性能,优化加载速度和用户体验。 总之...