使用powershell登录后,如何从网站获取表数据?

使用powershell登录后,如何从网站获取表数据?,powershell,request,Powershell,Request,我的公司希望我从他们的内部网站抓取数据,组织起来,然后发送到数据库。数据显示在站点内导航到的表上。我想将这些字段拉入文件或内存,以便进一步处理 到目前为止,我可以通过获取提交登录按钮的ID并传递我的用户名/密码登录到powershell中的站点。我能够通过使用导航方法将页面更改为站点中的相应页面。但是,在新页面上运行Invoke WebRequest以及在新页面上使用Net.WebClient都会返回在原始站点的登录屏幕上找到的信息(我知道,因为表中的任何内容都不会将其包含在返回的值中,无论我使

我的公司希望我从他们的内部网站抓取数据,组织起来,然后发送到数据库。数据显示在站点内导航到的表上。我想将这些字段拉入文件或内存,以便进一步处理

到目前为止,我可以通过获取提交登录按钮的ID并传递我的用户名/密码登录到powershell中的站点。我能够通过使用导航方法将页面更改为站点中的相应页面。但是,在新页面上运行Invoke WebRequest以及在新页面上使用Net.WebClient都会返回在原始站点的登录屏幕上找到的信息(我知道,因为表中的任何内容都不会将其包含在返回的值中,无论我使用什么命令)。注释的代码是我以前尝试过的

这是代码减去我的id/密码/站点链接的值

[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对象的依赖。