2016-03-09 67 views
7

我正在使用aCefSharp.Wpf.ChromiumWebBrowser(版本47.0.3.0)加载网页。页面加载后的一些要点我想获取源代码。从CefSharp Web浏览器获取HTML源代码

我呼吁:

wb.GetBrowser().MainFrame.GetSourceAsync() 

但它似乎并没有被返回所有的源代码(我相信这是因为有孩子帧)。

如果我称:

wb.GetBrowser().MainFrame.ViewSource() 

我可以看到它列出了所有的源代码(包括内帧)。

我想获得与ViewSource()相同的结果。请有人指出我正确的方向吗?

更新 - 添加的代码示例

注:Web浏览器指向过于地址将只工作直至并包括2016年10月3日。之后,它可能会显示不同的数据,这不是我会看到的。

在frmSelection.xaml文件

<cefSharp:ChromiumWebBrowser Name="wb" Grid.Column="1" Grid.Row="0" /> 

在frmSelection.xaml.cs文件

public partial class frmSelection : UserControl 
{ 
    private System.Windows.Threading.DispatcherTimer wbTimer = new System.Windows.Threading.DispatcherTimer(); 

    public frmSelection() 
    { 

     InitializeComponent(); 

     // This timer will start when a web page has been loaded. 
     // It will wait 4 seconds and then call wbTimer_Tick which 
     // will then see if data can be extracted from the web page. 
     wbTimer.Interval = new TimeSpan(0, 0, 4); 
     wbTimer.Tick += new EventHandler(wbTimer_Tick); 

     wb.Address = "http://www.racingpost.com/horses2/cards/card.sd?race_id=644222&r_date=2016-03-10#raceTabs=sc_"; 

     wb.FrameLoadEnd += new EventHandler<CefSharp.FrameLoadEndEventArgs>(wb_FrameLoadEnd); 

    } 

     void wb_FrameLoadEnd(object sender, CefSharp.FrameLoadEndEventArgs e) 
     { 
      if (wbTimer.IsEnabled) 
       wbTimer.Stop(); 

      wbTimer.Start(); 
     } 

    void wbTimer_Tick(object sender, EventArgs e) 
    { 
     wbTimer.Stop(); 
     string html = GetHTMLFromWebBrowser(); 
    } 

    private string GetHTMLFromWebBrowser() 
    { 
     // call the ViewSource method which will open up notepad and display the html. 
     // this is just so I can compare it to the html returned in GetSourceAsync() 
     // This is displaying all the html code (including child frames) 
      wb.GetBrowser().MainFrame.ViewSource(); 

     // Get the html source code from the main Frame. 
      // This is displaying only code in the main frame and not any child frames of it. 
      Task<String> taskHtml = wb.GetBrowser().MainFrame.GetSourceAsync(); 

      string response = taskHtml.Result; 
    return response; 
    } 

} 
+0

你能分享更多的代码吗?我无法重现您的问题,我使用'ViewSource'获取与'GetSourceAsync'相同的文本。尝试使用“地址”设置为“http:// stackoverflow.com”(它有两个框架,一个“iframe”和主框架) –

+0

感谢您的采访。我已将示例源添加到原始帖子中。 – Scott

回答

11

我不认为我完全得到这个DispatcherTimer解决方案。我会做这样的:

public frmSelection() 
{ 
    InitializeComponent(); 

    wb.FrameLoadEnd += WebBrowserFrameLoadEnded; 
    wb.Address = "http://www.racingpost.com/horses2/cards/card.sd?race_id=644222&r_date=2016-03-10#raceTabs=sc_"; 
} 

private void WebBrowserFrameLoadEnded(object sender, FrameLoadEndEventArgs e) 
{ 
    if (e.Frame.IsMain) 
    { 
     wb.ViewSource(); 
     wb.GetSourceAsync().ContinueWith(taskHtml => 
     { 
      var html = taskHtml.Result; 
     }); 
    } 
} 

我做的ViewSource输出,并在html变量的文本diff和他们是一样的,所以我不能在这里重现您的问题。

这就是说,我注意到主框架加载得相当晚,所以你必须等待一段时间,直到记事本弹出源代码。

+0

感谢您对我的代码的反馈,我有正弦更新以反映您的示例。 自从发布示例以来,我在另一台计算机上运行了代码,并获得与您相同的结果(均返回完整的源代码)。我只能断定我的机器有些奇怪的事情,我会考虑做一个格式。 – Scott

1

我有同样的问题试图获得点击和项目位于一个框架,而不是在主框架。使用在你的答案的例子中,我写了下面的扩展方法:

 public static IFrame GetFrame(this ChromiumWebBrowser browser, string FrameName) 
    { 
     IFrame frame = null; 

     var identifiers = browser.GetBrowser().GetFrameIdentifiers(); 

     foreach (var i in identifiers) 
     { 
      frame = browser.GetBrowser().GetFrame(i); 
      if (frame.Name == FrameName) 
       return frame; 
     } 

     return null; 
    } 

如果你有一个“使用”表单包含此方法,你可以做类似的模块上:

var frame = browser.GetFrame("nameofframe"); 
     if (frame != null) 
     { 
      string HTML = await frame.GetSourceAsync(); 
     } 

当然你需要确保页面加载完成才能使用它,但我打算使用它很多。希望能帮助到你!

Jim