Загрузка данных
import re
from pathlib import Path
from urllib.parse import urlparse, parse_qs, unquote, urlencode, urlunparse
from playwright.sync_api import sync_playwright
FOLDER_URL = "https://disk.yandex.ru/client/disk/%D1%81%D0%B2%D0%B0%D0%B4%D1%8C%D0%B1%D0%B0%208.09.18%20(%D1%80%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F%20%D0%BF%D0%B0%D0%BF%D0%BA%D0%B0)" # ссылка на папку
OUT_DIR = Path("photos_best_0_1")
PROFILE_DIR = "browser_profile"
WAIT_SEC = 8 # сколько ждать смены фото после стрелки
MAX_FAILS = 4 # сколько пропусков подряд считать концом папки
TRY_BIGGER = True # пробовать запросить превью покрупнее
OUT_DIR.mkdir(exist_ok=True)
FIND_IMG = """
() => {
let best = null, bestArea = 0;
for (const img of document.images) {
const r = img.getBoundingClientRect();
const area = r.width * r.height;
if (r.width > 300 && r.height > 300 && img.complete && img.naturalWidth > 300
&& area > bestArea && img.currentSrc.startsWith('http')) {
best = img; bestArea = area;
}
}
return best ? best.currentSrc : null;
}
"""
def ext_of(ct):
ct = (ct or "").lower()
if "png" in ct:
return ".png"
if "webp" in ct:
return ".webp"
if "gif" in ct:
return ".gif"
return ".jpg"
def bigger_url(url):
u = urlparse(url)
q = parse_qs(u.query)
if "size" not in q:
return None
q["size"] = ["4000x4000"]
return urlunparse(u._replace(query=urlencode(q, doseq=True)))
def fetch(ctx, url):
try:
r = ctx.request.get(url)
if r.ok and r.headers.get("content-type", "").startswith("image/"):
return r
except Exception as e:
print(f" ошибка запроса: {e}")
return None
def save(ctx, src, n):
resp = None
if TRY_BIGGER:
big = bigger_url(src)
if big:
resp = fetch(ctx, big)
if resp is None:
resp = fetch(ctx, src)
if resp is None:
print(f"[{n}] ОШИБКА скачивания: {src[:120]}")
return False
u = urlparse(src)
q = parse_qs(u.query)
name = unquote(q["filename"][0]) if "filename" in q else unquote(Path(u.path).name)
name = re.sub(r'[\\/:*?"<>|]', "_", name) or "photo"
if not Path(name).suffix:
name += ext_of(resp.headers.get("content-type"))
body = resp.body()
(OUT_DIR / f"{n:04d}_{name}").write_bytes(body)
print(f"[{n}] {name} {len(body) / 1e6:.2f} МБ")
return True
with sync_playwright() as p:
ctx = p.chromium.launch_persistent_context(
PROFILE_DIR,
headless=False,
viewport={"width": 1800, "height": 850},
device_scale_factor=2,
)
page = ctx.pages[0] if ctx.pages else ctx.new_page()
page.goto(FOLDER_URL)
input("Откройте ПЕРВОЕ фото, дождитесь загрузки и нажмите Enter... ")
page.bring_to_front()
seen = set()
n = 0
skipped = 0
fails = 0
last = page.evaluate(FIND_IMG)
if last:
seen.add(last)
n += 1
save(ctx, last, n)
while True:
page.keyboard.press("ArrowRight")
new = None
for _ in range(WAIT_SEC * 4):
page.wait_for_timeout(250)
s = page.evaluate(FIND_IMG)
if s and s != last:
page.wait_for_timeout(400) # догрузка качественной версии
new = page.evaluate(FIND_IMG) or s
break
if new and new not in seen:
seen.add(new)
last = new
n += 1
save(ctx, new, n)
fails = 0
else:
fails += 1