닫힌 HTML 태그가 없을 때 HTMLAgilityPack에서 문제를 해결할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/1928293

  •  20-09-2019
  •  | 
  •  

문제

글쎄, 나는 다음과 같은 문제가있다.
내가 가지고있는 HTML은 기형이 있으며,이 경우 HTML 민첩성 팩을 사용하여 노드를 선택하는 데 문제가 있습니다.
코드는 다음과 같습니다.

string strHtml = @"
<html>
  <div>
    <p><strong>Elem_A</strong>String_A1_2 String_A1_2</p>
    <p><strong>Elem_B</strong>String_B1_2 String_B1_2</p>
  </div>
  <div>
    <p><strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas</p>
    <p><strong>Elem_B</strong>String_B2_2 String_B2_2</p>
  </div>
</html>";
HtmlAgilityPack.HtmlDocument objHtmlDocument = new HtmlAgilityPack.HtmlDocument();
objHtmlDocument.LoadHtml(strHtml);
HtmlAgilityPack.HtmlNodeCollection colnodePs = objHtmlDocument.DocumentNode.SelectNodes("//p");
List<string> lststrText = new List<string>();
foreach (HtmlAgilityPack.HtmlNode nodeP in colnodePs)
{
  lststrText.Add(nodeP.InnerHtml);
}

문제는 String_A2_2가 괄호로 둘러싸여 있다는 것입니다.
따라서 htmlagility pack은 lststrtext에서 4 대신 5 개의 문자열을 반환합니다.
htmlagility pack return 요소 3을"<strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas"?
아니면 요소를 닫기 위해 전처리를 할 수 있습니까?
lstStrText의 현재 내용은 다음과 같습니다

lststrText[0] = "<strong>Elem_A</strong>String_A1_2 String_A1_2"  
lststrText[1] = "<strong>Elem_B</strong>String_B1_2 String_B1_2"  
lststrText[2] = ""  
lststrText[3] = ""  
lststrText[4] = "<strong>Elem_B</strong>String_B2_2 String_B2_2"
도움이 되었습니까?

해결책

대부분의 HTML 파서는 작동하는 DOM을 구축하려고 시도합니다. 그들은 어떤 식 으로든 개조되거나 폐쇄 될 것입니다.

노드를 선택하는 것이 중요하고 속도와 엄청난 양의 데이터가 문제가되지 않으면 모든 것을 잡을 수 있습니다.u003Cp> 대신 정규 표현식이있는 태그 :

Regex reMatchP = new Regex(@"<(p)>.*?</\1>");
foreach (Match m in reMatchP.Matches(strHtml))
{
   Console.WriteLine(m.Value);
}

이 정규 표현은u003Cp> 태그는 잘 형성되고 닫힙니다.

이 REGEX를 프로그램에서 많이 실행하려면 다음과 같이 선언해야합니다.

static Regex reMatchP = new Regex(@"<(p)>.*?</\1>", RegexOptions.Compiled);

편집 : 민첩성 팩 변경

htmlagility 팩을 사용하려면 htmldocument.cs에서 푸시 노드 기능을 수정할 수 있습니다.

if (HtmlNode.IsCDataElement(CurrentNodeName()))
{
   _state = ParseState.PcData;
   return true;
}

// new code start
if ( !AllowedTags.Contains(_currentnode.Name) )
{
    close = true;
}
// new code end

허용되는 경우 B, P, BR, SPAN, DIV 등 알려진 모든 알려진 태그 목록이되는 경우.

출력은 100%가 아니라 원하는 것이 아니라 충분히 가깝습니까?

<strong>Elem_A</strong>String_A1_2 String_A1_2
<strong>Elem_B</strong>String_B1_2 String_B1_2
<strong>Elem_A</strong>String_A2_2 <ignorestring_a2_2></ignorestring_a2_2> asdas
<strong>Elem_B</strong>String_B2_2 String_B2_2

다른 팁

당신은 사용할 수 있습니다 Tidynet 사전 처리를 수행하려면 귀하가 암시합니다. 귀하의 경우 귀하의 경우에 적용 할 수없는 이유를 설명하기 위해 답변을 편집 할 수 있습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top