我正在使用 jsoup 进行 HTML 表格解析。下面是我必须识别正确段的场景。识别正确段的过程是:
无论我在哪里找到关键字-> ABC,我都必须迭代直到获得<tr>
HTML 标记(用于表识别),然后检查它是否包含所有 4 个关键字ForVote、AgainstVote、Absent、NoVotes第一行(如果没有,则转到下一次出现的关键字-> ABC)并遵循相同的过程。一旦我得到匹配表内的 4 个投票关键字,我就可以提取表中的数字。
我遇到的问题是:如果关键字ABC只出现一次,我可以解析。但是当ABC 不止一次出现导致解析错误的段时,就无法做到这一点
我要解析的示例 HTML 代码是:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Correct segment to be identified for parsing table </title>
</head>
<body>
<div>ABC Keyword</div>
<!--First Occurrence of Keyword(Not a correct segment as the table below doesn't have the correct headers)-->
<div> asd xyz asdf</div>
</br>
<table border="1px">
<tbody>
<tr>
<td>For Vote</td>
<td>Against Vote</td>
<td>Some Header1</td>
<td>Some Header2</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>
<div>
<p>Another 'ABC' is the keyword in the document</p>
<!--2nd Occurence, but not correct segment-->
</div>
<div> asd xyz jskadl</div>
</br>
<div> ABC is keyword </div>
<!-- 3rd Occurrence, this is the correct segment below which the required table with keywords ForVote, AgainstVote, Absent, NoVotes are found whose values are to be parsed-->
</br>undefined</br>undefined<div>
<table border="1px">
<tbody>
<tr>
<td>ForVote</td>
<td>AgainstVote</td>
<td>Absent</td>
<td>NoVotes</td>
</tr>
<tr>
<td>10</td>
<td>5</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
</div>
<p>Doc ends</p>
</body>
</html>
Java 代码
我的逻辑是迭代直到找到 ABC。找到包含 ABC 的元素,为其添加一个 class=tagid。选择(div.tagid)。然后找到<tr>
标签。查找表格是否为预期格式,即代码中的 isVertical=0。然后检查第一行中是否存在所有四个关键字。如果是,则解析数值。在多次出现“ABC”的情况下不起作用:-(
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final static String regexPattern1 = "ABC";
final static String tableregexPattern1 = "ForVotes";
final static Pattern tPat1 = Pattern.compile(tableregexPattern1);
//a function for finding occurrence of ABC
public static Element htmlIterator(String HTMLTags, String regexPattern) throws IOException {
pattern = Pattern.compile(regexPattern1, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);// compiles the matching regex
for (String tag : HTMLTags) {
Elements tagData = doc.select("div");
for (Element element1 : tagData) {
if (element1.select("div").text().trim().equals("")) {
continue;
} else {
final String dataParsedInTag = element1.select("div").text().trim();
final String dataParsedInTagClean = dataParsedInTag.replace(",", "");
final Matcher matcher = pattern.matcher(dataParsedInTagClean);
b1 = matcher.find();
if (b1) {
System.out.println(b1 + " matched");
return element1;
}
}
}
}
public static void main{
doc=Jsoup.parseHTML(input); //input is above given HTML snippet
element1 = htmlIterator(div, regexPattern1);// returns the element which has "ABC"
Elements ele = element1.getElementsMatchingText(pattern);
if(ele != null) {
Elements manipulatedElement = ele.addClass(tagid);//attach class= tagid to the identified div
//iterate till I get <tr>
while (true) {
resultTableHTML = doc.selectFirst(div+"."+tagid).nextElementSibling();
resultTableInChar = doc.selectFirst(div+"."+tagid).nextElementSibling().toString();
nextResultTable = doc.selectFirst(div+"."+tagid).nextElementSibling();
// System.out.println(resultTableInChar);
while (!resultTableInChar.contains("tr")) {
resultTableInChar = nextResultTable.nextElementSibling().toString();
nextResultTable = nextResultTable.nextElementSibling();// for continuous iteration
System.out.println("-->Iterating" + nextResultTable);
}
break;
}
//check if the table is having the keyword ForVotes and is int the expected tabular format that is an isVertical=0
Elements rows = nextResultTable.select("tr");// just select the rows and check if its empty or not
for (Element rowElement : rows) {
Matcher mat1 = tPat1.matcher(rowElement.text());
boolean isTablewithFirstHeaderKeyword = mat1.find();
if (!(rowElement.text().isEmpty()) && (isTablewithFirstHeaderKeyword) ) {
String tmpLines[] = rowElement.text().trim().replaceAll(",", "").split(" ");
String tmpRowElement = rowElement.text().trim().replaceAll(",", "");
Matcher mat5 = tPat5.matcher(tmpRowElement);
boolean typeVerticaldetected = mat5.find();//for detecting the numerical values
if (typeVerticaldetected) {
isVertical = 1;
break;
} else {
isVertical = 0;
break;
}
}
}
if (isVertical == 0) {
System.out.println("Horizontal Table Identified. Start Parsing.....");
rows = nextResultTable.select("tr");
for (Element rowElement : rows) {
//if row isn't empty then find all 4 keywords
if (!rowElement.text().isEmpty()) {
Matcher mat1 = tPat1.matcher( rowElement.toString());//tpat1 is regex for ForVotes inside table row, CAN use contains for now
Matcher mat2 = tPat2.matcher( rowElement.toString());//tpat2 is regex for AgainstVotes inside table row
Matcher mat3 = tPat3.matcher( rowElement.toString());//tpat3 is regex for Absent inside table row
Matcher mat4 = tPat4.matcher( rowElement.toString());//tpat4 is regex for NoVotes inside table row
boolean hasTableHeaderKeywords = mat1.find() && mat2.find() && mat3.find() && mat4.find();
System.out.println(mat1.find()+";"+mat2.find()+";"+mat3.find()+";"+mat4.find()+";");
if(hasTableHeaderKeywords) {
rowElement = rowElement.nextElementSibling();
String tmpLines[] = rowElement.text().trim().replaceAll(",", "").split(" ");
Matcher mat5 = tPat5.matcher(tmpLines[0]);//tpat5 is regex for numerical digits inside table 2nd row
Matcher mat6 = tPat5.matcher(tmpLines[1]);
Matcher mat7 = tPat5.matcher(tmpLines[2]);
Matcher mat8 = tPat5.matcher(tmpLines[3]);
System.out.println(mat5.matches());
System.out.println(mat6.matches());
System.out.println(mat7.matches());
System.out.println(mat8.matches());
if (mat5.matches())
{
for(int index=0 ; index < tmpLines.length ; index++) {
System.out.println("Value at index-> "+index+" is : "+tmpLines[index]);
}
System.out.println("For : "+ tmpLines[0] + "|" +"Against : "+ tmpLines[1] + "|" + "Abstain : "+tmpLines[2] + "|" +"Broker Non-Votes : "+ tmpLines[3]);
break;
}
else {
System.out.println("Numerical Values werent found in expected range for"+tmpLines);
}
}