首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按顺序获取html文档的链接

按顺序获取html文档的链接
EN

Stack Overflow用户
提问于 2013-12-01 00:18:55
回答 1查看 1.7K关注 0票数 2

我想要一个HTML文档的所有链接。这不是一个问题,但显然,它把所有的链接按字母顺序存储在一个的数组中。我想要的链接按原来的顺序(而不是字母)。

那么有没有可能得到第一个找到的链接,存储它,然后再存储第二个链接,.?我已经尝试过使用HtmlAgilityPack和Webbrowser方法,但它们都是按字母顺序排列的。对于以后的目的来说,最初的顺序很重要。

我听说使用Regex可能是可能的,但我已经找到了足够的答案,他们说您不应该将其用于HTML解析。那我该怎么做?

下面是Webbrowser-Control代码,我尝试使用它获取链接并将它们存储到数组中:

代码语言:javascript
复制
    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++;
            }
        }
    }

预先谢谢你,奥帕克

EN

回答 1

Stack Overflow用户

发布于 2013-12-01 01:54:55

您可以通过使用HTML DOM API遍历DOM树来获得正确的顺序。下面的代码会这样做。注意,我使用dynamic访问DOM。这是因为WebBrowserHtmlElement.FirstChild/HtmlElement.NextSibling不能用于此目的,因为它们返回DOM文本节点的null

代码语言:javascript
复制
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);
}

如果您确实需要获得一个用于标记的HtmlElement对象列表,而不是dynamic本机元素,那么使用GetElementById的小技巧仍然可以实现

代码语言:javascript
复制
private void btnGet_Click(object sender, EventArgs e)
{
    // element.FirstChild / NextSibling don't work because they stop on DOM text nodes

    var links = new List<HtmlElement>();
    var document = this.webBrowser.Document;
    dynamic domDocument = document.DomDocument;
    Action<dynamic> walkTheDom = null;

    walkTheDom = (domElement) =>
    {
        if (domElement.tagName == "A")
        {
            // get HtmlElement for the found <A> tag
            string savedId = domElement.id;
            string uniqueId = domDocument.uniqueID;
            domElement.id = uniqueId;
            links.Add(document.GetElementById(uniqueId));
            if (savedId != null)
                domElement.id = savedId;
            else
                domElement.removeAttribute("id");
        }
        for (var child = domElement.firstChild; child != null; child = child.nextSibling)
        {
            if (child.nodeType == 1) // is an Element node?
                walkTheDom(child);
        }
    };

    // walk the DOM for <A> tags
    walkTheDom(domDocument.body);

    // show the found tags
    string combinedHtml = links.Aggregate(String.Empty, (html, element) => html + element.OuterHtml + Environment.NewLine);
    MessageBox.Show(combinedHtml);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20307268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档