HtmlParser解析html页面中的数据

本文介绍如何使用HTTP客户端模拟登陆网站,并通过HTML解析器提取网页中的关键数据,包括表格数据、超级链接、页面总页数等信息,实现数据的自动化收集与入库。
上篇文章已经讲解了怎么使用httpClient模拟登陆并获取指定路径页面的内容,获取到页面内容后,我们就可以使用HtmlParser解析页面中对我们有用的数据供我们自己使用了。哈哈

1、解析html中table的数据保存到数据库中

//htmlStr为使用HttpClient获取到页面的内容,querySql为查询数据是否重复语句(使用hashcode),saveSql插入数据语句
public void parseData(String htmlStr,String querySql,String saveSql){
HashMap<String, Object> query = new HashMap<String, Object>();
// String htmlStr = robot.readTextFile(path, "UTF-8");
Parser myParser;
NodeList nodeList = null;
myParser = Parser.createParser(htmlStr,"UTF-8");
//获取table标签
NodeFilter tableFilter = new NodeClassFilter(TableTag.class);
OrFilter lastFilter = new OrFilter();
lastFilter.setPredicates(new NodeFilter[] { tableFilter });
try {
//html结构中所有的table集合
nodeList = myParser.parse(lastFilter);
StringBuffer hashStr = new StringBuffer();

for (int i = 0; i <= nodeList.size(); i++) {
if (nodeList.elementAt(i) instanceof TableTag) {
//获取html结构中表格的所有内容
TableTag tag = (TableTag) nodeList.elementAt(i);
if(tag.getAttribute("style") != null){
if(tag.getAttribute("style").equalsIgnoreCase("table-layout: fixed;")){
//获取表格中行集合
TableRow[] rows = tag.getRows();

//j=0 为第一行,j=1为第二行。从第二行开始循环,因为第一行为表头(一般情况是从第一行开始循环)
for (int j = 1; j < rows.length; j++) {
TableRow tr = (TableRow) rows[j];

//获取行中的列集合
TableColumn[] td = tr.getColumns();
for (int k = 0; k < td.length; k++) {
//列的数据顺序和页面上的数据顺序一致。如:content_url、content_ip、content_time
// logger.info(td[k].toPlainTextString().trim()+"\n");

hashStr.append(td[k].toPlainTextString().trim());

query.put("content_"+k, td[k].toPlainTextString().trim());
//如果有超级链接时,取出子路径
if(td[k].getChildrenHTML().indexOf("<a href") != -1){
Pattern p = Pattern.compile("<a[^<>]*?\\shref=['\"]?(.*?)['\"]?\\s.*?>");
Matcher m = p.matcher(td[k].getChildrenHTML().trim());
if(m.find()){
query.put("child_url", m.group(1));


//保存病毒详细信息
if(m.group(1).indexOf("vss_virus_report.action") != -1){
HashMap<String, Object> childquery = new HashMap<String, Object>();
String virus_name = m.group(1).split("=")[1];
//判断病毒详细信息中是否有重复的数据
if(!repeatData(virus_name.hashCode(),"alarm.ipmanage.virusdetails.repeatdata")){
childquery.put("tid", GenerateSerial.getUUID());
childquery.put("virus_name", virus_name);
childquery.put("hashcode", virus_name.hashCode());
String url = "http://124.238.214.79/platform/"+m.group(1).split("/")[1].replaceAll(" ", "%20");
childquery.put("content", robot.get(url));
service.saveObjects("alarm.ipmanage.savevirusdetails", childquery);
}
}

//域名挂马详细信息
if(m.group(1).indexOf("websiteSecurity.action") != -1){
String url = "http://124.238.214.79/platform/pages/"+m.group(1);
String htmlStrDetails = robot.get(url);
if(htmlStrDetails != ""){
this.parseDomainData(htmlStrDetails, "alarm.ipmanage.domaindetails.repeatdata", "alarm.ipmanage.savedomaindetails");
}
}


}
}
}

//判断数据中是否已有重复的数据
if(repeatData(hashStr.toString().hashCode(),querySql)){
//有重复数据跳出循环,不插入数据库
//清空值,继续判断下一行数据
hashStr.delete(0, hashStr.length());
continue;
}else{

query.put("tid", GenerateSerial.getUUID());
query.put("hashcode", hashStr.toString().hashCode());
//把采集的信息保存到数据库中
service.saveObjects(saveSql, query);
//清空值,继续判断下一行数据
hashStr.delete(0, hashStr.length());
}

}
}
}

}
}


} catch (Exception e) {
logger.info("------------->解析html文件失败!");
}
}



2、有时页面有好多页,需要知道总页数,然后循环解析数据并保存

public int getTotalPages(String htmlStr) {
// String htmlStr = robot.readTextFile(path, "UTF-8");
Parser myParser;
NodeList nodeList = null;
int totalPages = 0;
myParser = Parser.createParser(htmlStr,"UTF-8");
//获取input标签
NodeFilter inputFilter = new NodeClassFilter(InputTag.class);
OrFilter lastFilter = new OrFilter();
lastFilter.setPredicates(new NodeFilter[] { inputFilter });
try {
//html结构中所有input集合
nodeList = myParser.parse(lastFilter);

for (int i = 0; i <= nodeList.size(); i++) {

if(nodeList.elementAt(i) instanceof InputTag){
//获取html结构中input标签的所有内容
InputTag inputTag = (InputTag)nodeList.elementAt(i);

if(inputTag.getAttribute("id") != null){
if(inputTag.getAttribute("id").equalsIgnoreCase("total")){
// logger.info("-------------------------->"+inputTag.getAttribute("value"));
totalPages = Integer.parseInt(inputTag.getAttribute("value"));
}
}
}

}
} catch (Exception e) {
logger.info("------------------->解析总页数失败!");
}

return totalPages;

}



3、解析html中的超级链接

public void parseHref(String path,String querySql,String saveSql){

String htmlStr = robot.readTextFile(path, "UTF-8");
//没有<body>元素不能解析
htmlStr = "<body>"+htmlStr+"</body>";
// 创建Parser对象根据传给字符串和指定
Parser parser = Parser.createParser(htmlStr, "UTF-8");
// 创建HtmlPage对象HtmlPage(Parser parser)
HtmlPage page = new HtmlPage(parser);

try {
parser.visitAllNodesWith(page);
} catch (ParserException e) {
e.printStackTrace();
}

// 所有的节点
NodeList nodelist = page.getBody();
// 建立一个节点filter用于过滤节点
NodeFilter filter = new TagNameFilter("A");
// 得到所有过滤后,想要的节点
nodelist = nodelist.extractAllNodesThatMatch(filter, true);

for (int i = 0; i < nodelist.size(); i++) {
LinkTag link = (LinkTag) nodelist.elementAt(i);
// 链接地址
logger.info(link.getAttribute("href") + "\n");
// 链接名称
logger.info(link.getStringText());
}
}



4、采集数据,调用解析方法

//系统登录,采用HttpClient登录,登录之后才能采集
boolean logging = robot.login();
if(logging){
String wssHistoryUrl = "http://124.238.214.79/platform/pages/getWssHistory.action?startDate="+startDate+"&endDate="+endDate+"&pageContext.currentpage=1";
//根据路径采集url列表数据
String htmlStr1 = robot.get(wssHistoryUrl);
//先获取总页数
int wss = this.getTotalPages(htmlStr1);
for (int i = 0; i <= wss; i++) {
//解析采集到的数据,然后插入数据库
this.parseData(robot.getText2("http://124.238.214.79/platform/pages/getWssHistory.action?startDate="+startDate+"&endDate="+endDate+"&pageContext.currentpage="+i), "alarm.ipmanage.url.repeatdata", "alarm.ipmanage.saveurl");
}
}
### SAM模型概述 SAM(Segment Anything Model)是一种由Meta开发的通用分割模型,旨在解决图像中的任意目标分割问题。它通过学习一组可以泛化到新类别和场景的目标表示来实现这一目的[^1]。 #### 工作原理 SAM的核心理念在于其能够生成高质量的掩码(masks),这些掩码用于精确描述输入图像中特定区域的内容。具体来说: - **编码器部分**:SAM利用了一个强大的视觉Transformer作为骨干网络,该网络负责提取高层次特征并理解整个图像语义信息。 - **解码器部分**:基于来自编码器的信息以及用户的提示(prompts),如点击位置或者边界框等简单指示,解码器会生成最终所需的像素级精度的分割结果[^2]。 这种设计使得即使是在未见过的数据集上也能表现出色,因为模型已经学会了如何根据不同类型的提示去适应各种可能的任务需求。 #### 应用场景 由于其灵活性高效性,SAM适用于多个领域内的实际应用案例之中: 1. **医疗影像分析**:通过对医学扫描图片进行精准标注从而辅助医生诊断疾病状态; 2. **自动驾驶技术**:帮助车辆识别道路上行人、障碍物及其他重要元素以便做出安全决策; 3. **增强现实/虚拟现实环境构建**:允许开发者更方便快捷地创建交互式的三维空间体验产品原型。 以下是关于如何加载预训练权重的一个Python代码片段示例: ```python import torch from segment_anything import sam_model_registry, SamPredictor device = 'cuda' if torch.cuda.is_available() else 'cpu' sam_checkpoint = "path/to/sam_vit_h_4b8939.pth" model_type = "vit_h" sam = sam_model_registry[model_type](checkpoint=sam_checkpoint).to(device=device) predictor = SamPredictor(sam) image_path = "./example.jpg" input_image = cv2.imread(image_path) input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB) predictor.set_image(input_image) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值