#!/usr/bin/env python3 """Скрипт для скачивания голых и не только девушек с блога blog.stanis.ru""" import re import shutil import os.path import requests from bs4 import BeautifulSoup import click __author__ = "Alexander Popov" __version__ = "1.0.4" __license__ = "Unlicense" # Путь к директории для загрузки изображений DOWNLOAD_DIRECTORY = "./images" # Количество загружаемых страниц DOWNLOAD_PAGES = 0 def print_version(ctx, param, value): if not value or ctx.resilient_parsing: return click.echo("Версия: {0}".format(__version__)) ctx.exit() @click.command(add_help_option=False) @click.option( "--directory", default="./images", help="Путь к директории для загрузки изображений.", ) @click.option("--pages", default=0, help="Количество загружаемых страниц.") @click.option( "--version", "-v", is_flag=True, callback=print_version, is_eager=True, help="Отобразить версию программы.", ) @click.help_option("--help", "-h", help="Показать эту справку") def click(directory, pages, version): DOWNLOAD_DIRECTORY = directory DOWNLOAD_PAGES = pages main(DOWNLOAD_DIRECTORY, DOWNLOAD_PAGES) def get_images_links(page): """В качестве аргумента получает номер страницы и возвращает списком адреса всех изображений""" # На сайте фильтр изображений настроен через cookies # Так что устанавливаем их в нужное положение cookies = dict(block="951") # Загружаем страницу и подсовываем её парсеру с необходимыми параметрами r = requests.get( "http://blog.stanis.ru/?back={0}".format( page, ), cookies=cookies, ) soup = BeautifulSoup( r.text.encode("cp1251"), "html.parser", from_encoding="windows-1251" ) # Получаем все теги на странице img_tags = soup.findAll("img", src=re.compile("img/*")) # Получаем все адреса изображений и сохраняем их в список img_links img_links = list() for image in img_tags: img_links.append(image["src"].split("/")[1]) return img_links def image_download(image): """В качестве аргумента получает уникальное имя изображения, скачивает и сохраняет его на диск""" response = requests.get( "https://blog.stanis.ru/imgs/{0}".format( image, ), stream=True, ) image_size = int(response.headers.get("Content-Length", 0)) if ( not os.path.exists("{0}/{1}".format(DOWNLOAD_DIRECTORY, image)) or int(os.path.getsize("{0}/{1}".format(DOWNLOAD_DIRECTORY, image))) != image_size ): with open("{0}/{1}".format(DOWNLOAD_DIRECTORY, image), "wb") as out_image: shutil.copyfileobj( response.raw, out_image, ) return True else: return False def main(download_directory, download_pages): """Главный цикл программы""" if not os.path.exists(download_directory): os.mkdir(download_directory) current_page = 0 downloaded_counter = 0 spinner = ["◢◣◤◥", "◰◳◲◱", "◴◷◶◵", "◐◓◑◒", "|/-\\"] spinner_id = 0 while True: try: # Получаем адреса изображений и сортируем их в порядке возрастания images = get_images_links(current_page) images.sort() # Проверка на количество загруженных страниц # аргумент --pages if current_page >= download_pages and download_pages != 0: print("\nВсего загружено {0} файлов.".format(downloaded_counter)) quit() # По очереди скачиваем изображения for image in images: if image_download(image): downloaded_counter += 1 print( "\r{spinner} Загружено {total_files} файлов.".format( total_files=downloaded_counter, spinner=spinner[2][spinner_id] ), end="", ) if spinner_id < 3: spinner_id += 1 else: spinner_id = 0 current_page += 1 except KeyboardInterrupt: print("\nВсего загружено {0} файлов.".format(downloaded_counter)) quit() if __name__ == "__main__": click()