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

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

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

Старожил


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

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


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

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

 

Ветеран


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

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


Цитата Griboed0ff:
поставил, готов к тестам. »
Только учтите, что по умолчанию PowerShell 7 работает с UTF8, поэтому скрипты с кириллицей должны быть в этой кодировке.
Код: Выделить весь код
# pwsh $OutputEncoding

Preamble          :
BodyName          : utf-8
EncodingName      : Unicode (UTF-8)
HeaderName        : utf-8
WebName           : utf-8
WindowsCodePage   : 1200
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 65001

# powershell $OutputEncoding

IsSingleByte      : True
BodyName          : us-ascii
EncodingName      : US-ASCII
HeaderName        : us-ascii
WebName           : us-ascii
WindowsCodePage   : 1252
IsBrowserDisplay  : False
IsBrowserSave     : False
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 20127
На эту тему, можно почитать тут

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



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

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


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата Foreigner:
Только учтите, что по умолчанию PowerShell 7 работает с UTF8 »
Да, к тому же, utf8, в powershell core необходимо именовать utf-8...
По рукам бы надавать за такую вот "совместимость", этим индусам...

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

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

Отправлено: 13:48, 09-05-2020 | #112


Старожил


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

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


Цитата YuS_2:
попробуйте так проверить: »
Скрытый текст
Код: Выделить весь код
param (
	#[parameter(Mandatory=$true)]
	[string]$outfile = 'D:\PowerShell\готовые\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 'D:\PowerShell\готовые\all_ip.txt'
$ips = 130..190 |%{$n=$_;$arr|%{"$_"+$n}}|sort

$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 4 |export-csv $outfile -notype -enc utf8 -d ';' -append
Скрытый текст
Код: Выделить весь код
PS C:\Windows\System32> D:\PowerShell\готовые\phone_p7.ps1
SetValueInvocationException: D:\PowerShell\готовые\phone_p7.ps1:28
Line |
  28 |  [net.servicepointmanager]::securityprotocol = 'ssl3,tls,tls11,tls12'
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception setting "securityprotocol": "The requested security protocol is not supported."

ForEach-Object: D:\PowerShell\готовые\phone_p7.ps1:32
Line |
  32 |  $ips|% -parallel {
     |       ~~~~~~~~~~~~~
     | The value of the using variable '$using:number' cannot be retrieved because it has not been set in the local
     | session.

PS C:\Windows\System32>


похоже надо доустановить, щас решу отпишусь.

Отправлено: 14:00, 09-05-2020 | #113


Старожил


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

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


Ни на одном компе не работает.

Отправлено: 14:56, 09-05-2020 | #114


Ветеран


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

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


Цитата Griboed0ff:
не работает »
По поводу строки 28:
Код: Выделить весь код
[net.servicepointmanager]::securityprotocol = 'ssl3,tls,tls11,tls12'
Её лучше закомментировать. Она в pwsh не работает, у меня тоже самое в другом скрипте (обновление Far)

Код: Выделить весь код
$using:number
По идее переменная $number должна быть определена до начала цикла foreach-object, Например $enc1 и $enc2 определены в параметрах и не вызывают ошибки. Где $number вообще назначается? Что-то не вижу.
Это сообщение посчитали полезным следующие участники:

Отправлено: 16:04, 09-05-2020 | #115


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата Griboed0ff:
похоже надо доустановить »
не надо...
Про строку 28 уже написали...
А по поводу $using:number - ранее, переменная определялась внутри цикла foreach-object (что неправильно), а теперь я вынес её за пределы цикла.
В общем, надо добавить перед циклом:
Код: Выделить весь код
...
if ([string]::isnullorempty($selecttable)){
	$number = 0
} else {$number = $selecttable}
$ips|% -parallel {
...

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

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

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


Старожил


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

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


Цитата YuS_2:
В общем, надо добавить перед циклом: »
Скрытый текст
Код: Выделить весь код
param (
	#[parameter(Mandatory=$true)]
	[string]$outfile = 'D:\PowerShell\готовые\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 'D:\PowerShell\готовые\all_ip.txt'
$ips = 2..254 |%{$n=$_;$arr|%{"$_"+$n}}|sort

if ([string]::isnullorempty($selecttable)){
	$number = 0
} else {$number = $selecttable}
$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 4 |export-csv $outfile -notype -enc utf8 -d ';' -append
Скрытый текст
Код: Выделить весь код
PS C:\Windows\System32> D:\PowerShell\готовые\phone_p7.ps1
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Недопустимый параметр: 28591
ConvertFrom-Html:
Line |
  11 |  …       $html = [net.webutility]::htmldecode($content)|convertfrom-html
     |                                                         ~~~~~~~~~~~~~~~~
     | Cannot bind argument to parameter 'Content' because it is null.
Ошибка: You cannot call a method on a null-valued expression.
Ошибка: You cannot call a method on a null-valued expression.
Ошибка: You cannot call a method on a null-valued expression.
файл заполнился нормально, но
названия столбиков
Код: Выделить весь код
IP	MAC-адрес	Номер телефона	Серийный номер	Номер модели


Да быстрее кстати, но жаль ограничено количеством ядер.

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


Старожил


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

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


скормил файлик с подсетями побольше
Скрытый текст
Код: Выделить весь код
PS C:\Windows\System32> D:\PowerShell\готовые\phone_p7.ps1
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: You cannot call a method on a null-valued expression.
Ошибка: Response status code does not indicate success: 500 (Internal Server Error).
Ошибка: You cannot call a method on a null-valued expression.
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка:
Service Unavailable

Service Unavailable
HTTP Error 503. The service is unavailable.


Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: Exception calling "IndexOf" with "2" argument(s): "Value cannot be null. (Parameter 'array')"
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка: You cannot call a method on a null-valued expression.
Ошибка: Response status code does not indicate success: 404 (Not Found).
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.
Ошибка:
Service Unavailable

Service Unavailable
HTTP Error 503. The service is unavailable.


Ошибка: Exception calling "IndexOf" with "2" argument(s): "Value cannot be null. (Parameter 'array')"
Ошибка: Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера.
Ошибка: 401 Unauthorized

Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.


Видимо 7 пошик и ошибки пишет другие

Отправлено: 19:23, 09-05-2020 | #118


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата Griboed0ff:
Ошибка: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение. »
это из блока try-catch, т.е. пинг проходит, а (iwr $_).content - с ошибкой... проверьте вручную.

Цитата Griboed0ff:
Недопустимый параметр: 28591 »
Проверьте, есть ли такие цифры в перечне:
Код: Выделить весь код
[text.encoding]::getencodings()
Цитата Griboed0ff:
файл заполнился нормально, но »
Хмм...
Цитата Griboed0ff:
utf8 »
А вот тут, читали:
Цитата YuS_2:
Да, к тому же, utf8, в powershell core необходимо именовать utf-8... »
? Надо исправить... и сам скрипт сохраняйте в utf-8

Цитата Griboed0ff:
жаль ограничено количеством ядер. »
Не ограничено, можно использовать и большее число... поэкспериментируйте.

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


Отправлено: 19:37, 09-05-2020 | #119


Старожил


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

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


Цитата YuS_2:
Да, к тому же, utf8, в powershell core необходимо именовать utf-8. »
сохранял в utf-8. Что имеете ввиду "именовать"?

Цитата YuS_2:
Не ограничено, можно использовать и большее число... поэкспериментируйте. »
поставил 100, пошик занял всю память и довольно быстро заполняет файлик, ошибок почти не выдает.

Отправлено: 19:45, 09-05-2020 | #120



Компьютерный форум 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




 
Переход