本文迁移自老博客,原始链接为 https://seven.blog.ustc.edu.cn/%e7%bd%91%e9%a1%b5%e5%86%85%e5%ae%b9%e7%9a%84%e8%a7%a3%e6%9e%90/
在使用heritrix爬虫抓取网页时,在工程目录下自动生成“jobs”文件夹,包含本次抓取任务。抓取下来网页以镜像方式存放,也就是将 URL 地址按“/”进行切分,进而按切分出来的层次存储。 爬取结束后,结果存放在工作目录下。如图:
如果想对抓取的内容进行处理并建立索引,需要解析这些文件中的html文件获取信息来进行索引,htmlparser就是专门用来进行解析网页内容的工具包。递归的对各文件进行解析,对每个文件夹下的html进行解析,提取出有用信息,然后存储到XML文件中,以供将来进行索引和搜索。使用了如下的方式递归的遍历文件夹,并使用readTextAndTitle方法提取文件标题和文本内容,然后对获取的字符串进行处理后后存到xml文件里。示例代码如下:
public class HTMLParserTest {
private static ArrayList<String> filelist = new ArrayList<String>();
static String filePath;
static String name;
static void getFiles(String filePath) {
File root = new File(filePath);
File[] files = root.listFiles();
for (File file : files) {
if (file.isDirectory()) {
//递归调用
getFiles(file.getAbsolutePath());
filelist.add(file.getAbsolutePath());
File directory = new File(file.getAbsolutePath());
File[] htmlFiles = directory.listFiles(new FileNameSelector(
"html"));
for (File file1 : htmlFiles) {
name = file.getAbsolutePath() + "/" + file1.getName();
String path = file.getAbsolutePath() + "/"
+ file1.getName();
StringBuffer sbStr = new StringBuffer();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(new File(path)));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
String temp = "";
try {
while ((temp = reader.readLine()) != null) {
sbStr.append(temp);
sbStr.append("");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
String result = sbStr.toString();
// readAll(result);
// readByHtml(result);
try {
readTextAndTitle(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String args[]) throws Exception {
filePath = "F:/workspace/MyHeritrix/jobs/sdufe-20130414121132012/mirror";
getFiles(filePath);
}
// 读取文本内容和标题
public static void readTextAndTitle(String result) throws Exception {
resourceAdd add = new resourceAdd();
Parser parser;
NodeList nodelist;
parser = Parser.createParser(result, "GB2312");
NodeFilter textFilter = new NodeClassFilter(TextNode.class);
NodeFilter titleFilter = new NodeClassFilter(TitleTag.class);
OrFilter lastFilter = new OrFilter();
lastFilter.setPredicates(new NodeFilter[] { textFilter, titleFilter });
nodelist = parser.parse(lastFilter);
Node[] nodes = nodelist.toNodeArray();
String line = "暂无内容";
Node node;
String[] tmp = new String[9];
int q = 0;
int num = 0;
for (int i = 0; i < nodes.length && i < 9; i++) {
node = nodes[i];
if (node instanceof TextNode) {
TextNode textnode = (TextNode) node;
line = textnode.getText();
} else if (node instanceof TitleTag) {
TitleTag titlenode = (TitleTag) node;
line = titlenode.getTitle();
}
if (isTrimEmpty(line))
continue;
System.out.println(line);
if (line.isEmpty())
continue;
else
num++;
if (line.length() > 10)
line = line.substring(0, 9);
tmp[q++] = line;
}
if (num < 8)
return;
else {
tmp[5] = "2013-04-18";
tmp[2] = "html";
tmp[7] = "duyimin";
tmp[8] = "暂无";
tmp[0] = "1000";
String a = "http://192.168.0.9:8080/resources/"
+ name.substring(53);
char[] b = new char[100];
b = a.toCharArray();
for (int i = 0; i < a.length(); i++) {
if (b[i] == '\\')
b[i] = '/';
}
tmp[6] = String.valueOf(b);
add.xmldb(tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6],
tmp[7], tmp[8]); //将数据存储到xml数据文件,供以后索引使用
}
}
//去掉左右空格后字符串是否为空
public static boolean isTrimEmpty(String astr) {
if ((null == astr) || (astr.length() == 0)) {
return true;
}
if (isBlank(astr.trim())) {
return true;
}
return false;
}
//字符串是否为空:null或者长度为0.
public static boolean isBlank(String astr) {
if ((null == astr) || (astr.length() == 0)) {
return true;
} else {
return false;
}
}
}
由于Heritrix是把爬取的内容照单全收,力求保存页面原貌,但是不会自动建立索引,所以我们才需要用如上述的方式对抓取的网页手动处理,这方面Nutch做的较好,Nutch只获取并保存可索引的内容,他是一个完整的搜索框架,包含了抓取和搜索的全过程,并有基于hadoop的分布式框架类似eclipse的插件机制,易于集成到自己的应用中。