首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#如何在使用CefSharp重定向或刷新后继续运行CefSharp代码

C#如何在使用CefSharp重定向或刷新后继续运行CefSharp代码
EN

Stack Overflow用户
提问于 2022-04-23 06:24:36
回答 2查看 132关注 0票数 0

我需要通过编程在网站上做3个动作

  1. 填充搜索输入
  2. 按下搜索按钮

(在此之后,出现一个请求,页面返回搜索结果)

  1. 单击第一个链接

如果我把动作1和2放在按钮1中:

代码语言:javascript
运行
复制
private void Button1_Click(object sender, EventArgs e)
{
string jsScript1 = "document.getElementById('story').value=" + '\'' + textFind.Text + '\'' + ";" 
+ "document.querySelector('body > div.wrapper > div.header > div.header44 > div.search_panel > span > form > button').click();";
var task1 = chrome.EvaluateScriptAsync(jsScript1);
task1.Wait();
}

和按钮2中的行动3:

代码语言:javascript
运行
复制
private void Button2_Click(object sender, EventArgs e)
{
   string jsScript3 = "document.getElementsByTagName('a')[1].click();";
   var task3 = chrome.EvaluateScriptAsync(jsScript3);
   task3.Wait();
}

一切都很完美。但我想在一个按钮里做所有这些动作。

我找到了以下解决方案:

代码语言:javascript
运行
复制
private async void ButtonFind_Click(object sender, EventArgs e)
        {
//Action 1 & 2
string jsScript1 = "document.getElementById('story').value=" + '\'' + textFind.Text + '\'' + ";" 
+ "document.querySelector('body > div.wrapper > div.header > div.header44 > div.search_panel > span > form > button').click();";
await chrome.EvaluateScriptAsync(jsScript1);



            //Action3
            Thread.Sleep(1000); //it is necessary to set exactly 1 seconds
            string jsScript3 = "document.getElementsByTagName('a')[2].click();";
            await chrome.EvaluateScriptAsync(jsScript3);

        }

我必须使用Thread.Sleep(1000);,因为在JavaScript中,重定向或单击搜索按钮会破坏当前在浏览器中运行的所有脚本。但我认为使用Thread.Sleep或Task.Delay不是一个好主意。否则,我如何才能不使用Thread.休眠/Task.Delay来更改代码?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-04-23 09:10:04

您可以使用以下内容来等待页面加载

代码语言:javascript
运行
复制
// create a static class for the extension method 
public static Task<LoadUrlAsyncResponse> WaitForLoadAsync(this IWebBrowser browser)
{
    var tcs = new TaskCompletionSource<LoadUrlAsyncResponse>(TaskCreationOptions.RunContinuationsAsynchronously);

    EventHandler<LoadErrorEventArgs> loadErrorHandler = null;
    EventHandler<LoadingStateChangedEventArgs> loadingStateChangeHandler = null;

    loadErrorHandler = (sender, args) =>
    {
        //Actions that trigger a download will raise an aborted error.
        //Generally speaking Aborted is safe to ignore
        if (args.ErrorCode == CefErrorCode.Aborted)
        {
            return;
        }

        //If LoadError was called then we'll remove both our handlers
        //as we won't need to capture LoadingStateChanged, we know there
        //was an error
        browser.LoadError -= loadErrorHandler;
        browser.LoadingStateChanged -= loadingStateChangeHandler;

        tcs.TrySetResult(new LoadUrlAsyncResponse(args.ErrorCode, -1));
    };

    loadingStateChangeHandler = (sender, args) =>
    {
        //Wait for while page to finish loading not just the first frame
        if (!args.IsLoading)
        {
            browser.LoadError -= loadErrorHandler;
            browser.LoadingStateChanged -= loadingStateChangeHandler;
            var host = args.Browser.GetHost();

            var navEntry = host?.GetVisibleNavigationEntry();

            int statusCode = navEntry?.HttpStatusCode ?? -1;

            //By default 0 is some sort of error, we map that to -1
            //so that it's clearer that something failed.
            if (statusCode == 0)
            {
                statusCode = -1;
            }

            tcs.TrySetResult(new LoadUrlAsyncResponse(statusCode == -1 ? CefErrorCode.Failed : CefErrorCode.None, statusCode));
        }
    };

    browser.LoadingStateChanged += loadingStateChangeHandler;
    browser.LoadError += loadErrorHandler;

    return tcs.Task;
}

// usage example 
await Task.WhenAll(chrome.WaitForLoadAsync(), chrome.EvaluateScriptAsync(script));
票数 1
EN

Stack Overflow用户

发布于 2022-04-26 09:16:08

你绝不能以这种方式使用睡眠。Web可能会花费更多的时间或更少的时间,而您的代码在一段时间内就会失败。您必须始终在异步模式下工作。如果需要,您可以在出现错误的情况下放置超时,但在正常模式下,请始终等到得到所需的超时。

例如,单击该按钮并设置计时器以等待链接的出现。然后,导航到第一个链接。

在其他情况下,当出现真正的导航而丢失JavaScript上下文时,可以使用绑定对象将C#应用程序和浏览器组合在一起。这样做,您可以从您的JavaScript查询您在做什么,并从JavaScript向您的C#代码提供反馈。这是坚持国家的一种方式。

一个典型的示例是,当您填写一些表单并单击“继续”,继续.在几页中导航。如果要收集所有信息,则需要绑定对象。我将它与json序列化一起使用来管理更复杂的数据。

如果您要在浏览器中进行大量工作,我建议您将自己的脚本插入到您导航的页面中。在此表单中,您可以在加载的页面中使用您自己的类。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71977392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档