我试图通过C#为网页上的随机元素生成CSS选择器.一些背景:
我使用一个带有WebBrowser控件的窗体.导航时可以要求光标下的元素的CSS选择器.获取html元素是微不足道的,当然,通过以下方式:
WebBrowser.Document.GetElementFromPoint();
目标是创建一个“严格”css选择器,导致光标下面的元素,a-la:
html > body > span:eq(2) > li:eq(5) > div > div:eq(3) > span > a
这个选择器基于:eq运算符,因为它意味着由jQuery和/或SizzleJS处理(这两个支持:eq – 原始CSS选择器不会.Thumbs up @BoltClock帮助我澄清这一点).所以,你得到的照片.为了实现这一目标,我们将检索到的HtmlElement提供给下面的方法,并通过询问我们遇到的每个元素的父级来启动DOM树.
private static List GetStrictCssForHtmlElement(HtmlElement element)
{
List familyTree;
for (familyTree = new List(); element != null; element = element.Parent)
{
string ordinalString = CalculateOrdinalPositionAmongSameTagSimblings(element);
if (ordinalString == null) return null;
familyTree.Add(element.TagName.ToLower() + ordinalString);
}
familyTree.Reverse();
return familyTree;
}
private static string CalculateOrdinalPositionAmongSameTagSimblings(HtmlElement element, bool simplifyEq0 = true)
{
int count = 0;
int positionAmongSameTagSimblings = -1;
if (element.Parent != null)
{
foreach (HtmlElement child in element.Parent.Children)
{
if (element.TagName.ToLower() == child.TagName.ToLower())
{
count++;
if (element == child)
{
positionAmongSameTagSimblings = count - 1;
}
}
}
if (positionAmongSameTagSimblings == -1) return null; // Couldn't find child in parent's offsprings!?
}
return ((count > 1) ? (":eq(" + positionAmongSameTagSimblings + ")") : ((simplifyEq0) ? ("") : (":eq(0)")));
}
这种方法已经可靠地用于各种页面.然而,有一个特别的页面使我的头:
尝试检索列表中任何元素的CSS选择器(在页面的中心)失败的原因很简单:
升序后,以第一个SPAN元素的方式(您可以通过使用IE9的web-dev工具检查页面来查看它)来进行验证),它会尝试通过计算它的相同标签兄弟之间的顺序位置来处理它.为了做到这一点,我们需要问这个兄弟节点的父节点.这是事情变得奇怪的地方. SPAN元素报告它的父是一个ID =“recent-index”的DIV元素.但是,这不是SPAN的直接父级(直接父级是LI class =“wrap isAdv”).这导致方法失败,因为 – 不知不觉 – 它没有发现儿童中的SPAN.
但它甚至更加严厉.我检索并隔离了SPAN本身的HtmlElement.然后我得到它的父,并使用它重新下降到SPAN元素使用:
HtmlElement regetSpanElement = spanElement.Parent.Children[0].Children[1].Children[1].Children[0].Children[2].Children[0];
这导致我们回到我们开始的SPAN节点…但是有一点:
regetSpanElement.Parent.TagName;
现在报告李为父母X-X.这怎么可能?任何洞察力
提前再次感谢.
笔记:
>我保存了Html代码(如WebBrowser.Document.Html中所示),并自己检查,以确保没有任何有趣的事情发生(也就是WebBrowser控件的不同代码,而不是我在IE9中看到的代码),但这是没有发生结构匹配100%的路径).
>我在IE9模式下运行WebBrowser控件,使用这里概述的说明:
试图让WebBrowser控件和IE9尽可能的一样运行.
>我怀疑观察到的效果可能是由于一些脚本在我的背后运行.然而,我的知识在网络编程方面并没有达到极限.
编辑:Typos