上篇文章基于html字符串截取模式的爬虫,在实际使用过程中存在较大的使用限制,为此简单研究了下基于jsoup模式的爬虫,相对于字符串截取,在实用性上也有很大的优势。
梳理了下jsoup获取指定数据的大概流程如下:
- 通过网址URL得到html源码信息
- 将源码转义为对象类型
- 通过获取其中的node节点集合,进行指定数据的解析获取
- 将所需数据封装返回即可。
以下是根据梳理的流程进行的对应编码信息
/**
* 根据网址解析指定数据并返回结果
* @param url 要请求的网址
* @param mark 要获取的数据解析条件
* @return
* @throws IOException
*/
public static List<HtmlFilterResponse> getHtmlValueListFromUrl(String url, HtmlFilterRequest mark) throws IOException {
//获得一个和网站的链接,注意是Jsoup的connect
Connection connect = Jsoup.connect(url);
//获得该网站的Document对象
Document document = connect.get();
return getDataFromDocument(document, mark);
}
其中getDataFromDocument方法是获取指定数据的方法,HtmlFilterRequest和HtmlFilterResponse分别代表入参和出参,两者代码如下:
@Data
public class HtmlFilterRequest {
/**
* 要筛选的全部数据范围key定义
* 示例:.book-img-text ul li
*/
private String elementsTagRangeKey;
/**
* 要筛选的数据范围key定义
* 示例:.book-mid-info h2 a
*/
private String textTagRangeKey;
/**
* 筛选对应标签的第一个值key定义
* 示例:.total p,筛选出 总字数 信息
*/
private String textTagRangeFirstKey;
/**
* 筛选对应标签的最后一个值key定义
* 示例:.total p,筛选出 总推荐 信息
*/
private String textTagRangeLastKey;
/**
* 多属性部分的配置
*/
private List<TagAttrRange> multiTagAttrRangeList;
/**
* 筛选对应标签下的html信息
*/
private String htmlTagRangeKey;
/**
* 要筛选的数据范围key定义-结果数据前缀
* 示例:.book-mid-info h2 a
*/
private String preTextTag;
/**
* 筛选对应标签的第一个值key定义-结果数据前缀
* 示例:.total p,筛选出 总字数 信息
*/
private String preTextTagFirst;
/**
* 筛选对应标签的最后一个值key定义-结果数据前缀
* 示例:.total p,筛选出 总推荐 信息
*/
private String preTextTagLast;
/**
* 筛选对应标签下的html信息-结果数据前缀
*/
private String preHtmlTag;
/**
* 要筛选的数据范围key定义-结果数据后缀
* 示例:.book-mid-info h2 a
*/
private String sufTextTag;
/**
* 筛选对应标签的第一个值key定义-结果数据后缀
* 示例:.total p,筛选出 总字数 信息
*/
private String sufTextTagFirst;
/**
* 筛选对应标签的最后一个值key定义-结果数据后缀
* 示例:.total p,筛选出 总推荐 信息
*/
private String sufTextTagLast;
/**
* 筛选对应标签下的html信息-结果数据后缀
*/
private String sufHtmlTag;
}
@Data
public class TagAttrRange {
/**
* 要定位的标签位置
* 示例:.book-mid-info h2 a【class=book-mid-info下的h2标签里面的a标签】
*/
private String tagRangeKey;
/**
* 要筛选的属性
* 配套tagRangeKey示例:title【class=book-mid-info下的h2标签里面的a标签里面的title属性值】
*/
private String tagRangeAttrKey;
/**
* 取值结果的前缀内容
*/
private String preTagAttrVal;
/**
* 取值结果的后缀内容
*/
private String sufTagAttrVal;
/**
* 取值类型
*/
private HtmlValueTypeEnum hvtEnum;
}
public enum HtmlValueTypeEnum {
/**
* 文本
*/
TEXT,
/**
* 第一个值
*/
FIRST_TEXT,
/**
* 最后一个值
*/
LAST_TEXT,
/**
* html信息
*/
HTML,
/**
* 标签属性值
*/
ATTR_VALUE
}
@Data
public class HtmlFilterResponse {
/**
* 将html内容以文本格式显示,并保持原格式
*/
private String rootPlainText;
/**
* 获得标签里面的文本内容
* 示例:<a><span>123</span></a>
* 假设获取a标签下的文本&