Powershell vs WSH :)

Задачка: есть сайт. И надо вытащить с него картинку из центра страницы, нажать на кнопочку «Следующий билет», вытащить картинку оттуда, и так далее до конца. Файлы идут не подряд, просто наугад вытягивать их добавляя цифру не катит.

На WSH это было реализовано napa3ut'ом так.

Ну и увидев этот ужас я решил сделать покрасивее и покороче🙂

Update: переборол лень, напряг мозг на 5 минут, и приписал $wc.downloadFile()😉 теперь если вызвать с ключиком -download то будет скачивать без всякого вгета🙂

Замечу что пример частный, и у обоих языков есть свои преимущества (хотя у PoSH их куда больше ;)).

function Get-ItemsFromSite($StartPage='http://www.vodish.ru/edu/card/ab/3/', $itemPattern='url\((.+?)\);',
$nextPagePattern='"([\w\d\/]+?)" title="Следующий билет">', $baseUrl='http://www.vodish.ru',
[switch]$download=$false, $max=10)
{
	$wc = new-object System.Net.WebClient; $n = 1
	$wc.Encoding = [System.Text.Encoding]::GetEncoding("windows-1251")
	$page=$startPage
	while($Page -ne "" -and $n -le $max)
	{
		write-host "Parsing page $page" -foreground "DarkGray"
		$page = $wc.DownloadString($Page)
		if($page -match $itemPattern)
		{
			if ($download)
			{
				$fname = [string]$n+$matches[1].substring($matches[1].lastindexof("."))
				$wc.DownloadFile($baseUrl+$matches[1],$fname)
			}
			else{write-output ($baseUrl+$matches[1])}		
		}
		if($page -match $nextPagePattern) {$Page=$baseUrl+$matches[1]}else{$Page=""}
		if($page -eq $startPage){$page=""}
		$n++
	}
}

Скрипт универсальный, годится для вытаскивания не только картинок, и не только с этого сайта — только дай соответствующие регекспы🙂 Но по умолчанию я поставил параметры для данного сайта, так что можно просто скопировать скрипт в консоль, и сразу вызывать не указывая параметров.

Для удобства я его положил в файлик Web.ps1 и подгрзил оттуда:

PS L:\PowerShell> . Web.ps1
PS L:\PowerShell> Get-ItemsFromSite
Parsing page http://www.vodish.ru/edu/card/ab/3/

Parsing page http://www.vodish.ru/edu/card/ab/4/

Parsing page http://www.vodish.ru/edu/card/ab/5/

...

Скрипт выдаёт на выходе массив строчек с урлами выковырянных объектов. (Строки «Parsing page …» не являются объектами вывода и просто пишутся на консоль) Его можно просто перенаправить в файл обычным «>», сохранить в переменную, или скормить сразу wget'у (Думаю проще и более по повершелловски было бы скачивать файлы тем же WebClient'ом, но я пока этого еще не пробовал, и поэтому не пишу =) Позже наверняка напишу Get-WwwObject в аналогию Get-WwwString.
Так вот. Получаем урлы в переменную…:

$kartinki = Get-ItemsFromSite

Убираем повторные:

$kartinki = $kartinki | Sort-Object -Unique 

И скачиваем…

$kartinki | foreach {wget.exe $_}

Ну или всё сразу:

Get-ItemsFromSite | Sort-Object -Unique | foreach {wget.exe $_}

Что-бы скачивать картинки по мере разбора страничек — убираем Sort-Object из конвеера (Для выбора уникальных элементов ему приходится дожидатся окончания разбора страниц):

Get-ItemsFromSite | foreach {wget.exe $_}

PS: я прикрутил параметр $max, для ограничения максимального кол-ва картинок, мне например для тестирования хватало и 10 штук. Ну а на практике — ставьте сколько хотите, в пределах [System.Double]::MaxValue ;))

Get-ItemsFromSite -max 1000

Задавайте вопросы, жду… Уже без особой надежды…😉

Опубликовано в PowerShell. Комментарии к записи Powershell vs WSH :) отключены
%d такие блоггеры, как: