使用powershell登录后,如何从网站获取表数据?
我的公司希望我从他们的内部网站抓取数据,组织起来,然后发送到数据库。数据显示在站点内导航到的表上。我想将这些字段拉入文件或内存,以便进一步处理 到目前为止,我可以通过获取提交登录按钮的ID并传递我的用户名/密码登录到powershell中的站点。我能够通过使用导航方法将页面更改为站点中的相应页面。但是,在新页面上运行Invoke WebRequest以及在新页面上使用Net.WebClient都会返回在原始站点的登录屏幕上找到的信息(我知道,因为表中的任何内容都不会将其包含在返回的值中,无论我使用什么命令)。注释的代码是我以前尝试过的 这是代码减去我的id/密码/站点链接的值使用powershell登录后,如何从网站获取表数据?,powershell,request,Powershell,Request,我的公司希望我从他们的内部网站抓取数据,组织起来,然后发送到数据库。数据显示在站点内导航到的表上。我想将这些字段拉入文件或内存,以便进一步处理 到目前为止,我可以通过获取提交登录按钮的ID并传递我的用户名/密码登录到powershell中的站点。我能够通过使用导航方法将页面更改为站点中的相应页面。但是,在新页面上运行Invoke WebRequest以及在新页面上使用Net.WebClient都会返回在原始站点的登录屏幕上找到的信息(我知道,因为表中的任何内容都不会将其包含在返回的值中,无论我使
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Visible= $true # Make it visible
$username="myid"
$password="mypw"
$ie.Navigate("https://webpage.com/index.jsp")
While ($ie.Busy -eq $true) {Start-Sleep -Seconds 3;}
$usernamefield = $ie.document.getElementByID('login')
$usernamefield.value = "$username"
$passwordfield = $ie.document.getElementByID('password')
$passwordfield.value = "$password"
$Link = $ie.document.getElementByID('SubmitLogin')
$Link.click()
$url = "https://webpage.com/home.pa#%5BT1%2CM181%5D"
$ie.Navigate($url)
While ($ie.Busy -eq $true) {Start-Sleep -Seconds 3;}
$doc = $ie.document
$web = New-Object Net.WebClient
$web.DownloadString($url)
#$r = Invoke-WebRequest $url
#$r.Forms.fields | get-member
#$InnerText = $r.AllElements |
# Where-Object {$_.tagName -ne "TD" -and $_.innerText -ne $null} |
# Select -ExpandProperty innerText
#write-host $InnerText
#$r.AllElements|Where-Object {$_.InnerHtml -like "*=*"}
#$doc = $ie.Document
#$doc.getElementByID("ext-element-7") | % {
# if ($_.id -ne $null){
# write-host $_.id
# }
#}
$ie.Quit()
我显然没有您的页面,也无法确保登录后的
帖子
的正文包含登录
和密码
字段,因此需要您进行一些尝试。作为一个小示例,如果打开console dev tools network选项卡并按POST
进行筛选,您可以观察登录页面是如何登录的。当我打开reddit登录时,它会向https://www.reddit.com/login
正文包含用户名
和密码
键/值(均为纯文本)。此操作将设置我的浏览器会话以保持我的登录
下面是一个代码示例,它使用
HtmlAgilityPack
库与生成的页面进行交互,就像它是XML
一样
启用TLS1.2:
[System.Net.ServicePointManager]::SecurityProtocol =
[System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12
设置web会话:
$iwrParams = @{
'Uri' = 'https://webpage.com/index.jsp'
'Method' = 'POST'
'Body' = @{
'login' = $username
'password' = $password
}
'SessionVariable' = 'session'
# avoids cases where IE has not been opened
'UseBasicParsing' = $true
}
# don't care about response - only here to initialize the session
$null = Invoke-WebRequest @iwrParams
获取保护页面内容:
$iwrParams = @{
'Uri' = 'https://webpage.com/home.pa#%5BT1%2CM181%5D'
'WebSession' = $session
'UseBasicParsing' = $true
}
$output = (Invoke-WebRequest @iwrParams).Content
$html.LoadHtml($output)
# do stuff with output.
$html.DocumentNode.SelectNodes('//*/text()').Text.Where{$PSItem -like '*=*'}
下载/添加HtmlAgility
:
if (-not (Test-Path -Path "$PSScriptRoot\HtmlAgilityPack.dll" -PathType Leaf))
{
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/HtmlAgilityPack -OutFile "$PSScriptRoot\html.zip"
Expand-Archive -Path "$PSScriptRoot\html.zip" -DestinationPath "$PSScriptRoot\html" -Force
Copy-Item -Path "$PSScriptRoot\html\lib\netstandard2.0\HtmlAgilityPack.dll" -Destination "$PSScriptRoot\"
Remove-Item -Path "$PSScriptRoot\html", "$PSScriptRoot\html.zip" -Recurse -Force
}
Add-Type -Path "$PSScriptRoot\HtmlAgilityPack.dll"
$html = [HtmlAgilityPack.HtmlDocument]::new()
加载/分析页面内容:
$iwrParams = @{
'Uri' = 'https://webpage.com/home.pa#%5BT1%2CM181%5D'
'WebSession' = $session
'UseBasicParsing' = $true
}
$output = (Invoke-WebRequest @iwrParams).Content
$html.LoadHtml($output)
# do stuff with output.
$html.DocumentNode.SelectNodes('//*/text()').Text.Where{$PSItem -like '*=*'}
脚注
我在代码中做了一个假设,您正在执行一个脚本,其中将填充
$PSScriptRoot
。如果以交互方式运行,则可以使用$pwd
自动变量(从*nix、打印工作目录结转)。这段代码需要PSv5+。经过一些认真的努力,我成功地使页面正常工作。事实证明,我并不是在等待加载所有内容,但一旦加载完毕,我最终找到了正确的标签/名称,使所有内容都正常工作
假设原始帖子中的代码在“ie.Navigate($url)”之前是正确的
$ie.Navigate($url)
While($ie.Busy-eq$true){Start Sleep-Seconds 3;}
$r=调用WebRequest$url
$doc=$ie.document
$j=($doc.getElementsByTagName(“body”)|其中{$\.className-eq'在的引号中找到的完整的类名你看了问题的答案了吗?我只是看了那个问题,我无法使用列出的方法/代码提取任何数据。我一直得到一个空值表达式,所以我认为仍然缺少一些东西。你试过不使用IE com对象吗?原谅我,你的答案是it’很好,但是我可以通过脚本很好地登录到网站。我的意思是,我甚至可以在新页面的窗口中看到它的变化。我似乎无法获取新的数据page@KingofNES我理解这一点,但使用这种方法,您可以从页面中提取信息,并删除对IE&com对象的依赖。