Показать полную графическую версию : вытянуть информацию из html полученного через curl
Страниц :
1
2
3
[
4]
5
6
7
8
Griboed0ff
20-04-2020, 12:34
В данный момент ip адрес запроса это результат [array]$arr = $((Get-Netipaddress |? ipaddress -match "^10\.").ipaddress -replace "\d+$")
$ips = 130..190 |%{$n=$_;$arr|%{"$_"+$n}}|sort|?{test-connection $_ -count 1 -q} Можно ли сделать чтобы подсети брались из файла?
Например в файле 10.80.1.
10.80.26.
10.83.3. брать первую часто запроса из файла, а вторую как и раньше с 130 по 190 айпишник.
опробовал на вроде таких же страничках и посыпались ошибки. Странички приложил. »
Странички не при чем. Дело в версии powershell.
Командлет Invoke-WebRequest и Invoke-RestMethod добавлены в powershell v 3.0, а методы парсеров html, возможно и в более поздние версии...
В общем, имеет смысл обновить powershell до актуальной версии...
Да, есть нюанс: если на машине нет Internet Explorer-а, то командлеты эти использовать не получится... они тесно связаны с ним.
Ещё один нюанс: если используется powershell core, т.е. версия новее 5.1, то методы парсинга html через IE, в них уже вырезаны, там придется использовать внешние парсеры типа PowerHTML, в которых уже используется парсинг по типу XML (XPATH и т.п.)... но это уже будет совсем другой скрипт.
Griboed0ff
20-04-2020, 12:53
В общем, имеет смысл обновить powershell до актуальной версии... » такой стоит
Major Minor Build Revision
----- ----- ----- --------
5 1 15063 786
Можно ли сделать чтобы подсети брались из файла? »
Конечно. Именно так, будет лучше... кстати, это предлагал DJ Mogarych...
[array]$arr = gc 'list_Net.txt'
$ips = 130..190 |%{$n=$_;$arr|%{"$_"+$n}}|sort|?{test-connection $_ -count 1 -q}
такой стоит »
Значит отсутствует IE... в ошибках указывается на отсутствие методов...
Griboed0ff
20-04-2020, 12:59
Значит отсутствует IE... в ошибках указывается на отсутствие методов... »
IE тоже есть, может запускать не от админа.
IE тоже есть, может запускать не от админа. »
Хмм, тогда не знаю... надо проверять-тестировать, почему отсутствуют методы...
От админа или от пользователя - без разницы.
Попробую сейчас немного переделать скрипт под другой метод...
Griboed0ff
20-04-2020, 13:24
Кстати на моем пк, на других моделях айпишек скрипт отработал корректно! :up
Тогда непонятно почему на других пк не работает. Пошик не не старый, ie есть. :dont-know
Тогда непонятно почему на других пк не работает. »
может net framework не обновлен? без физического доступа, трудно что-либо предполагать...
Вот переделанный скрипт:
param (
#[parameter(Mandatory=$true)]
$encode = 65001,
[string]$outfile = 'table.csv',
[int]$number = 1
)
function convert ($from, $to){
begin{
$fenc = [text.encoding]::getencoding($from)
$tenc = [text.encoding]::getencoding($to)
}
process{
$a = $tenc.getbytes($_)
$fenc.getstring($a)
}
}
[net.servicepointmanager]::securityprotocol = 'ssl3,tls,tls11,tls12'
[array]$arr = gc 'list_Net.txt'
$ips = 130..190 |%{$n=$_;$arr|%{"$_"+$n}}|sort|?{test-connection $_ -count 1 -q}
$ips|%{
$html = iwr $_
$tables = $html.parsedhtml.getelementsbytagname("table")
$tbl = ($tables|?{($_.getelementsbytagname('table')|%{$_}).count -eq 0})[$number]|%{
$headers = @();
$tr = $_|%{$_.getelementsbytagname("tr")}
if($headers = $tr|?{$_.firstchild().tagname -eq 'th'}|
%{$_.getelementsbytagname("th")}|select -exp innertext){
if ($headers -match [char]208){$headers=$headers|convert $encode 28591}
$headers = $headers.trim()
} else {
$headers = 1..([linq.parallelenumerable]::max(
[linq.parallelenumerable]::asparallel($tr.lastchild().cellindex)
)+1)|%{"H$_"}
}
$rowind = ,1 * $headers.count
$tr.where({$_.firstchild().tagname -eq 'td'})|%{
$row = $_.getelementsbytagname("td") |? innertext -ne $null| select innertext,rowspan,colspan
if($row.innertext -match [char]208){
for($i=0;$i -lt $row.count;$i++){
$row[$i].innertext = $row[$i].innertext|convert $encode 28591
}
}
try {
$str = [ordered]@{}
$k=0
foreach ($item in $row){
if ($rowind[$k] -gt 1){
while ($rowind[$k] -gt 1){
$str[$headers[$k]] = $null
$rowind[$k] -= 1
$k++
}
}
if (($colspan = $item.colspan) -gt 1) {
$str[$headers[$k]] = if($item.innertext){
$item.innertext.trim()
} else {$null}
if ($item.rowspan -gt 1){$rowind[$k] = $item.rowspan}
$k++
while ($colspan -gt 1){
$str[$headers[$k]] = $null
$colspan -=1
if ($rowind[$k] -gt 1){$rowind[$k]-=1}
$k++
}
} else {
$str[$headers[$k]] = if($item.innertext){
$item.innertext.trim()
} else {$null}
if ($item.rowspan -gt 1){$rowind[$k] = $item.rowspan}
$k++
}
}
[pscustomobject]$str
} catch {
write-host Разметка заголовков не соответствует размерам строк -for red
write-host $_ -for cyan
}
}
}
[pscustomobject]@{
'IP' = $_
'MAC-адрес' = $tbl[([array]::indexof($tbl.h1,'MAC-адрес'))].h2
'Номер телефона' = if ([array]::indexof($tbl.h1,'Номер телефона') -ne -1){
$tbl[([array]::indexof($tbl.h1,'Номер телефона'))].h2
} else {
$tbl[([array]::indexof($tbl.h1,'Номер телефона 1'))].h2
}
'Серийный номер' = $tbl[([array]::indexof($tbl.h1,'Серийный номер'))].h2
'Номер модели' = $tbl[([array]::indexof($tbl.h1,'Номер модели'))].h2
}
} |export-csv $outfile -notype -enc utf8 -d ';'
- но тормоз получился изрядный...
Griboed0ff
20-04-2020, 18:02
- но тормоз получился изрядный... » это вообще не проблема.
Это полное решение. Работает на 4 видах айпишек.
придется из батника запускать так как на компах не включено исполнение ps скриптов. типа команда Set-ExecutionPolicy RemoteSigned и потом запуск скрипта. Есть ли варианты включить эту команду в сам скрипт, чтобы не городить батников?
Есть ли варианты включить эту команду в сам скрипт, чтобы не городить батников? »
Батником проще, ибо изменение политики запуска скриптов потребует ручного вмешательства.
Батник:
powershell -ex bypass .\script.ps1
Griboed0ff
20-04-2020, 18:31
Батник: »
я использовал такое решение, нагуглил @echo off
SetLocal EnableExtensions
set "ps=" & for %%X in (powerShell.exe) do set "ps=%%~$PATH:X"
if not defined ps set "ps=%systemRoot%\syswow64\windowsPowerShell\v1.0\powerShell.exe"
For /F "UseBackQ delims=" %%a in (`"cmd /c "
"%ps%" -ExecutionPolicy ByPass -NoProfile -command "D:\1.ps1"
""`) do (
echo %%a
)
pause объяснение было такое что по умолчанию винда может и не знать через что запускать скрипт
я использовал такое решение »
это почти то же самое, только с дополнительной проверкой переменной среды окружения PATH, на наличие пути к исполняемому файлу powershell.exe
Но, имхо, это излишне, если, конечно, эта переменная не подвергалась ручным изменениям...
Griboed0ff
21-04-2020, 09:30
Интересно есть ли ограничение по объему входных данных. Я скормил ему файлик с 700 подсетями, уже скоро как сутки чем то занят, не прерываю вдруг закончит все же.
Интересно есть ли ограничение по объему входных данных. »
Не должно быть, но можно последить за потреблением памяти...
уже скоро как сутки чем то занят »
а я предупреждал, что получился великий тормоз :)
Можно, конечно, было бы и прогрессбар прикрутить, но это только добавит "тормозов"
Чтобы проще было наблюдать, можно организовать вывод каждого IP в отдельный файл...
Griboed0ff
21-04-2020, 11:24
а я предупреждал, что получился великий тормоз » Это не страшно, просто первый раз запустил скрипт с большим объемом обрабатываемой информации и не понимал работает или нет. Реально только потребление памяти немного меняется. Так массово запускать буду редко, в основном сбор инфы только с одной подсетью. Можно, конечно, было бы и прогрессбар прикрутить, но это только добавит "тормозов" » это да лишнее, работает не трогай :)
YuS_2, помогите пожалуйста собрать теперь этого Франкенштейна (http://forum.oszone.net/thread-344921.html)
DJ Mogarych
21-04-2020, 12:47
скормил ему файлик с 700 подсетями, уже скоро как сутки чем то занят »
Когда возникают такие ситуации, это значит, что задача решается не теми методами.
Griboed0ff
21-04-2020, 13:23
Когда возникают такие ситуации, это значит, что задача решается не теми методами. » согласен, но других инструментов нет и не предвидится, поэтому лучше такой скрипт, чем собирать эти данные руками.
DJ Mogarych
21-04-2020, 22:10
Про GLPI слышали или вообще про инвентаризационный софт?
согласен, но других инструментов нет и не предвидится »
Ну почему нет... я вот упоминал про PowerHTML
Вот, скрипт на его основе:
param (
#[parameter(Mandatory=$true)]
[string]$outfile = 'table_phtml.csv',
$encode = 65001,
[int[]]$SelectTable = 1
)
#---Эту секцию можно удалить после однократного запуска скрипта от имени админа ------------------
# Установка дополнительного модуля PowerHTML, для независимого парсинга HTML
# Может потребоваться ручное подтверждение установки.
if (!(get-module -list powerhtml)) {
write-verbose "Installing PowerHTML module for the current user..."
install-module powerhtml #-scope currentuser
}
#-----------------------------------------------------------------------------------------
function convert ($from, $to){
begin{
$fenc = [text.encoding]::getencoding($from)
$tenc = [text.encoding]::getencoding($to)
}
process{
$a = $tenc.getbytes($_)
$fenc.getstring($a)
}
}
[net.servicepointmanager]::securityprotocol = 'ssl3,tls,tls11,tls12'
[array]$arr = gc 'list_Net.txt'
$ips = 130..190 |%{$n=$_;$arr|%{"$_"+$n}}|sort|?{test-connection $_ -count 1 -q}
$ips|%{
$a = (iwr $_).content
$content = if ($a -match [char]208){
$a|convert $encode 28591
} else {$a}
$html = [net.webutility]::htmldecode($content)|convertfrom-html
[array]$tables = $html.selectnodes('//table')
# Исключение вложенных таблиц:
$tables = $tables|?{$_.innerhtml -notmatch 'table'}
if ([string]::isnullorempty($selecttable)){
$number = 0..($tables.count-1)
} else {$number = $selecttable}
$tbl = $tables[$number]|%{$n=0}{
$tr = if($_.element('tbody')){
$_.element('tbody').elements('tr')
} else {$_.elements('tr')}
$headers = @()
if($headers = $tr|?{$_.element('th') -ne $null}|
%{$_.elements('th')}|select -exp innertext){
$headers=$headers.trim()
} else {
$headers = 1..(
[linq.parallelenumerable]::max(
[linq.parallelenumerable]::asparallel(($tr|
%{($_.elements('td')|? innertext -ne ''|%{$_}).count}))
)
)|%{"H$_"}
}
$rowind = ,1 * $headers.count
$tr|?{$_.elements('td') -ne $null}|%{
$row = $_.elements('td')|? innertext -ne ''|%{
$attr = $_.attributes
if ($attr){
$rowspan = ($attr|? name -eq 'rowspan'|select value).value
$colspan = ($attr|? name -eq 'colspan'|select value).value
}
[pscustomobject]@{
'InnerText' = $_.innertext
'RowSpan' = if($rowspan){[int]$rowspan} else {1}
'ColSpan' = if($colspan){[int]$colspan} else {1}
}
}
$str = [ordered]@{}
$k=0
foreach ($item in $row){
if ($rowind[$k] -gt 1){
while ($rowind[$k] -gt 1){
$str[$headers[$k]] = $null
$rowind[$k] -= 1
$k++
}
}
if (($colspan = $item.colspan) -gt 1) {
$str[$headers[$k]] = if($item.innertext){
$item.innertext.trim()
} else {$null}
if ($item.rowspan -gt 1){$rowind[$k] = $item.rowspan}
$k++
while ($colspan -gt 1){
$str[$headers[$k]] = $null
$colspan -=1
if ($rowind[$k] -gt 1){$rowind[$k]-=1}
$k++
}
} else {
$str[$headers[$k]] = if($item.innertext){
$item.innertext.trim()
} else {$null}
if ($item.rowspan -gt 1){$rowind[$k] = $item.rowspan}
$k++
}
}
[pscustomobject]$str
}
}
[pscustomobject]@{
'IP' = $_
'MAC-адрес' = $tbl[([array]::indexof($tbl.h1,'MAC-адрес'))].h2
'Номер телефона' = if ([array]::indexof($tbl.h1,'Номер телефона') -ne -1){
$tbl[([array]::indexof($tbl.h1,'Номер телефона'))].h2
} else {
$tbl[([array]::indexof($tbl.h1,'Номер телефона 1'))].h2
}
'Серийный номер' = $tbl[([array]::indexof($tbl.h1,'Серийный номер'))].h2
'Номер модели' = $tbl[([array]::indexof($tbl.h1,'Номер модели'))].h2
}
} |export-csv $outfile -notype -enc utf8 -d ';'
Плюсы:
Работает гораздо быстрее предыдущих вариантов парсинга через IE
Парсер не зависит от наличия IE в системе. Может работать на версиях Powershell Core, где встроенный парсер HTML, связанный с IE, был вырезан, т.е. работает на самых свежих версиях powershell Core...
Таблицу разбирает, также с учетом rowspan и colspan
Минусы:
Зависимость от dom-структуры, всё также, присутствует...
Возможно, что-то не учтено (собирал по-быстрому), но проверен на тех страницах, которые здесь были показаны...
Griboed0ff
22-04-2020, 07:23
Про GLPI слышали или вообще про инвентаризационный софт? » слышал конечно, но за сторонний софт будет не хорошо, иб никогда не пропустит. Поэтому встроенные средства. Скрипт нормально работает в одной подсети, а снять данные со всех айпишек это разовая задача.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.