Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - вытянуть информацию из html полученного через curl

Ответить
Настройки темы
PowerShell - вытянуть информацию из html полученного через curl

Старожил


Сообщения: 211
Благодарности: 2

Профиль | Отправить PM | Цитировать


Изменения
Автор: Griboed0ff
Дата: 17-09-2021
Доброго всем времени суток. Есть задача, которую надо решить именно через bat. Через curl скачивается страничка и из нее нужно извлечь нужную информацию, на скрине отмечено, что нужно вытянуть мак-адрес, номер телефона, модель и серийный номер. На данный момент батник уже может: узнает какая подсеть на компе, потом сканит диапазон из этой подсети, потом curl скачивает странички с айпишки с данными. А вот далее нужно, чтобы батник мог как-то вытянуть данные со странички и плюс как-то мог сам подставить все странички, которые есть в папке.

Отправлено: 08:26, 16-04-2020

 

Старожил


Сообщения: 211
Благодарности: 2

Профиль | Отправить PM | Цитировать


Цитата YuS_2:
-есть проверка существования хостов и если они не отвечают, то в массив не должны попадать... »
Убрал первую проверку пингом и дело пошло быстрее намного.
Скрытый текст
Код: Выделить весь код
param (
	#[parameter(Mandatory=$true)]
	[string]$outfile = 'C:\Users\svushak2\Desktop\all_phone.csv',
	$enc1 = 65001,
	$enc2 = 28591,
	[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 'C:\Users\svushak2\Desktop\all_ip.txt'
$ips = 130..190 |%{$n=$_;$arr|%{"$_"+$n}}|sort

$ips|%{
	if (test-connection $_ -count 1 -q){
		try {
			$a = (iwr $_).content
			#$a = gc $_ -raw -enc utf8
			$content = if ($a -match [char]208){
				if ($a -match 'windows-1251'){$enc1,$enc2 = 1251,1252}
				$a|convert $enc1 $enc2
			} 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 ''}|%{
					$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-адрес' 		= if ([array]::indexof($tbl.h1,'MAC-адрес') -ne -1){
										$tbl[([array]::indexof($tbl.h1,'MAC-адрес'))].h2
									  } else {$tbl[([array]::indexof($tbl.h1,'MAC Address'))].h2}
				'Номер телефона'	= if ([array]::indexof($tbl.h1,'Номер телефона') -ne -1){
										$tbl[([array]::indexof($tbl.h1,'Номер телефона'))].h2
									  } elseif ([array]::indexof($tbl.h1,'Номер телефона 1') -ne -1){
									  	$tbl[([array]::indexof($tbl.h1,'Номер телефона 1'))].h2
									  } else {
									  	$tbl[([array]::indexof($tbl.h1,'Phone DN'))].h2
									  }
				'Серийный номер'	= if ([array]::indexof($tbl.h1,'Серийный номер') -ne -1){
										$tbl[([array]::indexof($tbl.h1,'Серийный номер'))].h2
									  } else {$tbl[([array]::indexof($tbl.h1,'Serial Number'))].h2}
				'Номер модели'		= if ([array]::indexof($tbl.h1,'Номер модели') -ne -1){
										$tbl[([array]::indexof($tbl.h1,'Номер модели'))].h2
									  } else {$tbl[([array]::indexof($tbl.h1,'Model Number'))].h2}
			}
		} catch {
			write-host Ошибка: $_ -for red
		}
	}
}  |export-csv $outfile -notype -enc utf8 -d ';' -append
Интересно если вообще пинг убрать, то еще быстрее будет?

Может пошик умеет пинговать многопоточно? а то получается большой объем когда скрипту даешь, то это надолго и непонятно когда он закончит, потому что из списка подсетей пингует не по порядку как в файле, а в каком-то своем порядке, а так было бы понятно по результату хотя бы.

скормил скрипту 2500 подсетей, уже неделю файл заполняет, но заполняет

Отправлено: 12:09, 08-05-2020 | #101



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1218
Благодарности: 509

Профиль | Отправить PM | Цитировать


Цитата Griboed0ff:
Интересно если вообще пинг убрать, то еще быстрее будет? »
если его убрать, то будут ошибки... выше Вы сами о них сообщали.

Кстати, код я немного изменил, в этой части:
Скрытый текст
Код: Выделить весь код
$ips|%{
	if (test-connection $_ -count 1 -q){
		try {
			$a = (iwr $_).content
			$content = if ($a -match [char]208){
				if ($a -match 'windows-1251'){$enc1,$enc2 = 1251,1252}
				$a|convert $enc1 $enc2
			} else {$a}
			$html = [net.webutility]::htmldecode($content)|convertfrom-html
			[array]$tables = $html.selectnodes('//table')
			# Исключение вложенных таблиц:
			$tables = $tables|?{$_.selectnodes('.//table') -eq $null}
			$tbl = $tables[$number]|%{$n=0}{
				$tr = $_.selectnodes('.//tr')
				$headers = @()
				if ($headers = $_.selectnodes('.//th')){
					$headers = ($headers|select -exp innertext).trim()
				} else {
					$headers = 1..([linq.parallelenumerable]::max(
						[linq.parallelenumerable]::asparallel(
							($tr|%{$_.selectnodes('.//td').count})
						)
					))|%{"H$_"}
				}
				$rowind = ,1 * $headers.count
				$tr|?{$_.selectnodes('.//td') -ne $null}|%{
					$row = $_.selectnodes('.//td')|%{
						$attr = $_.attributes
						if ($attr){
							$rowspan = ($attr|? name -eq 'rowspan').value
							$colspan = ($attr|? name -eq 'colspan').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
				}
			}
			$parr1 = $tbl.h1
			if ($tbl.h2 -ne $null) {$parr2 = $tbl.h2} else {$parr2 = $tbl.h3}
			[pscustomobject]@{
				'IP'				= $_
				'MAC-адрес' 		= if ([array]::indexof($parr1,'MAC-адрес') -ne -1) {
										$parr2[([array]::indexof($parr1,'MAC-адрес'))]
									  } else {$parr2[([array]::indexof($parr1,'MAC Address'))]}
				'Номер телефона'	= if ([array]::indexof($parr1,'Номер телефона') -ne -1) {
										$parr2[([array]::indexof($parr1,'Номер телефона'))]
									  } elseif ([array]::indexof($parr1,'Номер телефона 1') -ne -1) {
									  	$parr2[([array]::indexof($parr1,'Номер телефона 1'))]
									  } else {
									  	$parr2[([array]::indexof($parr1,'Phone DN'))]
									  }
				'Серийный номер'	= if ([array]::indexof($parr1,'Серийный номер') -ne -1) {
										$parr2[([array]::indexof($parr1,'Серийный номер'))]
									  } else {$parr2[([array]::indexof($parr1,'Serial Number'))]}
				'Номер модели'		= if ([array]::indexof($parr1,'Номер модели') -ne -1) {
										$parr2[([array]::indexof($parr1,'Номер модели'))]
									  } else {$parr2[([array]::indexof($parr1,'Model Number'))]}
			}
		} catch {
			write-host Ошибка: $_ -for red
		}
	}
} |export-csv $outfile -notype -enc utf8 -d ';' -append

- возможно, скорости не прибавит, но так будет правильнее...

Цитата Griboed0ff:
Может пошик умеет пинговать многопоточно? »
можно ранспейсы задействовать, но это целиком скрипт придется запускать в фоне, т.е. выходные файлы будут разными...
можно попробовать использовать workflow с конструкцией foreach -parallel (...){...}, примерно так:
Код: Выделить весь код
ForEach -Parallel ($<item> in $<collection>)
{
    [<Activity1>]
    [<Activity2>]
    ...
}
где, команды будут выполняться параллельно, но коллекция перебирается последовательно...
В общем, простор для творчества есть...

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 16:55, 08-05-2020 | #102


Ветеран


Сообщения: 1758
Благодарности: 966

Профиль | Цитировать


Цитата YuS_2:
попробовать использовать workflow »
Ну или ставить PowerShell Core (7), там это уже внедрили.
Код: Выделить весь код
ForEach-Object -Parallel
               -ThrottleLimit [int]     # Количество потоков
               -TimeoutSeconds [int]    # Задержка, чтобы успел войти весь $input
Это сообщение посчитали полезным следующие участники:

Отправлено: 17:31, 08-05-2020 | #103


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1218
Благодарности: 509

Профиль | Отправить PM | Цитировать


Цитата Foreigner:
Ну или ставить PowerShell Core (7), там это уже внедрили. »
Да, это кстати, как раз, упрощенное использование runspace...

-------
scio me nihil scire. Ѫ


Отправлено: 18:03, 08-05-2020 | #104


Ветеран


Сообщения: 27449
Благодарности: 8087

Профиль | Отправить PM | Цитировать


Foreigner, а реально там как — хост пользует несколько ядер единовременно?

Отправлено: 23:43, 08-05-2020 | #105


Ветеран


Сообщения: 1758
Благодарности: 966

Профиль | Цитировать



Цитата Iska:
а реально там как — хост пользует несколько ядер единовременно? »
Если честно, не знаю. Но прирост производительности наглядный, например пинг ускоряется в три раза. Но в справке написано, что -parallel не для всего подходит. Нужно выяснять путем тестирования.

Например простой перебор чисел 0..1000 значительно медленнее обычного foreach.

Отправлено: 01:06, 09-05-2020 | #106


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1218
Благодарности: 509

Профиль | Отправить PM | Цитировать


Foreigner, Iska,
Цитата Iska:
хост пользует несколько ядер единовременно? »
https://devblogs.microsoft.com/power...allel-feature/

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 08:12, 09-05-2020 | #107


Ветеран


Сообщения: 27449
Благодарности: 8087

Профиль | Отправить PM | Цитировать


YuS_2, спасибо, ясно. Ответ — да:
Цитата:
…if the machine you are running on has multiple cores that can host the script block threads. In this case the -ThrottleLimit parameter should be set approximately to the number of available cores.

Отправлено: 08:27, 09-05-2020 | #108


Старожил


Сообщения: 211
Благодарности: 2

Профиль | Отправить PM | Цитировать


Цитата YuS_2:
Кстати, код я немного изменил, в этой части: »
не смогу проверить пока срипт не переберет 2500, паузы то нет.
Сейчас гляну смогу ли поднять на рабочей тачке пошик 7.

поставил, готов к тестам.
Скрытый текст
Код: Выделить весь код
PowerShell 7.0.0
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/powershell
Type 'help' to get help.

PS C:\Program Files\PowerShell\7>


Я так понимаю надо будет указывать количество ядер или автоматически выставится? а так 4 ядра (i5-4590s).

Отправлено: 08:32, 09-05-2020 | #109


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1218
Благодарности: 509

Профиль | Отправить PM | Цитировать


Цитата Griboed0ff:
готов к тестам. »
попробуйте так проверить:
Скрытый текст
Код: Выделить весь код
...
$ips|% -parallel {
	if (test-connection $_ -count 1 -q -timeout 1){
		try {
			$a = (iwr $_).content
			$content = if ($a -match [char]208){
				if ($a -match 'windows-1251'){
					$enc1,$enc2 = 1251,1252
					$a|convert $enc1 $enc2
				} else {$a|convert $using:enc1 $using:enc2}
			} else {$a}
			$html = [net.webutility]::htmldecode($content)|convertfrom-html
			[array]$tables = $html.selectnodes('//table')
			# Исключение вложенных таблиц:
			$tables = $tables|?{$_.selectnodes('.//table') -eq $null}
			$tbl = $tables[$using:number]|%{$n=0}{
				$tr = $_.selectnodes('.//tr')
				$headers = @()
				if ($headers = $_.selectnodes('.//th')){
					$headers = ($headers|select -exp innertext).trim()
				} else {
					$headers = 1..([linq.parallelenumerable]::max(
						[linq.parallelenumerable]::asparallel(
							($tr|%{$_.selectnodes('.//td').count})
						)
					))|%{"H$_"}
				}
				$rowind = ,1 * $headers.count
				$tr|?{$_.selectnodes('.//td') -ne $null}|%{
					$row = $_.selectnodes('.//td')|%{
						$attr = $_.attributes
						if ($attr){
							$rowspan = ($attr|? name -eq 'rowspan').value
							$colspan = ($attr|? name -eq 'colspan').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
				}
			}
			$parr1 = $tbl.h1
			if ($tbl.h2 -ne $null) {$parr2 = $tbl.h2} else {$parr2 = $tbl.h3}
			[pscustomobject]@{
				'IP'				= $_
				'MAC-адрес' 		= if ([array]::indexof($parr1,'MAC-адрес') -ne -1) {
										$parr2[([array]::indexof($parr1,'MAC-адрес'))]
									  } else {$parr2[([array]::indexof($parr1,'MAC Address'))]}
				'Номер телефона'	= if ([array]::indexof($parr1,'Номер телефона') -ne -1) {
										$parr2[([array]::indexof($parr1,'Номер телефона'))]
									  } elseif ([array]::indexof($parr1,'Номер телефона 1') -ne -1) {
									  	$parr2[([array]::indexof($parr1,'Номер телефона 1'))]
									  } else {
									  	$parr2[([array]::indexof($parr1,'Phone DN'))]
									  }
				'Серийный номер'	= if ([array]::indexof($parr1,'Серийный номер') -ne -1) {
										$parr2[([array]::indexof($parr1,'Серийный номер'))]
									  } else {$parr2[([array]::indexof($parr1,'Serial Number'))]}
				'Номер модели'		= if ([array]::indexof($parr1,'Номер модели') -ne -1) {
										$parr2[([array]::indexof($parr1,'Номер модели'))]
									  } else {$parr2[([array]::indexof($parr1,'Model Number'))]}
			}
		} catch {
			write-host Ошибка: $_ -for red
		}
	}
} -throttlelimit 5 |export-csv $outfile -notype -enc utf8 -d ';' -append

- пинги будут выполняться чуть быстрее за счет -timeout 1
Количество одновременно выполняющихся сценариев, регулируйте параметром -throttlelimit 5

-------
scio me nihil scire. Ѫ


Последний раз редактировалось YuS_2, 09-05-2020 в 11:41.


Отправлено: 11:34, 09-05-2020 | #110



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - вытянуть информацию из html полученного через curl

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Как получить информацию, не отображаемую в HTML-коде? Apock Вебмастеру 0 26-12-2015 22:11
Имитация браузера через cURL dmit.medv Вебмастеру 0 28-12-2012 18:02
[решено] Вывести информацию из файла через JS MultiMax Вебмастеру 1 31-05-2011 22:58
[решено] Вытянуть содержание HTML тега с помощью регулярных выражений aesir AutoIt 4 28-08-2009 21:22
Как передать в javascript данные массива, полученного из кода на php vagner_HATE Вебмастеру 1 18-06-2009 13:51




 
Переход