Problem polega na tym, że przeglądarka zazwyczaj wykonuje javascript, co powoduje zaktualizowany DOM. O ile nie można analizować kodu javascript lub przechwytywać danych, których używa, trzeba będzie wykonać kod tak, jak zrobiłby to przeglądarka. W przeszłości wpadłem na ten sam problem, użyłem selenu i PhantomJS do renderowania strony. Po renderowaniu strony użyłbym klienta WebDriver do nawigacji po DOM i pobrania potrzebnej zawartości, wysłania AJAX.
Na wysokim poziomie, to są kroki:
- selen zainstalowana: http://docs.seleniumhq.org/
- Rozpoczął piasta selen jako usługa
- pobrane phantomjs (a bezgłowy przeglądarki, które można wykonać JavaScript): http://phantomjs.org/
- Rozpoczęte phantomjs w trybie webdriver wskazujące na piaście selenu
- W mojej aplikacji skrobanie zainstalowano webdriver klienta pakiet Nuget:
Install-Package Selenium.WebDriver
Oto Wykorzystanie przykładem webdriver phantomjs:
var options = new PhantomJSOptions();
options.AddAdditionalCapability("IsJavaScriptEnabled",true);
var driver = new RemoteWebDriver(new URI(Configuration.SeleniumServerHub),
options.ToCapabilities(),
TimeSpan.FromSeconds(3)
);
driver.Url = "http://www.regulations.gov/#!documentDetail;D=APHIS-2013-0013-0083";
driver.Navigate();
//the driver can now provide you with what you need (it will execute the script)
//get the source of the page
var source = driver.PageSource;
//fully navigate the dom
var pathElement = driver.FindElementById("some-id");
Więcej informacji na selen, phantomjs i webdriver można znaleźć na poniższych linków:
http://docs.seleniumhq.org/
http://docs.seleniumhq.org/projects/webdriver/
http://phantomjs.org/
EDIT: łatwiejsza metoda
Wydaje jest Nuget pakiet dla phantomjs, tak że nie trzeba piastę (użyłem klastra zrobić ogromny złomowanie w ten sposób):
Instalacja sterownika internetowej:
Install-Package Selenium.WebDriver
Install osadzone exe:
Install-Package phantomjs.exe
Zaktualizowany kod:
var driver = new PhantomJSDriver();
driver.Url = "http://www.regulations.gov/#!documentDetail;D=APHIS-2013-0013-0083";
driver.Navigate();
//the driver can now provide you with what you need (it will execute the script)
//get the source of the page
var source = driver.PageSource;
//fully navigate the dom
var pathElement = driver.FindElementById("some-id");
działa idealnie – Flynn
Dzięki za doskonały przykład. Działa świetnie. –
Próbowałem, ale driver.Url się nie zmienia. Nawet nie jest wyjątkiem. Po prostu przekaż i nadal działa: puste. Nawiguj więc zwrotami takimi jak
. Próbowałem innych adresów URL. Po prostu poczekaj sekundę i przejdź do następnej linii. Koniec kodu nie może oczywiście znaleźć id-id. Dowolny pomysł? –