update to 1.0.2
This commit is contained in:
parent
b2f6d710b3
commit
5aadc4603a
16
.editorconfig
Normal file
16
.editorconfig
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
venv/
|
|
||||||
images/
|
images/
|
||||||
|
165
stanis-tits.py
165
stanis-tits.py
@ -7,24 +7,30 @@ import requests
|
|||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
__author__ = "Alexander Popov"
|
__author__ = "Alexander Popov"
|
||||||
__version__ = "1.0.1"
|
__version__ = "1.0.2"
|
||||||
__license__ = "Unlicense"
|
__license__ = "Unlicense"
|
||||||
|
|
||||||
DOWNLOAD_DIR = "./images"
|
# Путь к директории для загрузки изображений
|
||||||
|
DOWNLOAD_DIRECTORY = "./images"
|
||||||
|
|
||||||
|
|
||||||
def checkResumeFile():
|
def resume_load():
|
||||||
|
"""Возвращает список последних 20 загруженных файлов"""
|
||||||
|
|
||||||
|
# Проверяет наличие файла .resume
|
||||||
if not os.path.exists(
|
if not os.path.exists(
|
||||||
"{0}/.resume".format(
|
"{0}/.resume".format(
|
||||||
DOWNLOAD_DIR,
|
DOWNLOAD_DIRECTORY,
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
if not os.path.exists(DOWNLOAD_DIR):
|
# Создаёт директорию для загрузки сисек
|
||||||
os.mkdir(DOWNLOAD_DIR)
|
if not os.path.exists(DOWNLOAD_DIRECTORY):
|
||||||
|
os.mkdir(DOWNLOAD_DIRECTORY)
|
||||||
|
|
||||||
|
# Создаёт файл .resume и пишет в него 0
|
||||||
with open(
|
with open(
|
||||||
"{0}/.resume".format(
|
"{0}/.resume".format(
|
||||||
DOWNLOAD_DIR,
|
DOWNLOAD_DIRECTORY,
|
||||||
),
|
),
|
||||||
"w",
|
"w",
|
||||||
) as f:
|
) as f:
|
||||||
@ -33,50 +39,64 @@ def checkResumeFile():
|
|||||||
else:
|
else:
|
||||||
with open(
|
with open(
|
||||||
"{0}/.resume".format(
|
"{0}/.resume".format(
|
||||||
DOWNLOAD_DIR,
|
DOWNLOAD_DIRECTORY,
|
||||||
),
|
),
|
||||||
"r",
|
"r",
|
||||||
) as f:
|
) as f:
|
||||||
lines = [line.split("\n")[0] for line in f][-20:]
|
lines = [int(line.split("\n")[0]) for line in f][-20:]
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def saveResume(resumeList):
|
def resume_save(donwloaded_list):
|
||||||
resumeList.sort()
|
"""Сохраняет список последних 20 загруженных файлов"""
|
||||||
|
|
||||||
|
donwloaded_list.sort()
|
||||||
with open(
|
with open(
|
||||||
"{0}/.resume".format(
|
"{0}/.resume".format(
|
||||||
DOWNLOAD_DIR,
|
DOWNLOAD_DIRECTORY,
|
||||||
),
|
),
|
||||||
"w",
|
"w",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as f:
|
) as f:
|
||||||
for item in resumeList[-20:]:
|
for item in donwloaded_list[-20:]:
|
||||||
f.write("{0}\n".format(item))
|
f.write("{0}\n".format(item))
|
||||||
|
|
||||||
|
|
||||||
def getImagesLinks(page):
|
def get_images_links(page):
|
||||||
URL = lambda page: "http://blog.stanis.ru/?back={0}".format(
|
"""В качестве аргумента получает номер страницы
|
||||||
page,
|
и возвращает списком адреса всех изображений"""
|
||||||
)
|
|
||||||
COOKIES = dict(block="951")
|
|
||||||
|
|
||||||
r = requests.get(URL(page), cookies=COOKIES)
|
# На сайте фильтр изображений настроен через cookies
|
||||||
|
# Так что устанавливаем их в нужное положение
|
||||||
|
cookies = dict(block="951")
|
||||||
|
|
||||||
|
# Загружаем страницу и подсовываем её парсеру с необходимыми параметрами
|
||||||
|
r = requests.get(
|
||||||
|
"http://blog.stanis.ru/?back={0}".format(
|
||||||
|
page,
|
||||||
|
),
|
||||||
|
cookies=cookies,
|
||||||
|
)
|
||||||
soup = BeautifulSoup(
|
soup = BeautifulSoup(
|
||||||
r.text.encode("cp1251"), "html.parser", from_encoding="windows-1251"
|
r.text.encode("cp1251"), "html.parser", from_encoding="windows-1251"
|
||||||
)
|
)
|
||||||
|
|
||||||
imagesData = soup.findAll("img", src=re.compile("img/*"))
|
# Получаем все теги <img> на странице
|
||||||
|
img_tags = soup.findAll("img", src=re.compile("img/*"))
|
||||||
|
|
||||||
imagesUrl = list()
|
# Получаем все адреса изображений и сохраняем их в список img_links
|
||||||
|
img_links = list()
|
||||||
|
for image in img_tags:
|
||||||
|
img_links.append(image["src"].split("/")[1])
|
||||||
|
|
||||||
for image in imagesData:
|
return img_links
|
||||||
imagesUrl.append(image["src"].split("/")[1])
|
|
||||||
|
|
||||||
return imagesUrl
|
|
||||||
|
|
||||||
|
|
||||||
def imageDownload(image):
|
def image_download(image):
|
||||||
|
"""В качестве аргумента получает уникальное имя изображения,
|
||||||
|
скачивает и сохраняет его на диск"""
|
||||||
|
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
"https://blog.stanis.ru/imgs/{0}".format(
|
"https://blog.stanis.ru/imgs/{0}".format(
|
||||||
image,
|
image,
|
||||||
@ -84,33 +104,82 @@ def imageDownload(image):
|
|||||||
stream=True,
|
stream=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
with open("{0}/{1}".format(DOWNLOAD_DIR, image), "wb") as out_image:
|
image_size = int(response.headers.get("Content-Length", 0))
|
||||||
shutil.copyfileobj(
|
|
||||||
response.raw,
|
if (
|
||||||
out_image,
|
os.path.exists("{0}/{1}".format(DOWNLOAD_DIRECTORY, image))
|
||||||
)
|
and int(os.path.getsize("{0}/{1}".format(DOWNLOAD_DIRECTORY, image)))
|
||||||
|
== image_size
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
with open("{0}/{1}".format(DOWNLOAD_DIRECTORY, image), "wb") as out_image:
|
||||||
|
shutil.copyfileobj(
|
||||||
|
response.raw,
|
||||||
|
out_image,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
resumeFiles = checkResumeFile()
|
"""Главный цикл программы"""
|
||||||
|
|
||||||
LOOP = True
|
resume_files = resume_load()
|
||||||
downloadPage = 0
|
|
||||||
|
|
||||||
while LOOP:
|
current_page = 0
|
||||||
imagesLinks = getImagesLinks(downloadPage)
|
downloaded_counter = 0
|
||||||
imagesLinks.sort()
|
|
||||||
|
|
||||||
for image in imagesLinks:
|
WHILE_BREAK = False
|
||||||
if not image.split(".")[0] in resumeFiles:
|
|
||||||
imageDownload(image)
|
|
||||||
resumeFiles.insert(
|
|
||||||
0,
|
|
||||||
image.split(".")[0],
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
LOOP = False
|
|
||||||
|
|
||||||
downloadPage += 1
|
while True:
|
||||||
|
try:
|
||||||
|
# Получаем адреса изображений и сортируем их в порядке возрастания
|
||||||
|
images = get_images_links(current_page)
|
||||||
|
images.sort()
|
||||||
|
|
||||||
saveResume(resumeFiles)
|
# Костыль
|
||||||
|
if WHILE_BREAK:
|
||||||
|
break
|
||||||
|
|
||||||
|
# По очереди скачиваем изображения
|
||||||
|
for image in images:
|
||||||
|
# На сайте могут обновляться изображения,
|
||||||
|
# когда находятся варианты более лучшего
|
||||||
|
# качества и разрешения.
|
||||||
|
# К именам таких файлов добавляется _NUM,
|
||||||
|
# где NUM - количество изменений,
|
||||||
|
# например 1356_3.jpg
|
||||||
|
|
||||||
|
# Файл .resume хранит последние 20 загруженных файлов.
|
||||||
|
# Бывает иногда, что изображение удаляется
|
||||||
|
# и может получиться так, что сохраненное имя в .resume
|
||||||
|
# будет отсутсвовать на странице, что будет в холостую
|
||||||
|
# продолжать работу скрипта.
|
||||||
|
|
||||||
|
# Файлы на странице расположены в обратном порядке,
|
||||||
|
# для этого перед их загрузкой и сохранением в .resume
|
||||||
|
# списки сортируются от меньшего к большему.
|
||||||
|
|
||||||
|
# По этому было принято решение, удалять часть _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:
|
||||||
|
WHILE_BREAK = True
|
||||||
|
break
|
||||||
|
|
||||||
|
current_page += 1
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Загружено {0} файлов.".format(downloaded_counter))
|
||||||
|
quit()
|
||||||
|
Loading…
Reference in New Issue
Block a user