Найти node в HTMLDocument(HtmlAgilityPack) по js innerHTML
Я использую CefSharp и js чтобы получить innerHTML элемента, на который нажали, и затем я хочу найти node в HtmlDocument, но не получается. Ниже просто код вставленного в страницу js-a и парсится страница в HtmlDocument
browser.ExecuteScriptAsync(@"
document.addEventListener('click', function(e) {
e = e || window.event;
CefSharp.PostMessage(e.target.parentElement.innerHTML);
}, false);
");
browser.GetSourceAsync().ContinueWith(taskHtml => { html.LoadHtml(taskHtml.Result); });
innerHTML может возвращать изображения
"<img data-src=\"//img0.happywear.ru/230x350/cache/goods/H/F/HF130EK_т.синий_front.jpg\" title=\"Полотенце махровое 70x130 см Happy Fox Home\" alt=\"Полотенце махровое 70x130 см Happy Fox Home\" class=\"content_product_catalog_list_item_img lazy loaded\" src=\"//img0.happywear.ru/230x350/cache/goods/H/F/HF130EK_т.синий_front.jpg\" data-was-processed=\"true\">
или что-то подобное когда человек кликает на текст
"<p class=\"price-block_title\">опт</p> <p class=\"price-block_wholesale\">139 ₽</p>
Подскажите, пожалуйста, как найти ноду по innerHTML. Или же как получить нажатый элемент(в браузере через библиотеку CefSharp) таким образом, чтобы потом с ним работать через библиотеку HtmlAgilityPack.
Если же есть библиотеки, позволяющие получить нажатый элемент со страницы и затем работать с ним(переходить к родителям его или чайлдом и все такое(например, находить элементы с похожим классом), то, пожалуйста, напишите.
Ответы (1 шт):
Благодаря человеку под ником aepot был найден способ получения ноды, нажатого элемента, путем записывания "пути"(массив номеров child-ов) до него на js и затем прохождения по этому пути до нужного элемента.
Ниже код функции, которая выполняется при вызове события FrameLoadEnd у ChromiumWebBrowser из CefSharp.
Она инжектит скрипт, который возвращает путь до нужной ноды
public async void OnFrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
//In the main frame we inject some javascript that's run on mouseUp
//You can hook any javascript event you like.
browser.ExecuteScriptAsync(@"
document.addEventListener('click', function(e) {
e = e || window.event;
target = e.target || e.srcElement;
CefSharp.PostMessage(getPath(target));
}, false);
function getIndex (node) {
var parent=node.parentElement||node.parentNode, i=-1, child;
while (parent && (child=parent.childNodes[++i])) if (child==node) return i;
return -1;
}
function getPath (node) {
var parent, path=[], index=getIndex(node);
(parent=node.parentElement||node.parentNode) && (path=getPath(parent));
index > -1 && path.push(index);
return path;
}
");
await browser.GetSourceAsync().ContinueWith(taskHtml => { html.LoadHtml(taskHtml.Result); });
}
}
Затем при получении сообщения от браузера(ивент JavascriptMessageReceived) с путем просто идем до ноды. clickedItem и есть нудная нода.
private void OnBrowserJavascriptMessageReceived(object sender, JavascriptMessageReceivedEventArgs e)
{
var windowSelection = (List<object>)e.Message;
HtmlNode clickedItem = html.DocumentNode;
for (int i = 0; i < windowSelection.Count; ++i)
clickedItem = clickedItem.ChildNodes[(int)windowSelection[i]];
}
Еще раз спасибо aepot, который нашел и скинул ссылку на вопрос(благодаря которому был найден способ решения задачи) в комментариях к моему вопросу. :)