Раньше я уже публиковал powershell скрипт с помощью которого можно скачать из Вконтакте все аудиозаписи с вашей страницы, на этот раз делюсь скриптом который поможет скачать общедоступные фотографии указанной страницы, профиля, группы.
Скрипт скачивает все фотографии из фотоальбомов и складывает их по соответствующим папкам. Также скачиваются фотографии из служебного альбома "Фотографии на стене сообщества", это может пригодится, если нужно скачать фотографии из какого-либо фото-паблика Вконтакте, который в принципе не пользуется фотоальбомами, просто публикует фотографии сразу на стену.
Но и это еще не все: скрипт записывает в метаданные (поле "Название") скачанного файла количество набранных лайков к фотографии. Это может пригодится тем, кто хочет скачать у группы-конкурента все фотографии и отсортировать изображения по лайкам для добавления наиболее залайканных фотографий - так сказать снять самые сливки. При следующем запуске скрипта если изображение уже скачано, то будет лишь обновлена информация в метаданных о количестве лайков:

Скрипт также запоминает какие фотографии были скачаны (в текстовом файле downloaded_files.txt каждой папки-альбом) и потом удалены - такие фотографии заново не перекачиваются.
Код скрипта:
#скрипт скачивает фотографии из вконтакте
#автор: elims.org.ua
<# #>
$photo_path = "D:\vk-photos\" #папка для сохранения изображений
$id = -22786271 #HD Обои
#альбомы которые нужно исключить:
$need_albums_id = 147102139,134040033,147102144,132334095
$global:photos_array = $null #обнулили масив всех фотографий сохраненного альбома
$global:album_photos_count = $null #обнуление переменной с количествов фотографий в альбоме
$sleep_time = 1 #время задержки между запросами
[void][reflection.assembly]::loadwithpartialname("system.drawing") #для доступа как метаданным в файлах изображений
function get_photo_list { #функция получения списка фотографий
$j = 0
do { #выбираем по 1000 фотографий пока не дойдем до конца альбома
Start-Sleep -s $sleep_time
$uri = $uri_part1 + $j + "&extended=1&v=5.24"
$request = $null
do { #пытаемся получить ответ от сервера пока это не получится
"Ссылка запроса: " + $uri
$request = Invoke-WebRequest -Uri $uri
Start-Sleep -s 1 #задержка в одну секунду
} while ($request -eq $null) #пока не получим нормальный ответ
$response_array = $request.content | ConvertFrom-Json #Конвертируем полученные данные из формата JSON в массив
$global:album_photos_count = $response_array.response.count #переопределяем количество фотографий в альбоме исходя из данных последнего запроса
$global:photos_array = $photos_array + $response_array.response.items #сохраняем в масив список фотографий
"Сохраненны данные " + $photos_array.count + " фотографий"
$j = $j + 1000
} while ($j -le $global:album_photos_count) #выбираем по 1000 фотографий пока не дойдем до конца альбома
}
function save_photos { #функция сохранения фотографии
"начинаем сохранять фотографии, если есть задержка значит найдены уже скачанные фотографии и происходит их пропуск"
$file_of_downloaded_files = $path + "\downloaded_files.txt" #имя файла со списком скачанных файлов
if (Test-Path $file_of_downloaded_files) { #если список скачанных файлов существует
$array_of_downloaded_files = Get-Content $file_of_downloaded_files #считываем его в массив
}
else { #если списка скачанных файлов не существует
$array_of_downloaded_files = @() #создаем пустой массив
}
foreach ($photo_id in $photos_array.id) {
if ($photos_array.photo_2560[$i_photo] -ne $null) { $photo = $photos_array.photo_2560[$i_photo] } #пытаемся скачать фотографию в качестве 2560
elseif ($photos_array.photo_1280[$i_photo] -ne $null) { $photo = $photos_array.photo_1280[$i_photo] } #если нет качества 2560 пытаемся скачать в 1280
elseif ($photos_array.photo_807[$i_photo] -ne $null) { $photo = $photos_array.photo_807[$i_photo] } #если нет качества 1280 качаем в 807
elseif ($photos_array.photo_604[$i_photo] -ne $null) { $photo = $photos_array.photo_604[$i_photo] } #если нет качества 807 качаем в 604
else { $photo = $null } #если нет необходимого качества, то ничего не качаем
$likes = $photos_array.likes[$i_photo].count #количество лайков к фотографии
$likes_sum = $likes_sum + $likes #сумма лайков к фотографиям в альбоме
$album_and_photo_id = [string]$photos_array.owner_id[$i_photo] + "_" + [string]$photos_array.id[$i_photo]
$filename = $path + $album_and_photo_id + ".jpg" #формируем имя файла без лайков в метаданных
$filename2 = $filename.substring(0,$filename.length - 5) + "_with_likes.jpg" #формируем временное имя файла с лайками в метаданных
if ( $photo -ne $null ) { #если ссылка на фотографию не пуста
"Альбом " + $i + " из " + $album_count + " : " + $album_title + " Фото " + $i_photo + " из " + $global:album_photos_count + ": " + $photo + " idPhoto: " + $photos_array.id[$i_photo] + " likes: " + $likes
if ((-not(Test-Path $filename))-and(-not($array_of_downloaded_files -contains $album_and_photo_id))) { #если такого файла не существует и он ранее не скачивался
Invoke-WebRequest $photo -OutFile $filename #скачиваем и сохраняем изображение
}
#прописывание количества лайков в метаданные изображения, в поле "название"
if (Test-Path $filename) { #если такой файл существует
if (-not($array_of_downloaded_files -contains $album_and_photo_id)) { #если ранее этот файл не скачивался
$array_of_downloaded_files = $array_of_downloaded_files + $album_and_photo_id
}
$img = [System.Drawing.Image]::Fromfile($filename)
$item = $img.psbase.GetPropertyItem(20624) #взяли в качестве примера не пустое поле с метаданными
$item.id = 270 #поле "название"
$item.type = 2
$likes_string = [int[]][char[]][string]("likes: " + $likes)
$likes_string = $likes_string + 0
$item.len = $likes_string.count
$item.Value = $likes_string #поле с количеством лайков
$img.SetPropertyItem($item) #сохраняем информацию о лайках
$filename2 = $filename.substring(0,$filename.length - 5) + "_with_likes.jpg"
$img.Save($filename2) #сохраняем файл с временным именем с информацией о лайках
$img.dispose() #закрываем файл без информации о лайках
Remove-Item $filename #удаляем файл без информации о лайках
Rename-Item $filename2 $filename #переименовываем временное имя файла с метаданными в исходное имя
}
}
$i_photo++
}
$likes_average = $likes_sum/$i_photo #подсчитываем в альбоме среднее количество лайков на фотографию
$likes_text = "Суммарное количество лайков: " + $likes_sum + " количество фотографий: " + $i_photo + " средняя оценка фотографии: " + $likes_average + " лайков"
$export_file = $path + "\likescount.txt"
$likes_text | Out-File $export_file -Encoding UTF8 #сохраняем в файл информацию о среднем количестве лайков на фотографию
$array_of_downloaded_files | Out-File $file_of_downloaded_files -Encoding UTF8 #сохраняем в файл информацию о скачанных фотографиях
$i_photo = 0 #обнулили порядковый номер фотографии в альбоме
$likes_sum = $null #обнулили сумарное количество лайков
}
#Получаем имя страницы\группы
if ($id -gt 0) { $uri = "https://api.vk.com/method/users.get?user_ids="+$id }
else {
$group_id = $id * -1
$uri = "https://api.vk.com/method/groups.getById?group_ids="+$group_id
}
$request = Invoke-WebRequest -Uri $uri
$response_array = $request.content | ConvertFrom-Json #Конвертируем полученные данные из формата JSON в массив
$id_name = $response_array.response.name + $response_array.response.first_name + $response_array.response.last_name
$id_name = $id_name -replace '(\\)|(\/)|(\*)|:|(\?)|"|<|>|(\|)|(\[)|(\])|(\n)', "_" #убираем некорректные знаки для имени файла
$id_name #имя страницы
$uri = "https://api.vk.com/method/photos.getAlbums?owner_id="+$id
$request = Invoke-WebRequest -Uri $uri
$response_array = $request.content | ConvertFrom-Json #Конвертируем полученные данные из формата JSON в массив
$album_count = $response_array.response.aid.count #количество альбомов
$i = 0 #счетчик альбомов
foreach ($album in $response_array.response.aid) { #обходим каждый альбом
$i_photo = 0
$global:album_photos_count = $response_array.response.size[$i] #количество фотографий в альбоме
$album_title = $response_array.response.title[$i] #название альбома
"Обрабатываем альбом: " + $album + " " + $album_title + " который состоит из " + $global:album_photos_count + " фотографий"
if ($need_albums_id -contains $album) { "Этот альбом пропускаем: " + $album } #перечисленные альбомы исключаются
#if (-not($need_albums_id -contains $album)) { "Этот альбом пропускаем: " + $album } #перечисленные альбомы включаются, все другие исключаются
else {
#создаем папку альбома
$album_title = $album_title -replace '(\\)|(\/)|(\*)|:|(\?)|"|<|>|(\|)|(\[)|(\])|(\n)', "_" #убираем некорректные знаки для имени файла
$path = $photo_path + $id + "_" + $id_name + "\" + $album_title+"-album" + $album + "\" #имя папки
if (-not(Test-Path $path)) { #если папка не существует
$result = New-Item -ItemType directory -Path $path #создаем папку
}
$uri_part1 = "https://api.vk.com/method/photos.get?owner_id="+$id+"&album_id="+$album+"&count=1000&offset="
get_photo_list #функция получения списка фотографий
save_photos #функция сохранения фотографий
$global:photos_array = $null #обнулили масив всех фотографий сохраненного альбома
$global:album_photos_count = $null #обнулили количество фотографий в альбоме
}
$i++
}
#качаем фотографии из альбома типа "Фотографии на стене сообщества"
$path = $photo_path + $id + "_" + $id_name + "\photos_from_wall\" #имя папки
if (-not(Test-Path $path)) { #если папка не существует
$result = New-Item -ItemType directory -Path $path #создаем папку
}
$album_title = "photos_from_wall"
$uri_part1 = "https://api.vk.com/method/photos.get?owner_id="+$id+"&album_id=wall&count=1000&offset="
get_photo_list #функция получения списка фотографий
save_photos #функция сохранения фотографийВ самом начале скрипта указываются три входных параметра:
$photo_path = "D:\vk-photos\" #папка для сохранения изображений $id = -22786271 #HD Обои #альбомы которые нужно исключить: $need_albums_id = 147102139,134040033,147102144,132334095,147158535,135840729,139940911,144126590,148117034,150218783,152202307,153578867,154970595,156369728,158058558,159302933,160588607,162081006,164777317,165552996,166939786,169325173,170826148,172398650,128782649,133628616,154341193,131374960,162793467,137349112,132441241,124936139,147158522,203298792,137419682,147102182,147102200,135127647,199208496,187953367
$photo_path - папка в которую будут сохраняться фотографии. У меня это папка "D:\vk-photos\". Можете указать свою папку
$id - id странички или группы во вконтакте из которой нужно скачать фотографии. У меня это id -22786271 которое принадлежит вот этому паблику vk.com/oboihd (если в id есть знак "-" значит это сообщество, ггруппа, паблик)
$need_albums_id - id альбомов которые нужно исключить, то есть не нужно скачивать.
Ну а если Вам нужно избавиться от дубликатов фотографий, то в этом поможет программа "Duplicate Photo Finder" или ее аналог.
Пользуйтесь! Если есть вопросы - задавайте их в комментариях =)
а нет скрипта для скачивания удалённых фотографий? (они на сервере хранятся, чтобы с дефрагментацией проблем не было, но нужна ссылка… в ручную не найти)
Антон, к сожалению я не знаю каким образом можно получить ссылки на удаленные фотографии.
А вообще кто-нибудь проверял работоспособность скрипта? Помимо всех прочих ошибок, которые выдал мне PowerShell и с которыми удалось справиться, одну убрать не удалось — Missing while or until keyword in do loop.
Подпихнул всё в PS ise и процесс пошёл.
Никто кроме тебя не поможет :) Пожалуйста выручай
Подскажи где ошибка, пытаюсь сделать пост на стену группы с картинкой
Обычный текстовый получается без проблем.
#Получение ссылки для загрузки рисунка в вк.
$url=Invoke-WebRequest’https://api.vkontakte.ru/method/photos.getWallUploadServer?gid=ид группы&access_token=МОЙ ТОКЕН’
#Получаем урл
$up=($url.content | ConvertFrom-Json).response.upload_url
#Параметр пост запроса
$postParams=@{photo=»C:\11.jpg»}
#Запрос
Invoke-WebRequest -Uri $up -Method POST -Body $postParams
В итоге получаю
{«server»:629531,»photo»:»[]»,»hash»:»68432950d3ab93e42e51ce42a1886453″}
Соответственно фото он не принимает, что я делаю не так?
Мстислав, загружать файлы ВК через апи я не пробовал. Так как было лень разбираться, она не так проста, как просто опубликовать пост.
Поэтому я делаю так: заранее вгружаю в ВК фотографии в какой-то фотоальбом, а потом уже публикую текст с фотографией (которая уже загружена в вк):
«wall.post?owner_id=»+$id+»&message=» + $text + «&attachments=» + $photo_id + «&v=5.24&access_token=»+$token
была ошибка допилил
была ошибка деление на ноль
133 строка
if (-not(Test-Path $path)) { #если папка не существует
$result = New-Item -ItemType directory -Path $path #создаем папку
}
А можете совсем немного изменить скрипт, чтобы имя файла сохранялось оригинальное.
Например сейчас -60545552_453635558.jpg, а надо 3T2Vt9XA2t4.jpg
К сожалению нет свободного времени на это.
Здравствуйте, получается нужно просто вставить этот код в PS и изменить куда будет сохранятся, откуда качать и какие альбомы не трогать??Если это так, то я всё сделал правильно только выдает разные ошибки :( помогите!!!
ну ответь пожалуйста!!!
Ильдар, увы, нет времени на помощь в разбирании ошибок. Скрипт публиковался для тех людей, который знакомы с powershell и смогут сами поправить ошибки
Всё же спасибо за отклик!
Здравствуйте! Возникла такая проблема: чаще всего скрипт не скачивает фотографии со стены сообщества — он их просто пропускает. Можете ли Вы помочь с этой проблемой?
Добрый день, а у вас случайно нет видео как этим пользоватса? Очень нужно, но в скриптах я полный нуб.
Пишет вот такую ошибку, в чем проблема?
Ссылка запроса: https://api.vk.com/method/photos.get?owner_id=285207579&album_id=&count=1000&offset=0&extended=1&v=5.24
Имя «Invoke-WebRequest» не распознано как имя командлета, функции, файла скрипта или выполняемой программы. Проверьте правильность написания имени, а также наличие и правильность пути, после че
го повторите попытку.
строка:23 знак:32
+ $request = Invoke-WebRequest <<<< -Uri $uri
+ CategoryInfo : ObjectNotFound: (Invoke-WebRequest:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
обновите powershell до более свежей версии
А как это все заставить работать? (Лично мне надо скачивание фотографий со стены сообщества)