Как вы получаете данные таблицы с веб-сайта после входа в систему с помощью powershell? - PullRequest
0 голосов
/ 17 сентября 2018

Моя компания хочет, чтобы я взял данные со своего внутреннего веб-сайта, организовал их и отправил в базу данных. Данные отображаются в таблицах, по которым вы перемещаетесь на сайте. Я хочу вытащить поля в файл или память для дальнейшей обработки.

Пока что я могу войти на сайт в 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()

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

После некоторых серьезных усилий - мне удалось заставить страницы работать правильно.Оказывается, я не ждал, пока все загрузится, но как только я получил это, я в конце концов нашел правильный тег / имя, чтобы все работало.

Предполагается, что код в исходном сообщении правильный до "ie.Navigate ($ url)"

$ ie. Navigate ($ url)

While ($ie.Busy -eq $true) {Start-Sleep -Seconds 3;}
$r = Invoke-WebRequest $url
$doc = $ie.document
$j = ($doc.getElementsByTagName("body") | Where {$_.className -eq 'thefullclassname found in the quotes of <body class="" of the area you wanted'}).innerText
write-host $j

Thisдал мне вывод очень раздражающей готовой таблицы, которая не является «таблицей» и имеет первую строку / столбец самостоятельно, так что форматирование вывода в простую в использовании версию будет новой проблемой.По крайней мере, я получил все на странице, где был текст, который мне был нужен ... так что прогресс!

0 голосов
/ 18 сентября 2018

У меня, очевидно, нет вашей страницы, и я не могу гарантировать, что тело POST от имени для входа содержит поля login и password, так что вам потребуются некоторые пробные версии и ошибки.В качестве мини-примера, если вы откроете вкладку сети консоли dev tools и отфильтруете по POST, вы сможете наблюдать, как ваша страница входа регистрирует вас. Когда я открываю reddit для входа, она отправляет POST в https://www.reddit.com/login с телом, содержащим ключ / значение username и password (оба в виде открытого текста).Это действие настраивает мой сеанс браузера для сохранения моего логина.


Вот пример кода, который использует библиотеку HtmlAgilityPack для взаимодействия с получающейся страницей, как если бы она была XML.

Включение TLS1.2:

[System.Net.ServicePointManager]::SecurityProtocol =
    [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12

Настройка веб-сеанса:

$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

Загрузка / добавление 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()

Загрузка / анализ содержимого вашей страницы:

$html.LoadHtml($output)

# do stuff with output.
$html.DocumentNode.SelectNodes('//*/text()').Text.Where{$PSItem -like '*=*'}

Сноска

Я сделал предположение в коде, который вы выполняли изскрипт где $PSScriptRoot будет заполнен.Если он запускается в интерактивном режиме, вы можете использовать вместо него автоматическую переменную $pwd (перенос из * nix, рабочий каталог печати).Для этого кода требуется PSv5 +.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...