Search code examples
c#webview2

How to download the first item in a page after the page complete loading


I want to download the specific file (the first item of the page) from a website, below is my code

using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeAsyc();
        }

        async void InitializeAsyc()
        {
            await webView21.EnsureCoreWebView2Async(null);
            webView21.CoreWebView2.Navigate("https://www.moodys.com");
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            var checkJs = "document.documentElement.innerText.indexOf('Sign In or Register')>-1";
            string res = await webView21.CoreWebView2.ExecuteScriptAsync(checkJs);
            //MessageBox.Show(res);

            if (res == "true")
            {
                MessageBox.Show("Please login Moody's");
            }
            else
            {
                MessageBox.Show("Successful");
                webView21.CoreWebView2.Navigate("https://www.moodys.com/search?keyword=Annual%20default%20study%20excel&searchfrom=GS");

                webView21.NavigationCompleted += webView21_NavigationCompleted;
            }
        }
        private void webView21_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
        {
            var checkfirst = "document.querySelector('.result-details > .result-detail:nth-child(1) a').getAttribute('href')";
            var result = webView21.CoreWebView2.ExecuteScriptAsync(checkfirst);
            webView21.CoreWebView2.Navigate("http://www.moodys.com/" + result);
        }
    }
}

But I found that webView21_NavigationCompleted part always run before complete loading the page, and always returns null then I fail to download.

Are there a method to load the js after the page complete loaded?


Solution

  • Thanks to all who try to help me in this problem.

    Although the solution is not perfect enough, it can help me to deal with the problem. I use wait time for 10 seconds and start doing the next steps afterwards. And I also use the TAB key to download the necessary documents.

    If there are any good solutions you find please tell me, thank you.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using Microsoft.Web.WebView2.Core;
    using Microsoft.Web.WebView2.WinForms;
    
    namespace WinFormsApp2
    {
        public partial class Form1 : Form
        {
            private static readonly string indexUrl = "http://www.moodys.com";
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private async void Form1_Load(object sender, EventArgs e)
            {
                await InitializeAsync(webView21);
            }
    
            public async Task InitializeAsync(WebView2 webView21)
            {
                CoreWebView2Environment webView2Environment = null;
                await webView21.EnsureCoreWebView2Async(webView2Environment);
            }
    
            private void webView21_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
            {
                webView21.CoreWebView2.Navigate(indexUrl);
            }
    
            private void webView21_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
            {
                string url = webView21.CoreWebView2.Source.ToString();
                Console.WriteLine(url);
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                bool res = IsLogin();
    
                if (res == true)
                {
                    MessageBox.Show("Please login Moody's");
                }
                else
                {
                    MessageBox.Show("Successful");
                    webView21.CoreWebView2.Navigate("https://www.moodys.com/search?keyword=Annual%20default%20study%20excel&searchfrom=GS");
                    int waittime = 10; //wait 10 seconds
                    int actualwaittime = waittime * 1000;
                    wait(actualwaittime);
                    SendKeys.SendWait("{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}");
                    SendKeys.SendWait("{ENTER}");
                }
            }
    
            public void wait(int milliseconds)
            {
                var timer1 = new System.Windows.Forms.Timer();
                if (milliseconds == 0 || milliseconds < 0) return;
    
                // Console.WriteLine("start wait timer");
                timer1.Interval = milliseconds;
                timer1.Enabled = true;
                timer1.Start();
    
                timer1.Tick += (s, e) =>
                {
                    timer1.Enabled = false;
                    timer1.Stop();
                    // Console.WriteLine("stop wait timer");
                };
    
                while (timer1.Enabled)
                {
                    Application.DoEvents();
                }
            }
    
            private bool IsLogin()
            {
                var js = @"document.documentElement.innerText.indexOf('Sign In or Register');";
                int res = Convert.ToInt32(ExecuteScript(js));
                return res >= 1;
            }
    
            private string ExecuteScript(string javaScript)
            {
                var taskAwaiter = webView21.CoreWebView2.ExecuteScriptAsync(javaScript).GetAwaiter();
                WaitAsyncTask(5, taskAwaiter);
                return taskAwaiter.GetResult();
            }
    
            public void WaitAsyncTask(int waitSecond, System.Runtime.CompilerServices.TaskAwaiter<string> activeTask)
            {
                DateTime WaitStartTime = DateTime.Now;
                double secondDiffer = (DateTime.Now - WaitStartTime).TotalSeconds;
                while (secondDiffer < waitSecond)
                {
                    secondDiffer = (DateTime.Now - WaitStartTime).TotalSeconds;
                    Application.DoEvents();
                    if (activeTask.IsCompleted)
                    {
                        break;
                    }
                }
            }
        }
    }