web-dev-qa-db-ja.com

CefSharp WebブラウザーからHTMLソースコードを取得する

ACefSharp.Wpf.ChromiumWebBrowser(バージョン47.0.3.0)を使用してWebページをロードしています。ページが読み込まれた後、ソースコードを取得したいです。

私は電話した:

wb.GetBrowser().MainFrame.GetSourceAsync()

ただし、すべてのソースコードを返すわけではありません(子フレームがあるためだと思います)。

私が電話した場合:

wb.GetBrowser().MainFrame.ViewSource() 

すべてのソースコード(内部フレームを含む)の一覧が表示されています。

ViewSource()と同じ結果を取得したいと思います。誰かが正しい方向に私を指し示すことができますか?

更新–追加されたコード例

注:Webブラウザーが指しているアドレスも、2016年3月10日までしか機能しません。その後、別のデータが表示されることがありますが、これは私が見ているものではありません。

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;
  }

}
12
Scott

私はこの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変数のテキストの差分を作成しましたが、これらは同じであるため、ここで問題を再現することはできません。

これは、メインフレームがかなり遅く読み込まれることに気づいたので、メモ帳がソースでポップアップするまでかなり待たなければなりません。

17
Szabolcs Dézsi

私は同じ問題を抱えていて、クリックしてアイテムをメインフレームではなくフレームに配置しようとしていました。回答の例を使用して、次の拡張メソッドを作成しました。

        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();
        }

もちろん、これを使用する前にページの読み込みが完了していることを確認する必要がありますが、私はそれを多く使用する予定です。それが役に立てば幸い!

ジム

1
Jim Wilcox