Skip to content

Instantly share code, notes, and snippets.

@cynthia2006
Last active February 11, 2026 18:12
Show Gist options
  • Select an option

  • Save cynthia2006/0c6e0e72786ba6a6e5aa655c50ac3eb3 to your computer and use it in GitHub Desktop.

Select an option

Save cynthia2006/0c6e0e72786ba6a6e5aa655c50ac3eb3 to your computer and use it in GitHub Desktop.
# /// script
# requires-python = ">=3.14"
# dependencies = [
# "aiofiles>=25.1.0",
# "httpx[http2]>=0.28.1",
# ]
# ///
import asyncio
import sys
from pathlib import PurePath
from signal import SIGINT
import aiofiles
import httpx
MAX_QUEUE_SIZE = 60
MAX_WORKERS = 10
stop_now = asyncio.Event()
async def download(client: httpx.AsyncClient, queue: asyncio.Queue):
while True:
if stop_now.is_set():
break
url, path = await queue.get()
async with (
aiofiles.open(path, 'wb') as output,
client.stream('GET', url) as r
):
if r.status_code != 200:
print(f"{url} not found on Pixiv, ignoring", file=sys.stderr)
if size := r.headers.get('Content-Length'):
await output.truncate(int(size))
async for chunk in r.aiter_bytes():
await output.write(chunk)
if size:
print(f"Downloaded {url} -> {path}; content-length {size}")
else:
print(f"Downloaded {url} -> {path}; content-length unknown")
async def main():
loop = asyncio.get_event_loop()
loop.add_signal_handler(SIGINT, lambda: stop_now.set())
async with (
httpx.AsyncClient(http2=True, timeout=None) as client,
):
queue = asyncio.Queue(MAX_QUEUE_SIZE)
tasks = set()
# Shielding is required to prevent premature writes.
for _ in range(MAX_WORKERS):
tasks.add(asyncio.shield(download(client, queue)))
while True:
if stop_now.is_set():
break
r = await client.get('https://api.lolicon.app/setu/v2?num=20')
if r.status_code != 200:
print(f"Lolicon API returned {r.status_code}", file=sys.stderr)
continue
data = r.json()['data']
for entry in data:
url = httpx.URL(entry['urls']['original'])
filename = PurePath(url.path).name
await queue.put((url, filename))
await asyncio.sleep(5)
await asyncio.gather(*tasks)
if __name__ == '__main__':
asyncio.run(main())
@cynthia2006
Copy link
Author

All it takes to run is

$ uv run https://gist.githubusercontent.com/cynthia2006/0c6e0e72786ba6a6e5aa655c50ac3eb3/raw/19f6b4c93997d7f502c56649417c46a16b5dab55/loli-dl.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment