Парсер картинок на php
При написании этого скрипта я ставил перед собой цель обойтись одним файлом без сторонних зависимостей. Итак, приступим.
У меня патологическая тяга к сохранению картинок, с изучением же кодинга архив изображений стал пополняться чуть ли не в геометрической прогрессии. Парсить я решил двач, так как там удобное API.
Использовать скрипт мы будем так: php parser.php ссылка директория
, причем на Windows нужно добавить путь к php.exe в переменную %PATH%
.
Для начала нужно обработать аргументы, которых у нас будет три - первый для вывода имени файла (я без понятия, как вы собираетесь назвать свой скрипт), второй для ссылки и третий, необязательный, для директории сохранения картинок. Заодно выведем краткий хелп:
if (isset($argv[1])) { $url = $argv[1]; } else { print_r("Usage: php {$argv[0]} url output_directory(optional)\n"); exit("\n\tExit with status: wrong script usage"); } if (isset($argv[2])) { $imagesDirectory = $argv[2]; } else { $imagesDirectory = 'images'; }
Обратите внимание на двойные кавычки и фигурные скобки вокруг первого аргумента.
Далее объявим массив для ссылок и заменим окончание ссылки с .html на .json, чтобы взаимодействовать с API:
$imageLinks = []; $request = preg_split('~(html)$~', $url, null, PREG_SPLIT_NO_EMPTY); $result = json_decode(file_get_contents($request[0] . 'json'), true);
Документация по json_decode и прочим функциям находится на сайте php.net, доступна в том числе и на русском языке.
Теперь нужно пройтись по полученному json'у и записать в массив все ссылки на картинки:
$threads = $result['threads'][0]; foreach ($threads as $thread) { foreach ($thread as $posts) { foreach ($posts as $key => $value) { if ($key == 'files') { foreach ($value as $path) { $imageLinks[] = 'https://2ch.hk' . $path['path']; } } } } }
После этого можно приступать к функции сохранения картинок, она будет принимать на вход 2 аргумента - массив ссылок и директорию вывода. Приступим к написанию функционала:
function saveImages($imageLinks, $imagesDirectory) { $extensionPattern = '~(https:\/\/2ch.hk\/[a-z]+\/[a-z]+\/[0-9]+\/[0-9]+)~'; $imageNamePattern = '~(https://2ch.hk/)[a-z]+(/[a-z]+/[0-9]+/)~'; foreach ($imageLinks as $imageLink) { $imageName = preg_split($imageNamePattern, $imageLink, null, PREG_SPLIT_NO_EMPTY); $extension = preg_split($extensionPattern, $imageLink, null, PREG_SPLIT_NO_EMPTY); $imageName = $imageName[0]; $extension = $extension[0]; if ($extension == '.webm' || $extension == '.mp4' || $extension == '.gif') { print_r($imageName . " will not be saved!\n"); continue; } else { file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . $imagesDirectory . DIRECTORY_SEPARATOR . $imageName, file_get_contents($imageLink)); print_r($imageName . " was saved successfully\n"); } } }
Для начала объявим 2 регулярных выражения для расширения и имени картинки (чтобы не генерировать рандомное имя каждый раз). Переприсвоение переменных - необходимость, вызванная особенностью preg_split.
Затем просто проходимся циклом по массиву ссылок, сохраняя картинки и отсекая видео и гифки. В конце сохраняем всё в указанную или дефолтную директорию, притом не важно, вызываете вы скрипт на Linux или на Windows, сохранение будет произведено корректно (Win10 1903 / Ubuntu 16.04 полёт нормальный).
Ну и в конце делаем проверку наличия директории, если она не была передана в качестве аргумента, сохраняем в дефолтную, которая называется 'images' и будет создана там же, где вы вызвали скрипт.
if (file_exists($imagesDirectory)) { saveImages($imageLinks, $imagesDirectory); print_r("\nJob Done!\n"); } else { mkdir($imagesDirectory); saveImages($imageLinks, $imagesDirectory); print_r("\nJob Done!\n"); }
Полный исходный код (вывод в консоль можно убрать, я его использую для отображения прогресса):
<?php if (isset($argv[1])) { $url = $argv[1]; } else { print_r("Usage: php {$argv[0]} url output_directory(optional)\n"); exit("\n\tExit with status: wrong script usage"); } if (isset($argv[2])) { $imagesDirectory = $argv[2]; } else { $imagesDirectory = 'images'; } $imageLinks = []; $request = preg_split('~(html)$~', $url, null, PREG_SPLIT_NO_EMPTY); $result = json_decode(file_get_contents($request[0] . 'json'), true); $threads = $result['threads'][0]; foreach ($threads as $thread) { foreach ($thread as $posts) { foreach ($posts as $key => $value) { if ($key == 'files') { foreach ($value as $path) { $imageLinks[] = 'https://2ch.hk' . $path['path']; } } } } } function saveImages($imageLinks, $imagesDirectory) { $extensionPattern = '~(https:\/\/2ch.hk\/[a-z]+\/[a-z]+\/[0-9]+\/[0-9]+)~'; $imageNamePattern = '~(https://2ch.hk/)[a-z]+(/[a-z]+/[0-9]+/)~'; foreach ($imageLinks as $imageLink) { $imageName = preg_split($imageNamePattern, $imageLink, null, PREG_SPLIT_NO_EMPTY); $extension = preg_split($extensionPattern, $imageLink, null, PREG_SPLIT_NO_EMPTY); $imageName = $imageName[0]; $extension = $extension[0]; if ($extension == '.webm' || $extension == '.mp4' || $extension == '.gif') { print_r($imageName . " will not be saved!\n"); continue; } else { file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . $imagesDirectory . DIRECTORY_SEPARATOR . $imageName, file_get_contents($imageLink)); print_r($imageName . " was saved successfully\n"); } } } if (file_exists($imagesDirectory)) { saveImages($imageLinks, $imagesDirectory); print_r("\nJob Done!\n"); } else { mkdir($imagesDirectory); saveImages($imageLinks, $imagesDirectory); print_r("\nJob Done!\n"); }
small_shell с любовью для @CodingCommunity