Selenium Chrome驱动程序:如何加载所有框架并获取完整页面源?

时间:2018-04-03 06:48:59

标签: c# selenium web-scraping selenium-chromedriver google-chrome-headless

我正在开发一个监控其他网站变化的Web应用程序。我遇到了一些网站,其中包含Frame set和Frames的负载。

我使用以下代码:

  var chromeOption = new ChromeOptions();
        chromeOption.AddArgument("--headless");
        Console.WriteLine("Getting into the Application");
        using (var driver = new ChromeDriver(chromeOption))
        {
            Console.WriteLine("Loading the Web Page");

            driver.Navigate().GoToUrl("http://www.xyz.dk/");
            var htmltxt = driver.PageSource;
        }

页面来源让我回复:

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>
    <title>Mr X. Consulting</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
</head>
<frameset cols="25%,50%,25%" frameborder="0">
  <frame src="border.html" />
  <frame src="jjc.html" />
  <frame src="border.html" />
</frameset>

PageSource未加载帧源。我在网上搜索了很多,甚至在这里徒劳无功,但没有得到有用的信息。

我的问题是我如何加载所有帧并获得如下所示的整个页面源(仅来自Chrome中的Inspect元素)

由于 Heveen

2 个答案:

答案 0 :(得分:0)

我不认为您可以(轻松)获得组合页面源,因为您在&#34; Inspect Element&#34;中看到,因为每个帧都有自己的源,类似于您在您右键单击页面,选择查看页面来源查看框架来源

然而,您可以通过递归遍历它们来获取所有帧的所有页面源:

    private static List<string> GetAllSources(IWebDriver driver)
    {
        var sources = new List<string>();
        driver.SwitchTo().DefaultContent();
        AddFrameSources(driver, sources);
        return sources;
    }

    private static void AddFrameSources(IWebDriver driver, List<string> sources)
    {
        sources.Add(driver.PageSource);
        var frames = driver.FindElements(By.TagName("frame"));
        var iframes = driver.FindElements(By.TagName("iframe"));
        foreach (var frame in frames.Union(iframes))
        {
            driver.SwitchTo().Frame(frame);
            AddFrameSources(driver, sources);
            driver.SwitchTo().ParentFrame();
        }
    }

答案 1 :(得分:0)

通过 Navigate().GoToUrl() Selenium 调用网址时,焦点仍然在顶级浏览上下文< / strong>即可。因此,在您调用PageSource的下一步中,将显示顶级浏览上下文 HTML 以及各种可用{{1}的存在}标签。

根据页面源,您提供了演示,或许您已经修剪了<frame>标签的属性。您可以通过切换到以下代码块后面的各个帧来检索 frames HTML

<frame>

备注

这个解决方案只是一个vanila解决方案,强调如何在一个框架内获取 HTML 。此外,您可以实施以下增强功能:

  • 您可以通过driver.Navigate().GoToUrl("http://www.xyz.dk/"); Console.WriteLine("HTML of Top Level Browsing Context : "); Console.WriteLine(driver.PageSource); driver.SwitchTo().Frame(driver.FindElement(By.XPath("//frame[@src='border.html']"))); Console.WriteLine("HTML of border frame : "); Console.WriteLine(driver.PageSource); driver.SwitchTo().ParentFrame(); driver.SwitchTo().Frame(driver.FindElement(By.XPath("//frame[@src='jjc.html']"))); Console.WriteLine("HTML of jjc frame : "); Console.WriteLine(driver.PageSource); driver.SwitchTo().ParentFrame(); driver.SwitchTo().Frame(driver.FindElement(By.XPath("//frame[@src='border.html']"))); Console.WriteLine("HTML of border frame : "); Console.WriteLine(driver.PageSource); 识别所有相框并创建列表
  • 迭代列表并使用正确的 WebDriverWait 切换到预期的帧。请参阅讨论How can I select a html element no matter what frame it is in in selenium?
  • 中的切换框架的更好方法部分