Próbuję wygenerować selektory CSS dla losowych elementów na stronie za pomocą C#. Niektóre tła:HtmlElement.Parent zwraca nieprawidłowy rodzic
Używam formularza z formantem WebBrowser. Podczas nawigacji można poprosić o selektor CSS elementu pod kursorem. Pierwsze HTML-element jest trywialne, oczywiście, za pomocą:
WebBrowser.Document.GetElementFromPoint(<Point>);
Dąży się do tworzenia selektora 'surowe' css prowadzący do elementu pod kursora, a la:
html > body > span:eq(2) > li:eq(5) > div > div:eq(3) > span > a
Ten selektor oparty jest na: operatorach eq, ponieważ jest przeznaczony do obsługi przez jQuery i/lub SizzleJS (te dwie funkcje obsługują: eq - oryginalne selektory CSS tego nie robią, Thumbs up @BoltClock za pomoc w wyjaśnieniu tego). Więc dostajesz obraz. Aby osiągnąć ten cel, możemy dostarczyć pobrane HTMLElement do poniższej metody i rozpocząć wynurzanie się drzewa DOM prosząc o dominującej każdego elementu natkniemy:
private static List<String> GetStrictCssForHtmlElement(HtmlElement element)
{
List<String> familyTree;
for (familyTree = new List<String>(); 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)")));
}
Metoda ta pracuje niezawodnie do różnych stron. Jednak jest jedna konkretna strona, która sprawia, że głowę w:
http://www.delicious.com/recent
Próbując odzyskać selektora CSS jakiegokolwiek elementu na liście (na środku strony) nie powiedzie się z jednego bardzo prostego powodu:
Po przebiciu uderza pierwszy element SPAN w górę (można go zobaczyć, sprawdzając stronę za pomocą narzędzi internetowych IE9 do weryfikacji) próbuje ją przetworzyć, obliczając jej pozycję porządkową wśród tego samego rodzeństwa tagów. Aby to zrobić, musimy poprosić go o węzeł rodzica dla rodzeństwa. To jest, gdzie sprawy stają się dziwne. Element SPAN zgłasza, że Parent to element DIV o id = "recent-index". Jednak jest to obiekt nadrzędny SPAN (bezpośrednim rodzicem jest LI class = "wrap isAdv"). Powoduje to niepowodzenie metody, ponieważ - nie dziwi - nie wykrywa ona SPAN wśród dzieci.
Ale robi się jeszcze dziwniej. Pobrałem i wyizolowałem HtmlElement samego SPAN. Potem dostałem to nadrzędna i użył go, aby ponownie zejść z powrotem w dół do elementu SPAN używając:
HtmlElement regetSpanElement = spanElement.Parent.Children[0].Children[1].Children[1].Children[0].Children[2].Children[0];
to doprowadzić nas z powrotem do węzła SPAN zaczęliśmy ... z jednym skręcie Jednakże:
regetSpanElement.Parent.TagName;
To teraz informuje LI jako rodzica XX. Jak to może być? Jakiś wgląd?
Jeszcze raz dziękuję.
Uwagi:
Uratowałem kod HTML (jak to przedstawiono wewnątrz WebBrowser.Document.Html) i kontrolowane mu się być w 100% pewien, że nic śmiesznego odbywa się (aka inny kod służył Kontrola WebBrowser niż ta, którą widzę w IE9 - ale tak się nie dzieje, struktura pasuje do 100% dla danej ścieżki).
Używam formantu WebBrowser w IE9 trybie wykonując instrukcje opisane tutaj:
http://www.west-wind.com/weblog/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version
Starając się uzyskać kontrolę WebBrowser i IE9 do uruchomienia jako podobnie jak to możliwe.
Podejrzewam, że zaobserwowane efekty mogą być spowodowane działaniem skryptu za moimi plecami. Jednak moja wiedza nie jest tak daleko idąca pod względem programowania internetowego, aby go przypiąć.
EDIT: Literówki
': eq()' nie jest prawidłowym selektorem CSS. Przypuszczam, że chodziło o 'html> body> span: nth-child (3)> li: nth-child (6)> div> div: nth-child (4)> span> a'? – BoltClock
Dzięki za umożliwienie mi wyjaśnienia - chciałem powiedzieć, że selektory css mają być przekazywane do jQuery i/lub SizzleJS. Zaktualizuję treść w oryginalnym poście. Aby to odzwierciedlić. Jeszcze raz dziękuję;) – xDisruptor
Witam, nie mam jeszcze odpowiedzi, ale chciałem powiedzieć kilka rzeczy; Po pierwsze, dziękuję za szczegóły w twoim pytaniu i dzięki uprzejmości członkom tej strony, +1 za to! Po drugie; Fascynuje mnie kontekst samego pytania; Rozumiem, co chcesz zrobić, czy możesz pomóc nam w wypełnieniu części Dlaczego? budujesz hierarchię drzew lub jakiś ślad szlaku? –