我正在做一些HTML解析,我正在使用HtmlAgilityPack ,我試圖檢查如果html是在瀏覽器中呈現的話節點元素是否可見。
通過可見,我可能滿足於檢查display
和visibility
樣式值。 (除非有額外的東西我應該擔心嗎?)。
那麼,我該怎麼做呢?有簡單的構建方式嗎?我可以使用一些XPath魔法嗎? (目前我對XPath的了解不多)。
我曾考慮手動解析樣式值,但寧願將其作為最後的手段保存。或者這是我唯一的選擇嗎?
僅供參考,我正在使用的對像是這樣的:
HtmlAgilityPack.HtmlNode node = GetNode();
好的,所以我設法做到了這一點,至少是為了我的需要。但請注意,正如其他評論所述,這不允許您檢查最終用戶是否可以看到(在屏幕上)元素。
我採用的方法簡單檢查了一些基本規則:如果元素的style屬性包含display:none
或visibility:hidden
,或者ancestor元素具有相同的樣式規則,則元素“不可見”。
考慮到這一點,這是我的代碼,為我做的工作:
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
的可見性。