HtmlAgilityPack:如何检查元素是否可见

本文关键字:元素 是否 检查 何检查 HtmlAgilityPack | 更新日期: 2023-09-27 17:58:35

我正在进行一些HTML解析,我正在使用HtmlAgilityPack,我正在尝试检查如果HTML在浏览器中呈现,节点元素是否可见。

通过可见,我可能满足于检查displayvisibility样式值。(除非有其他我应该担心的事情?)。

那么,我该怎么做呢?有简单的构建方法吗?我可以使用一些XPath魔术吗?(我目前对XPath没有太多的了解)。

我曾考虑过手动解析样式值,但宁愿将其作为最后手段。还是这是我唯一的选择?

仅供参考,我正在处理的对象是这样的:

HtmlAgilityPack.HtmlNode node = GetNode();

HtmlAgilityPack:如何检查元素是否可见

好吧,所以我已经做到了,至少是为了我的需要。但是,请注意,正如其他评论所说,这不允许您检查元素是否对最终用户可见(在屏幕上)。

我采用的方法简单地检查了一些基本规则:如果元素的样式属性包含display:nonevisibility:hidden,或者祖先元素具有相同的样式规则,则该元素"不可见"。

考虑到这一点,以下是我的代码,它为我完成了任务:

private static bool IsNodeVisible(HtmlAgilityPack.HtmlNode node)
{
    var attribute = node.Attributes["style"];
    bool thisVisible = false;
    if (attribute == null || CheckStyleVisibility(attribute.Value))
        thisVisible = true;
    if (thisVisible && node.ParentNode != null)
        return IsNodeVisible(node.ParentNode);
    return thisVisible;
}
private static bool CheckStyleVisibility(string style)
{
    if (string.IsNullOrWhiteSpace(style))
        return true;
    var keys = ParseHtmlStyleString(style);
    if (keys.Keys.Contains("display"))
    {
        string display = keys["display"];
        if (display != null && display == "none")
            return false;
    }
    if (keys.Keys.Contains("visibility"))
    {
        string visibility = keys["visibility"];
        if (visibility != null && visibility == "hidden")
            return false;
    }
    return true;
}
public static Dictionary<string, string> ParseHtmlStyleString(string style)
{
    Dictionary<string, string> result = new Dictionary<string, string>();
    style = style.Replace(" ", "").ToLowerInvariant();
    string[] settings = style.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
    foreach (string s in settings)
    {
        if (!s.Contains(':'))
            continue;
        string[] data = s.Split(':');
        result.Add(data[0], data[1]);
    }
    return result;
}

此操作的入口点是IsNodeVisible,并将检查传递给它的HtmlNode的可见性。