使用 powershell 从页面获取信息
Getting info from a page with powershell
所以我想使用 powershell 自动执行这个简单的操作:
- 转到我的网站
- 用"myname"
填充"USERNAME"
- 选中 "PERSONNEL_NBR" 复选框
- 提交
- 检索 PERSONNEL_NBR 并将其存储在变量中
注意:任何解决方案都适合我
我想使用 Invoke-WebRequest 因为它不会启动正确的 IE 会话来工作。将不胜感激!
此代码:
$ie = $null
$ie = new-object -com internetexplorer.application
$ie.navigate('http://example.com/')
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.name -eq "username"}; $link.value = "myname"
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.value -eq "PERSONNEL_NBR"}; $link.click()
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.type -eq "submit"}; $link.click()
sleep 2
$personnel_nbr = ((($ie.Document.body.outerHTML | findstr /L /C:">PERSONNEL_NBR<" ) -split "<SPAN class=tx>" | Select -Index 1).split("</SPAN>",2) | Select -Index 0)
$ie.quit()
有效,但前提是我打开 powershell 并从那里启动命令。如果我将它另存为脚本并启动它,它就不起作用。
PS: 降低 IE 安全性是不可行的,无论如何它都不能解决问题。
PPS: 上面的版本是我使用的代码的简化版本,没有跑题的东西。完整版正在等待浏览器,仍然无法使用(可能是由于 cookie 问题?如果有人可以建议如何做,我很乐意解决。我已经有关于 cookie 的信息,我重新注册了post 和 Chrome 开发工具。我只是不知道如何在我的脚本中使用这些信息。)
PPPS: 如果问题与交互模式有关,我不能在另一个模拟交互会话的 powershell 中执行所有这些命令吗?那行得通。有人知道怎么做吗?
第二个版本
这是另一种尝试。没有错误,但它 returns 我的页面内容。我什至不确定请求是否通过。
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$cookie = New-Object System.Net.Cookie
$cookie.Name = "mycookiename"
$cookie.Value = "mycookievalue"
$cookie.Path = "/"
$cookie.Domain = "example.com"
$session.Cookies.Add($cookie)
$uri = "http://example.com"
$body = @{username="myname";fields="PERSONNEL_NBR"}
#THESE ARE UNSUCCESSFUL ATTEMPTS
#$r = Invoke-WebRequest -Uri $uri -WebSession $session
#$r.InputFields[34].innerHTML = "true"
#$r.InputFields[34].innerText = "true"
#$r.Forms[0].Fields["fields"] = "PERSONNEL_NBR"
#$r.Forms[0].Fields["PERSONNEL_NBR"] = "true"
#$r.InputFields[0].innerText="myname"
#$r.Forms[0].Fields["username"] = "myname"
#$r = Invoke-WebRequest -Uri $uri -WebSession $session -Method Post -Body $r
$r = Invoke-WebRequest -Uri $uri -WebSession $session -Method Post -Body $body
$r.RawContent
使用 IE 通信对象有一些烦人的事情,但它们大多可以克服,例如使用 .visible = $false
将隐藏 IE window。
检查 .Busy
以查看页面实际加载的时间。您可能会发现您的脚本未作为独立脚本执行的原因是它 运行 很快。
$ie = New-Object -com internetexplorer.application;
$ie.visible = $false;
$ie.navigate('http://mypioneer.phibred.com/ews/');
while ($ie.Busy -eq $true)
{
Start-Sleep -Seconds 2;
}
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.name -eq "username"}; $link.value = "medada"
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.value -eq "PERSONNEL_NBR"}; $link.click()
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.type -eq "submit"}; $link.click()
while ($ie.Busy -eq $true)
{
Start-Sleep -Seconds 2;
}
$personnel_nbr = ((($ie.Document.body.outerHTML | findstr /L /C:">PERSONNEL_NBR<" ) -split "<SPAN class=tx>" | Select -Index 1).split("</SPAN>",2) | Select -Index 0)
Write-Host $personnel_nbr
$ie.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie)
Remove-Variable ie
另一种方法是尝试捕获表单提交 POST 数据并使用列出的工具之一重新创建 POST 传输 here
如果你需要在你的POST请求中使用cookie,你需要创建Cookie对象,将它添加到一个WebRequestSession对象中,并作为invoke-webrequest的WebSession参数:
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$cookie = New-Object System.Net.Cookie
$cookie.Name = "cookieName"
$cookie.Value = "cookieValue"
$cookie.Domain = "cookieDomain"
$session.Cookies.Add($cookie)
Invoke-WebRequest -Uri $uri -WebSession $session -Method Post -Body $body
$body
变量是post请求的内容,所以你需要使用你收集到的关于post请求的信息来创建它。它看起来像这样:
$body = @{
username = "medada"
input name = value
...
}
好的,所以.. 阻止脚本运行的问题既不是交互模式也不是 cookie。问题出在管理员权限上。
因此这段代码完美运行:
$ie = $null
$ie = new-object -com internetexplorer.application
$ie.navigate('http://example.com')
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.name -eq "username"}; $link.value = "myname"
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.value -eq "PERSONNEL_NBR"}; $link.click()
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.type -eq "submit"}; $link.click()
while ($ie.Busy -eq $true -and $timer -lt 10) {
sleep 1
$timer++
echo "Waiting for example.com..."
}
if ($timer -gt 10) {
while ($confirmation -ne "y" -and $confirmation -ne "n") {
$confirmation = Read-Host "`nConnection timed out. Do you want to try to grab it manually? (y/n)"
if ($confirmation -eq 'y') {
echo "`nPlease go to this page:`nhttp://example.com and put `"$username`" in the `"USERNAME`" field, then check the `"PERSONNEL_NBR`" checkbox and then submit."
Read-Host "`nPERSONNEL_NBR"
}
elseif ($confirmation -eq 'y') {
echo "`nRemember to add the PERSONNEL_NBR later!"
}
else {
echo "`nInvalid option."
}
}
$confirmation=$null
}
$personnel_nbr = ((($ie.Document.body.outerHTML | findstr /L /C:">PERSONNEL_NBR<" ) -split "<SPAN class=tx>" | Select -Index 1).split("</SPAN>",2) | Select -Index 0)
echo "The PERSONNEL_NBR is $personnel_nbr"
$ie.quit()
您只需要运行它作为管理员。感谢大家,感谢你们的帮助和时间。
所以我想使用 powershell 自动执行这个简单的操作:
- 转到我的网站
- 用"myname" 填充"USERNAME"
- 选中 "PERSONNEL_NBR" 复选框
- 提交
- 检索 PERSONNEL_NBR 并将其存储在变量中
注意:任何解决方案都适合我
我想使用 Invoke-WebRequest 因为它不会启动正确的 IE 会话来工作。将不胜感激!
此代码:
$ie = $null
$ie = new-object -com internetexplorer.application
$ie.navigate('http://example.com/')
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.name -eq "username"}; $link.value = "myname"
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.value -eq "PERSONNEL_NBR"}; $link.click()
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.type -eq "submit"}; $link.click()
sleep 2
$personnel_nbr = ((($ie.Document.body.outerHTML | findstr /L /C:">PERSONNEL_NBR<" ) -split "<SPAN class=tx>" | Select -Index 1).split("</SPAN>",2) | Select -Index 0)
$ie.quit()
有效,但前提是我打开 powershell 并从那里启动命令。如果我将它另存为脚本并启动它,它就不起作用。
PS: 降低 IE 安全性是不可行的,无论如何它都不能解决问题。
PPS: 上面的版本是我使用的代码的简化版本,没有跑题的东西。完整版正在等待浏览器,仍然无法使用(可能是由于 cookie 问题?如果有人可以建议如何做,我很乐意解决。我已经有关于 cookie 的信息,我重新注册了post 和 Chrome 开发工具。我只是不知道如何在我的脚本中使用这些信息。)
PPPS: 如果问题与交互模式有关,我不能在另一个模拟交互会话的 powershell 中执行所有这些命令吗?那行得通。有人知道怎么做吗?
第二个版本
这是另一种尝试。没有错误,但它 returns 我的页面内容。我什至不确定请求是否通过。
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$cookie = New-Object System.Net.Cookie
$cookie.Name = "mycookiename"
$cookie.Value = "mycookievalue"
$cookie.Path = "/"
$cookie.Domain = "example.com"
$session.Cookies.Add($cookie)
$uri = "http://example.com"
$body = @{username="myname";fields="PERSONNEL_NBR"}
#THESE ARE UNSUCCESSFUL ATTEMPTS
#$r = Invoke-WebRequest -Uri $uri -WebSession $session
#$r.InputFields[34].innerHTML = "true"
#$r.InputFields[34].innerText = "true"
#$r.Forms[0].Fields["fields"] = "PERSONNEL_NBR"
#$r.Forms[0].Fields["PERSONNEL_NBR"] = "true"
#$r.InputFields[0].innerText="myname"
#$r.Forms[0].Fields["username"] = "myname"
#$r = Invoke-WebRequest -Uri $uri -WebSession $session -Method Post -Body $r
$r = Invoke-WebRequest -Uri $uri -WebSession $session -Method Post -Body $body
$r.RawContent
使用 IE 通信对象有一些烦人的事情,但它们大多可以克服,例如使用 .visible = $false
将隐藏 IE window。
检查 .Busy
以查看页面实际加载的时间。您可能会发现您的脚本未作为独立脚本执行的原因是它 运行 很快。
$ie = New-Object -com internetexplorer.application;
$ie.visible = $false;
$ie.navigate('http://mypioneer.phibred.com/ews/');
while ($ie.Busy -eq $true)
{
Start-Sleep -Seconds 2;
}
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.name -eq "username"}; $link.value = "medada"
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.value -eq "PERSONNEL_NBR"}; $link.click()
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.type -eq "submit"}; $link.click()
while ($ie.Busy -eq $true)
{
Start-Sleep -Seconds 2;
}
$personnel_nbr = ((($ie.Document.body.outerHTML | findstr /L /C:">PERSONNEL_NBR<" ) -split "<SPAN class=tx>" | Select -Index 1).split("</SPAN>",2) | Select -Index 0)
Write-Host $personnel_nbr
$ie.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie)
Remove-Variable ie
另一种方法是尝试捕获表单提交 POST 数据并使用列出的工具之一重新创建 POST 传输 here
如果你需要在你的POST请求中使用cookie,你需要创建Cookie对象,将它添加到一个WebRequestSession对象中,并作为invoke-webrequest的WebSession参数:
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$cookie = New-Object System.Net.Cookie
$cookie.Name = "cookieName"
$cookie.Value = "cookieValue"
$cookie.Domain = "cookieDomain"
$session.Cookies.Add($cookie)
Invoke-WebRequest -Uri $uri -WebSession $session -Method Post -Body $body
$body
变量是post请求的内容,所以你需要使用你收集到的关于post请求的信息来创建它。它看起来像这样:
$body = @{
username = "medada"
input name = value
...
}
好的,所以.. 阻止脚本运行的问题既不是交互模式也不是 cookie。问题出在管理员权限上。
因此这段代码完美运行:
$ie = $null
$ie = new-object -com internetexplorer.application
$ie.navigate('http://example.com')
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.name -eq "username"}; $link.value = "myname"
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.value -eq "PERSONNEL_NBR"}; $link.click()
$link = $ie.Document.getElementsByTagName('input') | where-object {$_.type -eq "submit"}; $link.click()
while ($ie.Busy -eq $true -and $timer -lt 10) {
sleep 1
$timer++
echo "Waiting for example.com..."
}
if ($timer -gt 10) {
while ($confirmation -ne "y" -and $confirmation -ne "n") {
$confirmation = Read-Host "`nConnection timed out. Do you want to try to grab it manually? (y/n)"
if ($confirmation -eq 'y') {
echo "`nPlease go to this page:`nhttp://example.com and put `"$username`" in the `"USERNAME`" field, then check the `"PERSONNEL_NBR`" checkbox and then submit."
Read-Host "`nPERSONNEL_NBR"
}
elseif ($confirmation -eq 'y') {
echo "`nRemember to add the PERSONNEL_NBR later!"
}
else {
echo "`nInvalid option."
}
}
$confirmation=$null
}
$personnel_nbr = ((($ie.Document.body.outerHTML | findstr /L /C:">PERSONNEL_NBR<" ) -split "<SPAN class=tx>" | Select -Index 1).split("</SPAN>",2) | Select -Index 0)
echo "The PERSONNEL_NBR is $personnel_nbr"
$ie.quit()
您只需要运行它作为管理员。感谢大家,感谢你们的帮助和时间。