Compare commits
4 Commits
9fbb0eb813
...
c0c013c31b
Author | SHA1 | Date | |
---|---|---|---|
c0c013c31b | |||
ca50802d3f | |||
a5233d3d28 | |||
eb1ce5db14 |
@ -1,2 +1,3 @@
|
|||||||
requests==2.28.1
|
requests==2.28.1
|
||||||
beautifulsoup4==4.11.1
|
beautifulsoup4==4.11.1
|
||||||
|
click==8.1.3
|
||||||
|
150
stanis-tits.py
150
stanis-tits.py
@ -7,62 +7,45 @@ import shutil
|
|||||||
import os.path
|
import os.path
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
import click
|
||||||
|
|
||||||
__author__ = "Alexander Popov"
|
__author__ = "Alexander Popov"
|
||||||
__version__ = "1.0.2"
|
__version__ = "1.0.3"
|
||||||
__license__ = "Unlicense"
|
__license__ = "Unlicense"
|
||||||
|
|
||||||
# Путь к директории для загрузки изображений
|
# Путь к директории для загрузки изображений
|
||||||
DOWNLOAD_DIRECTORY = "./images"
|
DOWNLOAD_DIRECTORY = "./images"
|
||||||
|
# Количество загружаемых страниц
|
||||||
|
DOWNLOAD_PAGES = 0
|
||||||
|
|
||||||
|
|
||||||
def resume_load():
|
def print_version(ctx, param, value):
|
||||||
"""Возвращает список последних 20 загруженных файлов"""
|
if not value or ctx.resilient_parsing:
|
||||||
|
return
|
||||||
# Проверяет наличие файла .resume
|
click.echo("Версия: {0}".format(__version__))
|
||||||
if not os.path.exists(
|
ctx.exit()
|
||||||
"{0}/.resume".format(
|
|
||||||
DOWNLOAD_DIRECTORY,
|
|
||||||
)
|
|
||||||
):
|
|
||||||
# Создаёт директорию для загрузки сисек
|
|
||||||
if not os.path.exists(DOWNLOAD_DIRECTORY):
|
|
||||||
os.mkdir(DOWNLOAD_DIRECTORY)
|
|
||||||
|
|
||||||
# Создаёт файл .resume и пишет в него 0
|
|
||||||
with open(
|
|
||||||
"{0}/.resume".format(
|
|
||||||
DOWNLOAD_DIRECTORY,
|
|
||||||
),
|
|
||||||
"w",
|
|
||||||
) as f:
|
|
||||||
f.write("0")
|
|
||||||
return [0]
|
|
||||||
else:
|
|
||||||
with open(
|
|
||||||
"{0}/.resume".format(
|
|
||||||
DOWNLOAD_DIRECTORY,
|
|
||||||
),
|
|
||||||
"r",
|
|
||||||
) as f:
|
|
||||||
lines = [int(line.split("\n")[0]) for line in f][-20:]
|
|
||||||
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
def resume_save(donwloaded_list):
|
@click.command(add_help_option=False)
|
||||||
"""Сохраняет список последних 20 загруженных файлов"""
|
@click.option(
|
||||||
|
"--directory",
|
||||||
donwloaded_list.sort()
|
default="./images",
|
||||||
with open(
|
help="Путь к директории для загрузки изображений.",
|
||||||
"{0}/.resume".format(
|
)
|
||||||
DOWNLOAD_DIRECTORY,
|
@click.option("--pages", default=0, help="Количество загружаемых страниц.")
|
||||||
),
|
@click.option(
|
||||||
"w",
|
"--version",
|
||||||
encoding="utf-8",
|
"-v",
|
||||||
) as f:
|
is_flag=True,
|
||||||
for item in donwloaded_list[-20:]:
|
callback=print_version,
|
||||||
f.write("{0}\n".format(item))
|
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):
|
def get_images_links(page):
|
||||||
@ -109,12 +92,10 @@ def image_download(image):
|
|||||||
image_size = int(response.headers.get("Content-Length", 0))
|
image_size = int(response.headers.get("Content-Length", 0))
|
||||||
|
|
||||||
if (
|
if (
|
||||||
os.path.exists("{0}/{1}".format(DOWNLOAD_DIRECTORY, image))
|
not os.path.exists("{0}/{1}".format(DOWNLOAD_DIRECTORY, image))
|
||||||
and int(os.path.getsize("{0}/{1}".format(DOWNLOAD_DIRECTORY, image)))
|
or int(os.path.getsize("{0}/{1}".format(DOWNLOAD_DIRECTORY, image)))
|
||||||
== image_size
|
!= image_size
|
||||||
):
|
):
|
||||||
pass
|
|
||||||
else:
|
|
||||||
with open("{0}/{1}".format(DOWNLOAD_DIRECTORY, image), "wb") as out_image:
|
with open("{0}/{1}".format(DOWNLOAD_DIRECTORY, image), "wb") as out_image:
|
||||||
shutil.copyfileobj(
|
shutil.copyfileobj(
|
||||||
response.raw,
|
response.raw,
|
||||||
@ -122,15 +103,16 @@ def image_download(image):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def main(download_directory, download_pages):
|
||||||
"""Главный цикл программы"""
|
"""Главный цикл программы"""
|
||||||
|
if not os.path.exists(download_directory):
|
||||||
resume_files = resume_load()
|
os.mkdir(download_directory)
|
||||||
|
|
||||||
current_page = 0
|
current_page = 0
|
||||||
downloaded_counter = 0
|
downloaded_counter = 0
|
||||||
|
|
||||||
WHILE_BREAK = False
|
spinner = ["◢◣◤◥", "◰◳◲◱", "◴◷◶◵", "◐◓◑◒", "|/-\\"]
|
||||||
|
spinner_id = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@ -138,50 +120,34 @@ if __name__ == "__main__":
|
|||||||
images = get_images_links(current_page)
|
images = get_images_links(current_page)
|
||||||
images.sort()
|
images.sort()
|
||||||
|
|
||||||
# Костыль
|
# Проверка на количество загруженных страниц
|
||||||
if WHILE_BREAK:
|
# аргумент --pages
|
||||||
break
|
if current_page >= download_pages and download_pages != 0:
|
||||||
|
print("\nВсего загружено {0} файлов.".format(downloaded_counter))
|
||||||
|
quit()
|
||||||
|
|
||||||
# По очереди скачиваем изображения
|
# По очереди скачиваем изображения
|
||||||
for image in images:
|
for image in images:
|
||||||
# На сайте могут обновляться изображения,
|
image_download(image)
|
||||||
# когда находятся варианты более лучшего
|
downloaded_counter += 1
|
||||||
# качества и разрешения.
|
|
||||||
# К именам таких файлов добавляется _NUM,
|
|
||||||
# где NUM - количество изменений,
|
|
||||||
# например 1356_3.jpg
|
|
||||||
|
|
||||||
# Файл .resume хранит последние 20 загруженных файлов.
|
print(
|
||||||
# Бывает иногда, что изображение удаляется
|
"\r{spinner} Загружено {total_files} файлов.".format(
|
||||||
# и может получиться так, что сохраненное имя в .resume
|
total_files=downloaded_counter, spinner=spinner[2][spinner_id]
|
||||||
# будет отсутсвовать на странице, что будет в холостую
|
),
|
||||||
# продолжать работу скрипта.
|
end="",
|
||||||
|
)
|
||||||
|
|
||||||
# Файлы на странице расположены в обратном порядке,
|
if spinner_id < 3:
|
||||||
# для этого перед их загрузкой и сохранением в .resume
|
spinner_id += 1
|
||||||
# списки сортируются от меньшего к большему.
|
|
||||||
|
|
||||||
# По этому было принято решение, удалять часть _NUM
|
|
||||||
# из имени файла при сохранение в .resume.
|
|
||||||
# Один хуй никто не будет парсить сайт с самого начала,
|
|
||||||
# чтобы скачать сиськи в более высоком качестве.
|
|
||||||
|
|
||||||
# Если в списке resume присутствует текущий загружаемый файл
|
|
||||||
# тогда цикл программы останавливается.
|
|
||||||
# P.S. смотри на костыль WHILE_BREAK
|
|
||||||
if not int(image.split(".")[0].split("_")[0]) in resume_files:
|
|
||||||
image_download(image)
|
|
||||||
resume_files.insert(
|
|
||||||
0,
|
|
||||||
int(image.split(".")[0].split("_")[0]),
|
|
||||||
)
|
|
||||||
downloaded_counter += 1
|
|
||||||
resume_save(resume_files)
|
|
||||||
else:
|
else:
|
||||||
WHILE_BREAK = True
|
spinner_id = 0
|
||||||
break
|
|
||||||
|
|
||||||
current_page += 1
|
current_page += 1
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("Загружено {0} файлов.".format(downloaded_counter))
|
print("\nВсего загружено {0} файлов.".format(downloaded_counter))
|
||||||
quit()
|
quit()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
click()
|
||||||
|
Loading…
Reference in New Issue
Block a user