Оценка javascript с помощью AngleSharp

Я пытаюсь оценить javascript на странице, прежде чем делать запрос, потому что html, который я ищу, не существует в документе AngleSharp.

Есть метод: document.ExecuteScript(string)

Но я не знаю, как его использовать по сравнению с тем, как я видел другие библиотеки. Например, некоторый код Python выглядит так...

wait.until(presence_of_element_located((By.ID, "class-name")))

Который просто приостанавливает код, я думаю, пока вся страница не будет оценена. Затем элементы можно искать.

В AngleSharp похоже, что мне нужно запустить метод ExecuteScript, чтобы сделать то же самое. Но он просто выдает исключение (Jint.Runtime.JavaScriptException: «результаты не определены») и в результате возвращает объект, который полностью запутывает и совсем не помогает.

Что мне сделать, чтобы моя следующая команда:

IHtmlCollection<IElement> cells = document.QuerySelectorAll(s);

на самом деле просматривает весь документ, а не только исходный HTML?


person Gavin Williams    schedule 05.10.2020    source источник


Ответы (1)


Я думаю, что здесь больше, чем один вопрос. Так что я сломаю его.

Во-первых, давайте получим некоторые основы здесь:

  1. AngleSharp — это ядро ​​браузера, а не браузер и не JS-движок.
  2. AngleSharp предоставляет возможность расширить его, например, с помощью JS-движка. AngleSharp.Js — это такой движок на основе Jint, однако его пока экспериментальные и сложные скрипты точно не запустятся.
  3. Прежде чем мы перейдем к подробностям цикла событий и асинхронной загрузки, я бы рекомендовал убедиться, что любой сценарий, который вы ожидаете запустить, действительно работает.

Теперь к конкретике:

ExecuteScript — это небольшой помощник из AngleSharp.Js, который на самом деле запускает фрагмент кода JS, который вы предоставляете. Я думаю, это совсем не то, что вы хотите.

Если вы просто хотите подождать, пока что-то появится, вы можете сделать это с помощью нескольких строк кода C#:

var maxTime = TimeSpan.FromSeconds(1.5);

var totalTime = TimeSpan.Zero;
var pollTime = TimeSpan.FromMilliseconds(25);

while (totalTime < maxTime)
{
    await Task.Delay(pollTime.Milliseconds);
    
    // check condition
    if (document.QuerySelector(".foo.bar") != null)
    {
        // run zoned code
        break;
    }
    
    totalTime += pollTime;
}

AngleSharp.Js на самом деле имеет различные способы попасть в цикл обработки событий, т. е. дождаться, пока JS завершит текущую работу.

Например, WaitUntilAvailable() можно использовать для ожидания обработки события загрузки (и связанного с ним).

Чтобы поставить какое-то действие в очередь, был добавлен метод расширения Then(). Все эти методы расширения живут непосредственно в экземпляре IDocument.

person Florian Rappl    schedule 06.10.2020