【问题标题】:Screen scraping web page containing button with AJAX屏幕抓取网页包含带有 AJAX 的按钮
【发布时间】:2017-06-18 09:24:57
【问题描述】:

我正在尝试自动化我们的一些流程,其中包括登录到外部网页、单击链接以展开详细信息,然后获取显示的所有详细信息。

我已经登录了进程,一旦展开就可以获取所有详细信息。

问题在于点击链接。该链接的定义如下(我已经删除了Submit 方法的实际作用,因为代码很长并且可能无关紧要。显然img 只是作为示例的占位符):

<a id="form:SummarySubView:closedToggleControl" onclick="A4J.AJAX.Submit(...); return false;" href="#">
    <img ... />
</a>

我使用这些数据如下:

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    WebBrowser browser = (WebBrowser)sender;

    HtmlElement expandDetails = browser.Document.GetElementById("form:SummarySubView:closedToggleControl");
    //When open ID for element is "form:SummarySubView:openToggleControl"

    if(expandDetails == null) //If already expanded
    {
        //Stuff
    }
    else
    {
        expandDetails.InvokeMember("click"); //Click on element to run AJAX
    }
}

在运行expandDetails.InvokeMember("click"); 时,browser_DocumentCompleted 会按预期再次调用,但文档与之前相同,expandDetails 再次以“已关闭”ID 找到。这意味着我正在寻找的细节永远不会显示出来。

如何在 AJAX 脚本正确运行后访问文档?

添加Timer 来延迟检查文档似乎没有用。

【问题讨论】:

    标签: c# ajax webbrowser-control screen-scraping


    【解决方案1】:

    好的,首先,document.complete 事件将为页面中的所有框架触发。因此,如果您有 5 个 Iframe,您将获得 6 个文档完成事件。

    所以你需要检查你是否真的是顶层窗口。 单独这样做可能会解决您的问题。

    private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            WebBrowser wb = sender as WebBrowser;
            //check to make sure we are on the TOP-level page.
            if (wb.Document.Window.Parent == null)
            {
                //do whatever else you need to here
            }
        }
    

    如果还是不行,您可以在文档完成后使用计时器等待几秒钟。

     public partial class Form1 : Form
     {
        Timer t;
        public Form1()
        {
            InitializeComponent();
            webBrowser1.DocumentCompleted += WebBrowser1_DocumentCompleted;
        }
        private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            WebBrowser wb = sender as WebBrowser;
    
            //check to make sure we are on the TOP-level page.
            if (wb.Document.Window.Parent == null)
            {
                t = new Timer();
                t.Tick += (Timersender, eventargs) =>
                {
                    //do whatever else you need to here
                    t.Stop();
                };
                t.Interval = 2000; //wait 2 seconds for the document to complete
                t.Start();
            }
        }
    }
    

    您可以根据需要将计时器调整为更长或更短。但这应该可以满足您的需求。

    【讨论】:

    • 那么在应用AJAX功能之前文档是完整的吗?我会试一试...
    • 我不知道你在看什么网站。他们可以以任何他们想要的方式对其进行编码。但是是的,网站很有可能在 document.complete 触发后开始调用 ajax 方法,方法是从 javascript 或 $(document).ready 从 jQuery 挂钩到 window.onload。我的意思是,至少您应该检查正在触发的 document.complete 事件是否来自顶级窗口。如果这样做还不够,您可以添加一个计时器来等待几秒钟,同时其他 ajax 完成。
    • 所以我添加了Timer,但它似乎不起作用。无论我设置Timer 多久,它仍然显示“预点击”文档。
    【解决方案2】:

    所以一个非常简单的解决方案似乎奏效了。我的代码现在看起来像:

    void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser browser = (WebBrowser)sender;
    
        HtmlElement expandDetails = browser.Document.GetElementById("form:SummarySubView:closedToggleControl");
        //When open ID for element is "form:SummarySubView:openToggleControl"
    
        if(expandDetails == null) //If already expanded
        {
            //Stuff
        }
        else
        {
            expandDetails.InvokeMember("click"); //Click on element to run AJAX
    
            while (expandDetails != null)
            {
                expandDetails = browser.Document.GetElementById("form:SummarySubView0:closedToggleControl");
    
                Application.DoEvents();
                System.Threading.Thread.Sleep(200);
            }
    
            //Stuff
        }
    }
    

    所以运行while 循环对我来说效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      相关资源
      最近更新 更多