순서대로 HTML 문서의 링크를 가져옵니다.

c# html html-agility-pack regex webbrowser-control

문제

나는 HTML 문서의 모든 링크를 얻고 싶다. 이것은 문제가 아니지만 분명히 모든 링크를 하나씩 배열에 저장하기 전에 알파벳순으로 놓습니다. 나는 원본 순서 (알파벳이 아닌)로 링크를 갖고 싶다.

그래서 첫 번째로 발견 된 링크를 얻고 저장 한 다음 두 번째 링크를 얻을 가능성이 있습니까? HtmlAgilityPack과 Webbrowser-Control 메서드를 사용하여 이미 시도했지만 둘 다 사전 순으로 정렬됩니다. 원래의 순서는 나중에 사용하는 데 중요합니다.

Regex에서 가능할 수도 있다고 들었지만, HTML 파싱에 사용해서는 안되는 충분한 대답을 발견했습니다. 어떻게해야합니까?

다음은 Webbrowser-Control 코드입니다. 링크를 가져 와서 배열에 저장하려고했습니다.

    private void btnGet_Click(object sender, EventArgs e)
    {
        HtmlWindow mainFrame = webFl.Document.Window.Frames["mainFrame"];
        HtmlElementCollection links = mainFrame.Document.Links;

        foreach (HtmlElement link in links)
        {
            string linkText = link.OuterHtml;
            if (linkText.Contains("puzzle"))
            {
                arr[i] = linkText;
                i++;
            }
        }
    }

미리 감사드립니다, Opak

인기 답변

HTML DOM API를 사용하여 DOM 트리를 이동하여 올바른 순서를 얻을 수 있습니다. 다음 코드는이 작업을 수행합니다. dynamic API를 사용하여 DOM API에 액세스합니다. WebBrowserHtmlElement.FirstChild / HtmlElement.NextSibling 이 DOM 텍스트 노드에 대해 null 을 반환하기 때문에 이러한 목적으로 작동하지 않기 때문입니다.

private void btnGet_Click(object sender, EventArgs e)
{
    Action<object> walkTheDom = null;
    var links = new List<object>();

    // element.FirstChild / NextSibling don't work as they stop at DOM text nodes

    walkTheDom = (element) =>
    {
        dynamic domElement = element;
        if (domElement.tagName == "A")
            links.Add(domElement);
        for (dynamic child = domElement.firstChild; child != null; child = child.nextSibling)
        {
            if (child.nodeType == 1) // Element node?
                walkTheDom(child);
        }
    };

    walkTheDom(this.webBrowser.Document.Body.DomElement);

    string html = links.Aggregate(String.Empty, (a, b) => a + ((dynamic)b).outerHtml + Environment.NewLine);
    MessageBox.Show(html);
}

[업데이트] dynamic 네이티브 요소 대신 <A> 태그에 대한 HtmlElement 객체 목록을 실제로 얻어야하는 경우 GetElementById 사용하여 약간의 트릭을 사용하여 여전히 가능합니다.

private void btnGet_Click(object sender, EventArgs e)
{
    Action<object> walkTheDom = null;
    var links = new List<object>();

    // element.FirstChild / NextSibling don't work as they stop at DOM text nodes

    walkTheDom = (element) =>
    {
        dynamic domElement = element;
        if (domElement.tagName == "A")
            links.Add(domElement);
        for (dynamic child = domElement.firstChild; child != null; child = child.nextSibling)
        {
            if (child.nodeType == 1) // Element node?
                walkTheDom(child);
        }
    };

    walkTheDom(this.webBrowser.Document.Body.DomElement);

    string html = links.Aggregate(String.Empty, (a, b) => a + ((dynamic)b).outerHtml + Environment.NewLine);
    MessageBox.Show(html);
}



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