Парсер картинок на 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