【问题标题】:Executing page scripts before retrieving it's contents在检索其内容之前执行页面脚本
【发布时间】:2019-11-05 12:41:56
【问题描述】:

我有一个页面需要自动执行一些任务并抓取一些数据,但是页面在加载后会运行一些 JS 以将一些数据注入 DOM;我无法拦截(无论如何都不是很好的格式),我希望找到一个快速且不消耗内存的解决方案。

我尝试自己获取脚本并使用一些无头驱动程序(即 phantomJs)执行它们,但它没有更新页面源,我不确定如何从中检索更新的 DOM

var page = GetWebPage(url);
var scripts = page.Html.QuerySelectorAll("script");

var phantomDriver = new PhantomJSDriver(PhantomJSDriverService.CreateDefaultService(Directory.GetCurrentDirectory()));
phantomDriver.Navigate().GoToUrl(url);

foreach (var script in scripts)
    phantomDriver.ExecuteScript(script.InnerText);

var at = phantomDriver.PageSource;

【问题讨论】:

  • 可能你需要使用await...
  • 不,抱歉,添加了明确的等待,直到文档准备好,但这并没有解决它var wait = new WebDriverWait(phantomDriver, TimeSpan.FromSeconds(30.00)); wait.Until(driver1 => ((IJavaScriptExecutor)phantomDriver).ExecuteScript("return document.readyState").Equals("complete"));

标签: javascript selenium selenium-webdriver web-scraping automation


【解决方案1】:

您可以使用“等待”。根据this link,Selenium 既有隐式等待,也有显式等待。下面的示例使用了显式等待。

要使用显式等待,请使用 WebDriverWaitExpectedConditions。我不确定您使用的是什么语言,但这里有一个 python 示例。这在 try-catch 块中使用WebDriverWait,允许timeout 秒满足指定的ExpectedConditions。截至 2019 年 6 月,条件适用于:

python中的示例代码:

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

url = 'https://stackoverflow.com/questions/56724178/executing-page-scripts-before-retrieving-its-contents'
target = (By.XPATH, "//div[@class='gravatar-wrapper-32']")
timeout = 20  # Allow max 20 seconds to find the target

browser = webdriver.Chrome()
browser.get(url)
try:
    WebDriverWait(browser, timeout).until(EC.visibility_of_element_located(target))
except TimeoutException:
    print("Timed out waiting for page to load")
    browser.quit()

重要的一点在tryexcept 之间,您可以修改它以使用您感兴趣的特定“预期条件”。

【讨论】:

  • 不,抱歉,添加了明确的等待,直到文档准备好,但这并没有解决它var wait = new WebDriverWait(phantomDriver, TimeSpan.FromSeconds(30.00)); wait.Until(driver1 => ((IJavaScriptExecutor)phantomDriver).ExecuteScript("return document.readyState").Equals("complete"))
  • 您说该页面有一些在加载后运行的 JS,因此您的代码可能在该 JS 运行之前仍在运行。尝试设置预期条件以观察被 JS 修改的元素,以检测代码何时完成更改。
猜你喜欢
  • 1970-01-01
  • 2022-10-07
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 2018-07-25
  • 2013-02-12
  • 2015-09-30
相关资源
最近更新 更多