【问题标题】:Powershell Website Automation: Javascript Popup Box FreezePowershell 网站自动化:Javascript 弹出框冻结
【发布时间】:2013-06-25 17:22:48
【问题描述】:

我正在尝试自动化用户从网站下载文件提取的过程。我的问题是,一旦单击“导出”按钮,就会出现一个 javascript 弹出窗口,其中包含提取的各种日期参数以及需要单击的最终“下载”按钮。在此 javascript 弹出窗口期间出现问题。单击导出按钮并打开弹出窗口后,powershell 似乎在脚本期间冻结,并且不允许执行任何进一步的命令。

我尝试使用 WASP 模块和 SELECT-WINDOW 来获取正确的 IE 进程窗口,但是 'Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" |选择 - 前 1 | Set-WindowActive' 命令将不会执行,因为 Powershell 在单击初始“导出”按钮后立即卡住“运行脚本”(就在弹出窗口打开时)。有没有一种方法可以在打开弹出框后“刷新”Powershell以执行进一步的命令,或者有什么想法可以打破我陷入这个Javascrip弹出窗口的连续“运行脚本”循环窗户?

# Set access URL and Credentials
$WebU='username'
$WebP='password'
$URLlogin='http://websiteurl.com'
$IEwait="1000"
# Execute IE and navigate to URL
$ie = New-Object -com "InternetExplorer.application";
$ie.visible = $True;
$ie.navigate($URLlogin);

Try{
# Login steps
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("txtLogin"))
    { $ie.Document.getElementByID("txtLogin").value = $WebU }
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("txtPassword"))
    { $ie.Document.getElementByID("txtPassword").value = $WebP }
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("btnLogin"))
    { $ie.Document.getElementByID("btnLogin").Click() }
# Navigate through website to find the 'Export' button
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("managementMenu_btnLearningResults"))
    { $ie.Document.getElementByID("managementMenu_btnLearningResults").Click() } 
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
# This is the part that freezes the script. Once the 'btnExport' button is clicked, a JS popup keeps Powershell from executing any additional commands
if ($ie.Document.getElementByID("btnExport"))
    { $ie.Document.getElementByID("btnExport").Click() } 
# Once the popoup box opens, sending the 'ENTER' key should automatically download the export file
Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select -First 1 | Set-WindowActive
Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select-childwindow | Send-Keys "{ENTER}"
}
# These won't execute because the JS popup window confuses Powershell and keeps it in a continuous 'Running Script' process
Catch {
    "Error" }
Finally {
    "Now able to execute further commands" }

【问题讨论】:

    标签: javascript powershell automation


    【解决方案1】:

    在自动化 GUI 浏览器时经常会出现这个问题 - 模态对话框(如您描述的 JS 弹出窗口)会阻止您的脚本完成,直到有人将其关闭。这是因为您对浏览器本身的调用(导致模态对话框出现)也处于阻塞状态,等待用户交互。

    根据我的经验,处理这种情况的最简单方法是启动一个单独的进程来处理模态对话框。它需要两个步骤:

    1. 编写一个小的独立脚本/程序,等待模态对话框出现,然后将其关闭。这很容易通过手动启动弹出处理脚本,然后手动执行使对话框出现的步骤来测试。

    2. 一旦你开始工作,在你的自动浏览器的主程序中,在你执行创建模态对话框的代码行之前启动你的单独的对话框处理脚本。

    就是这样。感觉很笨拙,但它几乎可以在我见过的任何情况下工作(除非模态对话框需要提升的安全权限,这会带来其他问题)。

    此外,如果您使用的编程语言支持本机线程,则可以启动单独的线程(而不是进程)来处理模式对话框。

    假设您可以绕过它并且仍然对您的测试充满信心,那么如果可能的话,简单地绕过这样的模式对话框实际上会更便宜(就脚本开发和维护时间而言)。有时这可能需要修改应用程序,为您的测试代码提供进入系统的特殊接口。

    【讨论】:

      【解决方案2】:

      IE 对象模型实际上有点危险。它经常说事情已经准备好,但实际上还没有,因为底层资源还没有加载。每次我必须与页面交互时,我都对重写这段代码感到恼火,所以我编写了一个名为 AutoBrowse 的模块来处理它:

      http://autobrowse.start-automating.com/

      改用这个,你会回避这个问题。

      希望对你有帮助

      【讨论】:

      • 我已成功配置 AutoBrowse 以让我进入 javascript 弹出事件,但是我不确定此时如何处理该窗口。你会建议我在这个阶段做什么?打开浏览器 -Url websiteurl.com -可见 | Set-BrowserControl -Id txtLogin -Value $WebU | Set-BrowserControl -Id txtPassword -Value $WebP | Invoke-BrowserControl -Id btnLogin -Click | Invoke-BrowserControl -Id managementMenu_btnLearningResults -Click | Invoke-BrowserControl -Id btnExport -Click -->*HANGS*
      • 您始终可以尝试放弃拆分管道并将结果分配回变量。每次都会在后台调用 Wait-Browser,因此您可以尝试构建一些等待特定元素出现的东西。此外,您可能想尝试在 x86 PowerShell 下启动它,因为 IE 仍然是 32 位。
      【解决方案3】:
          While ( $ie.busy -eq $true){ 
              [System.Threading.Thread]::Sleep(2000); 
              $wshell = New-Object -ComObject wscript.shell;
              if($wshell.AppActivate('Message from webpage'))
              {
                  [System.Threading.Thread]::Sleep(1000); 
                  [System.Windows.Forms.SendKeys]::SendWait('{Enter}')
              }
          }
      

      【讨论】:

      • 推荐一些解释
      猜你喜欢
      • 2018-10-20
      • 2017-03-16
      • 2014-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多