0

HTML テーブルの解析に jsoup を使用しています。以下は、正しいセグメントを特定する必要があるシナリオです。正しいセグメントを識別するプロセスは次のとおりです。キーワードが見つかった場合
-> ABC<tr> 、 HTML タグを取得するまで反復する必要があります (テーブル識別用)。次に、4 つのキーワードForVoteAgainstVoteAbsentNoVotesがすべて含まれているかどうかを確認します。最初の行(そうでない場合は、キーワードの次の出現に移動します-> ABC)、同じプロセスに従います。テーブル内で一致する 4 つの投票キーワードを取得したら、テーブル内の数字を抽出できます。

私が立ち往生している問題は次のとおりです。キーワードABCが 1 つだけ出現する場合、解析できます。ただし、 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 であるかどうかを調べます。次に、最初の行に 4 つのキーワードがすべて存在するかどうかを確認します。はいの場合、数値を解析します。「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);
                            }
                        }
4

0 に答える 0