package com.leo.web.parser.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
/**
* @date 2016年9月2日 08:43:22
* @author 刘宗洋
* @email 595324626@qq.com
*
*/
public class FileUtil {
/**
* 文档去重
*
* @param fileName
* @return
*/
public static List<String> readFile(String fileName) {
File file = new File(fileName);
BufferedReader reader = null;
HashSet<String> sets = new HashSet<String>();
try {
reader = new BufferedReader(new FileReader(file));
String tempString = null;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
sets.add(tempString);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
List<String> lines = new ArrayList<String>();
for (String line : sets) {
lines.add(line);
}
return lines;
}
/**
* 一次性读取文件所有内容
*
* @param fileName
* @return
*/
public static String readToString(String fileRealPath) {
String encoding = "UTF-8";
File file = new File(fileRealPath);
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
try {
FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
return new String(filecontent, encoding);
} catch (UnsupportedEncodingException e) {
System.err.println("The OS does not support " + encoding);
e.printStackTrace();
return null;
}
}
/**
* 导出文件
*
* @param content
* 字符串
* @param filePath
* 保存路径
*/
public static void output(String content, String filePath) {
FileOutputStream fop = null;
File file;
try {
file = new File(filePath);
fop = new FileOutputStream(file);
// if file doesnt exists, then create it
if (!file.exists()) {
file.mkdirs();
file.createNewFile();
}
// get the content in bytes
byte[] contentInBytes = content.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fop != null) {
fop.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 从外网下载文件
*
* @param httpUrl
* 字符串
* @param saveFile
* 保存路径
*/
public static boolean httpDownload(String saveFile, String httpUrl) {
// 下载网络文件
// int bytesum = 0;
int byteread = 0;
URL url = null;
try {
url = new URL(httpUrl);
} catch (MalformedURLException e1) {
e1.printStackTrace();
return false;
}
File f = new File(saveFile);
if (f.exists()) {
return false;
}
String path = saveFile.substring(0, saveFile.lastIndexOf("/") + 1);
FileUtil.createFile(path);
try {
URLConnection conn = url.openConnection();
InputStream inStream = conn.getInputStream();
FileOutputStream fs = new FileOutputStream(saveFile);
byte[] buffer = new byte[1204];
while ((byteread = inStream.read(buffer)) != -1) {
// bytesum += byteread;
fs.write(buffer, 0, byteread);
}
fs.close();
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 获取网页源代码
*
* @param pageUrl
* 网页url
* @param encoding
* 编码方式
* @return 源码
*/
public static String getPageSource(String pageUrl) {
StringBuffer sb = new StringBuffer();
try {
// 构建一URL对象
URL url = new URL(pageUrl);
// 使用openStream得到一输入流并由此构造一个BufferedReader对象
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
String line;
// 读取www资源
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
in.close();
} catch (Exception ex) {
System.err.println(ex);
}
return sb.toString().replace("\n", "");
}
/**
* 调用htmlparser方法返回网页源码
*
* @return
*/
public static String getParserHtml(String url) {
String str = "";
try {
Parser parser = new Parser();
URL url1 = new URL(url);
URLConnection conn = url1.openConnection();
conn.setConnectTimeout(500);
parser.setEncoding("UTF-8");
parser.setConnection(conn);
NodeList nodeList = parser.parse(null);
str = nodeList.toHtml();
} catch (Exception e1) {
// System.out.println("连接打不开!");
}
return str;
}
/**
* 创建文件夹
*
* @param path
*/
public static void createFile(String path) {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
}
/**
* 从URL网址获取源并把所有匹配到的a标签的链接保存到txt文件
*
* @param url
* 网址
* @param fileSavePath
* txt文件保存地址
* @param attributeName
* a标签属性名
* @param attributeValue
* a标签属性值
* @return 如果返回0 :没有匹配到数据
*/
public static Integer exportLinkToTXTFromHTTP(String url, String fileSavePath, String attributeName,
String attributeValue) {
try {
String inputHTML = getParserHtml(url);
List<LinkTag> tags = (List<LinkTag>) parseTags(inputHTML, LinkTag.class, attributeName, attributeValue);
if (tags.size() > 0) {
StringBuffer sb = new StringBuffer();
for (LinkTag linkTag : tags) {
sb.append(linkTag.getLink() + "\r\n");
}
String str = sb.toString();
FileUtil.output(str.substring(0, str.length() - 2), fileSavePath);
System.out.println("获取完毕!共" + tags.size() + "条");
return tags.size();
} else {
return 0;
}
} catch (Exception e) {
// TODO: handle exception
return 0;
}
}
/**
* 从本地获取源并把所有匹配到的a标签的链接保存到txt文件
*
* @param filePath
* 网址
* @param fileSavePath
* txt文件保存地址
* @param attributeName
* a标签属性名
* @param attributeValue
* a标签属性值
* @return 如果返回0 :没有匹配到数据
*/
public static Integer exportLinkToTXTFromLocalHost(String filePath, String fileSavePath, String attributeName,
String attributeValue) {
try {
String inputHTML = FileUtil.readToString(filePath);
List<LinkTag> tags = (List<LinkTag>) parseTags(inputHTML, LinkTag.class, attributeName, attributeValue);
if (tags.size() > 0) {
StringBuffer sb = new StringBuffer();
for (LinkTag linkTag : tags) {
sb.append(linkTag.getLink() + "\r\n");
}
String str = sb.toString();
FileUtil.output(str.substring(0, str.length() - 2), fileSavePath);
System.out.println("获取完毕!共" + tags.size() + "条");
return tags.size();
} else {
return 0;
}
} catch (Exception e) {
// TODO: handle exception
return 0;
}
}
/**
* 解析具有某类属性值的标签列表
*
* @see 定义泛型--><T extends TagNode>
* @see 使用泛型-->List <T>,Class <T>
* @see 这里定义了一个类型必须是某种TagNode的泛型T,并且返回的List也必须是泛型T
* @see 而Class<T>的意思是传给tagType的是什么类型,所以返回给List<T>的就是什么类型
* @see 比如传进来的是org.htmlparser.tags.MetaTag.class,那么返回的就是List<MetaTag>
* @param inputHTML
* 被解析的HTML文本
* @param tagType
* 标签的类型,内部类使用故final
* @param attributeName
* 待解析的属性名,内部类使用故final
* @param attributeValue
* 待解析的属性值,内部类使用故final
*/
@SuppressWarnings({ "unchecked", "serial" })
public static <T extends TagNode> List<T> parseTags(String inputHTML, final Class<T> tagType,
final String attributeName, final String attributeValue) {
// 创建一个HTML解析器
Parser parser = new Parser();
NodeList tagList = null;
try {
parser.setInputHTML(inputHTML);
// 它会自动检测文件内部<meta http-equiv="Content-Type" content="text/html;
// charset=UTF-8"/>
// parser.setEncoding("UTF-8");
NodeFilter nodeFilter = new NodeFilter() {
@Override
public boolean accept(Node node) {
// 这里不需要if(node instanceof TagNode),因为上面已经定义了TagNode类型的泛型T
if (node.getClass() == tagType) {
// Node类型的实现类中只有TagNode才能getAttribute()获取属性值,所以要将之打回原形
T t = (T) node;
// 若传入的属性名是null,则认为是不需要查找指定属性值的标签,而是单纯的查找某类型T的标签
// if(null == attributeName){
// return true;
// }
if (null != attributeValue && attributeValue.equals(t.getAttribute(attributeName))) {
return true;
}
}
return false;
}
};
tagList = parser.extractAllNodesThatMatch(nodeFilter);
} catch (ParserException e) {
System.out.println("解析HTML文本时发生异常:" + e.getMessage());
}
// 过滤重复tag
HashSet<T> tagSets = new HashSet<T>();
for (int i = 0; i < tagList.size(); i++) {
T t = (T) tagList.elementAt(i); // 提取真实tag
tagSets.add(t);
}
List<T> tags = new ArrayList<T>();
for (T t : tagSets) {
tags.add(t);
}
return tags;
}
/**
* 解析属性值唯一的标签
*
* @see 和上面那个方法差不多,传给Class<T>的是什么类型,那么返回的就是什么类型
*/
public static <T extends TagNode> T parseTag(String inputHTML, final Class<T> tagType, final String attributeName,
final String attributeValue) {
List<T> tagList = parseTags(inputHTML, tagType, attributeName, attributeValue);
if (null != tagList && tagList.size() > 0) {
return tagList.get(0);
} else {
return null;
}
}
/**
* @param url
* @param encoding
* @return
*/
public static String checkURL(String url, String encoding) {
String str = "";
try {
Parser parser = new Parser();
URL url1 = new URL(url);
URLConnection conn = url1.openConnection();
conn.setConnectTimeout(500);
parser.setEncoding("UTF-8");
parser.setConnection(conn);
NodeList nodeList = parser.parse(null);
str = nodeList.toHtml();
} catch (Exception e1) {
System.out.println("连接打不开!");
}
return str;
}
/**
* 通过正则提取字符串中的项目 返回list
*
* @param str
* @param keywords
* @return
*/
public static List<String> getList(String str, String keywords) {
HashSet<String> set = new HashSet<String>();
Pattern pattern = Pattern.compile(keywords);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
set.add(matcher.group());
}
List<String> list = new ArrayList<String>();
list.addAll(set);
return list;
}
/**
* 复制单个文件
*
* @param oldFile
* :File
* @param newPath
* :String 文件路径
*/
public static void copyFile(File oldFile, String newPath) {
File file = new File(newPath.substring(0,newPath.length()-21));
if(!file.exists()){
file.mkdirs();
}
// Long starttime = System.currentTimeMillis();
InputStream inStream = null;
FileOutputStream fout = null;
try {
@SuppressWarnings("unused")
int bytesum = 0;
int byteread = 0;
if (oldFile.exists()) { // 文件存在时
inStream = new FileInputStream(oldFile); // 读入原文件
fout = new FileOutputStream(newPath);
byte[] buffer = new byte[1024];
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread; // 字节数 文件大小
fout.write(buffer, 0, byteread);
}
fout.flush();
}
} catch (Exception e) {
// System.out.println("复制文件【" + oldFile.getAbsolutePath() +
// "】时出错!");
e.printStackTrace();
} finally {
try {
// 关闭输入流
if (inStream != null) {
inStream.close();
}
// 关闭输出流
if (fout != null) {
fout.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Long endtime = System.currentTimeMillis();
// System.out.println("复制【" + oldFile.getAbsolutePath() + " 】用时【" +
// (endtime - starttime) + "】毫秒!");
}
/**
* 删除多个文件
*
* @param filePaths
* 文件路径数组
*/
public static void deleteFiles(String[] filePaths) {
for (int i = 0; i < filePaths.length; i++) {
File file = new File(filePaths[i]);
if (file.exists()) {
file.delete();
}
}
}
/**
* 分割list成指定的份数
* @param list
* @param count 制定分割成几份
* @return
*/
public static Map<Integer, List<String>> cutList(List<String> list,Integer count) {
Map<Integer, List<String>> listMap = new HashMap<Integer,List<String>>();
for (int i = 1; i <= count; i++) {
Integer counter = list.size() / count;
listMap.put(i, list.subList((i - 1) * counter, counter * i));
}
Integer countAdd = list.size() % count;
if (countAdd > 0) {
listMap.put(count+1, list.subList(list.size() - countAdd, list.size()));
}
return listMap;
}
}
网络爬虫简单功能工具类
最新推荐文章于 2023-06-18 14:54:07 发布