HTML 구문 분석 C # HTMLAgilityPack

c# html-agility-pack xpath

문제

HTMLAgilityPack을 사용하여 HTML 문자열에서 일부 값을 읽는 데 문제가 있습니다.

내가 읽고 싶은 두 항목은 신문 : 82548828과 물고기 : 8545852485

하지만 지금까지 작성한 코드를 사용하면 신문 항목 만 다시받을 수 있습니다.

나는 XPATH 내가 완전히 정확하지 않습니다 용의자,이 첫 번째 루프에 대한 XPATH는 이것이 다시 2 개의 제공으로 정확한 것 같아요

내 두 번째 루프가이 두 항목을 반복하게하고 싶습니다 (6이 있다고 생각합니까?)

또한 div2.SelectSingleNode (sXPathT); groupLabel을 추출하는 올바른 방법은 무엇입니까? 또는 더 좋은 방법이 있습니까?

감사

아래의 전체 테스트 코드

string strTestHTML = @"<div class=\""content\"" data-id=\""123456789\"">" + 
                              "  <div class=\"m-group item\">" +
                              "      <span class=\"group\">" +
                              "          <a href=\"javascript:void(0);\">" +
                              "          <span class=\"group-label\">Newspaper </span>" +
                              "          <span class=\"group-value\">82548828</span>" +
                              "          </a>" +
                              "      </span>" +
                              "      <span class=\"group\">" +
                              "          <a href=\"javascript:void(0);\">" +
                              "          <span class=\"group-label\">Fish </span>" +
                              "          <span class=\"group-value\">8545852485</span>" +
                              "          </a>" +
                              "      </span>" +
                              "  </div>" +
                              "</div>";


            //<div class="content" data-id="123456789">
            string sNewXpath = "//div[contains(@class,'content') and contains(@data-id, '" + "123456789" + "')]";
            //<div class="m-group item">
            string sSecondXPath = "/div[contains(@class,'m-group item')]";
            //<span class="group"
            string sThirdXPath = "//span[contains(@class,'group')]";

            string sXPathT = "//span[contains(@class,'group-label')]";
            string sXPathO = "//span[contains(@class,'group-value')]";

            HtmlAgilityPack.HtmlDocument Doc = new HtmlDocument();
            Doc.LoadHtml(strTestHTML);

            foreach (HtmlNode div in Doc.DocumentNode.SelectNodes(sNewXpath + sSecondXPath))
            {
                foreach (HtmlNode div2 in div.SelectNodes(sThirdXPath))
                {
                    var vOddL = div2.SelectSingleNode(sXPathT);
                    var vOddP = div2.SelectSingleNode(sXPathO);

                    string GroupLabel = vOddL.InnerText.Trim();

                    string GroupValue = vOddP.InnerText.Trim();
                }
            }

편집하다:

forloop에서 6 가지 항목을 다시 얻는 이유를 찾았습니다.

sThirdXPath : string sThirdXPath = "// span [contains (@ class, 'group')]";

해야한다:

string sThirdXPath = "// span [@ class = 'group']";

관심있는 값을 찾기 위해 div2에 포함 된 HTMLNode를 조사하는 올바른 방법을 찾고 있습니다. 필자는 HTML 문서가 아닌 현재 노드와 일치하도록 XPath가 필요하다고 가정합니다.

업데이트 된 HTML 샘플 :

<div class="content" data-id="123456789">
<div class="m-group item">
    <span class="group">
        <a href="javascript:void(0);">
        <span class="group-label">Newspaper </span>
        <span class="group-value">82548828</span>
        </a>
    </span>

    <span class="group">
        <a href="javascript:void(0);">
        <span class="group-label">Fish </span>
        <span class="group-value">8545852485</span>
        </a>
    </span>
</div>
</div>

<div class="content" data-id="987654321">
<div class="m-group item">
    <span class="group">
        <a href="javascript:void(0);">
        <span class="group-label">Bread</span>
        <span class="group-value">82548828</span>
        </a>
    </span>

    <span class="group">
        <a href="javascript:void(0);">
        <span class="group-label">Milk </span>
        <span class="group-value">8545852485</span>
        </a>
    </span>
</div>
</div>

위의 예에서 Just Bread와 The Value, Milk 및 그 Value에 액세스하는 올바른 XPATH는 무엇입니까? 내가 data-id = "987654321을 XPath에서 필터링 할 필요가 있다고 가정합니까?

수락 된 답변

의심의 여지가 있습니다. 이미 전체 경로에 대한 XPath 쿼리를 지정 했으므로 루프가 필요하지 않습니다. 이 예제에서 "Newspaper"및 "Fish"노드를 얻으려면 SelectSingleNode를 반복하고 호출하는 대신 SelectNodes를 사용하면됩니다. 물론 결과 세트를 반복 할 수있는 항목이 더 많은 경우이 예에서 색인으로 액세스 할 수 있습니다.

string sXPathT = "//span[contains(@class,'group-label')]";
string sXPathO = "//span[contains(@class,'group-value')]";

HtmlAgilityPack.HtmlDocument Doc = new HtmlDocument();
Doc.LoadHtml(strTestHTML);

var vOddL = Doc.DocumentNode.SelectNodes(sXPathT);
var vOddP = Doc.DocumentNode.SelectNodes(sXPathO);

string GroupLabelNewsPaper = vOddL.ElementAt(0).InnerText.Trim();
string GroupLabelFish = vOddL.ElementAt(1).InnerText.Trim();

string GroupValueNewspaper = vOddP.ElementAt(0).InnerText.Trim();
string GroupValueFish = vOddP.ElementAt(1).InnerText.Trim();

Console.WriteLine($"{GroupLabelNewsPaper}\t{GroupValueNewspaper}");
Console.WriteLine($"{GroupLabelFish}\t{GroupValueFish}");

산출:

Newspaper       82548828
Fish    8545852485

업데이트 : 특정 콘텐츠 노드를 얻으려면이 XPath를 사용할 수 있습니다.

string xpathForDataId = "//div[@class='content' and @data-id='987654321']";

위의 표현식으로 div를 필터링하면 자식 노드를 다음과 같이 얻을 수 있습니다.

string sXPathT = ".//span[contains(@class,'group-label')]";
string sXPathO = ".//span[contains(@class,'group-value')]";
string xpathForDataId = "//div[@class='content' and @data-id='987654321']";

HtmlAgilityPack.HtmlDocument Doc = new HtmlDocument();
Doc.LoadHtml(strTestHTML);

var specificNode = Doc.DocumentNode.SelectSingleNode(xpathForDataId);

var vOddL = specificNode.SelectNodes(sXPathT);
var vOddP = specificNode.SelectNodes(sXPathO);

string GroupLabelBread = vOddL.ElementAt(0).InnerText.Trim();
string GroupLabelMilk = vOddL.ElementAt(1).InnerText.Trim();

string GroupValueBread = vOddP.ElementAt(0).InnerText.Trim();
string GroupValueMilk = vOddP.ElementAt(1).InnerText.Trim();

Console.WriteLine($"{GroupLabelBread}\t{GroupValueBread}");
Console.WriteLine($"{GroupLabelMilk}\t{GroupValueMilk}");

sXPathT와 sXPathO에서 ".//"을 확인하십시오. 이를 통해 전체 문서가 아닌 현재 컨텍스트 만 검색합니다.

산출:

Bread   82548828
Milk    8545852485


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.