Files
proxy-scraper-checker/proxy_scraper_checker/scraper.py
T

112 lines
3.2 KiB
Python
Raw Normal View History

2024-01-21 17:45:01 +00:00
from __future__ import annotations
import asyncio
import itertools
import logging
import aiofiles
import aiofiles.os
import aiofiles.ospath
from aiohttp import ClientResponseError, ClientSession, ClientTimeout
2024-01-21 17:45:01 +00:00
from aiohttp_socks import ProxyType
from rich.progress import Progress, TaskID
2024-01-23 09:37:29 +03:00
from .http import get_response_text
2024-01-21 17:45:01 +00:00
from .parsers import PROXY_REGEX
from .proxy import Proxy
from .settings import Settings
from .storage import ProxyStorage
from .utils import bytes_decode, is_url
logger = logging.getLogger(__name__)
async def scrape_one(
*,
progress: Progress,
proto: ProxyType,
session: ClientSession,
source: str,
storage: ProxyStorage,
task: TaskID,
timeout: ClientTimeout,
) -> None:
try:
if is_url(source):
async with session.get(source, timeout=timeout) as response:
2024-01-21 21:46:01 +03:00
content = await response.read()
2024-01-23 09:37:29 +03:00
text = get_response_text(response=response, content=content)
2024-01-21 17:45:01 +00:00
else:
async with aiofiles.open(source, "rb") as f:
content = await f.read()
2024-01-23 09:37:29 +03:00
text = bytes_decode(content)
except ClientResponseError as e:
logger.warning(
"%s | HTTP status code %d: %s", source, e.status, e.message
)
2024-01-21 17:45:01 +00:00
except Exception as e:
logger.warning(
"%s | %s.%s: %s",
source,
e.__class__.__module__,
e.__class__.__qualname__,
e,
)
else:
proxies = PROXY_REGEX.finditer(text)
try:
proxy = next(proxies)
except StopIteration:
logger.warning("%s | No proxies found", source)
2024-01-21 17:45:01 +00:00
else:
for proxy in itertools.chain((proxy,), proxies): # noqa: B020
try:
protocol = ProxyType[
"HTTP"
if (p := proxy.group("protocol").upper()) == "HTTPS"
else p
]
except AttributeError:
protocol = proto
storage.add(
Proxy(
protocol=protocol,
host=proxy.group("host"),
port=int(proxy.group("port")),
username=proxy.group("username"),
password=proxy.group("password"),
)
)
2024-01-25 11:49:22 +03:00
progress.advance(task_id=task, advance=1)
2024-01-21 17:45:01 +00:00
async def scrape_all(
*,
progress: Progress,
session: ClientSession,
settings: Settings,
storage: ProxyStorage,
) -> None:
2024-01-25 11:49:22 +03:00
progress_tasks = {
2024-01-21 17:45:01 +00:00
proto: progress.add_task(
2024-01-25 11:49:22 +03:00
description="", total=len(sources), col1="Scraper", col2=proto.name
2024-01-21 17:45:01 +00:00
)
for proto, sources in settings.sources.items()
}
timeout = ClientTimeout(total=settings.source_timeout)
2024-01-25 10:30:40 +03:00
await asyncio.gather(
*(
scrape_one(
progress=progress,
proto=proto,
session=session,
source=source,
storage=storage,
2024-01-25 11:49:22 +03:00
task=progress_tasks[proto],
2024-01-25 10:30:40 +03:00
timeout=timeout,
)
for proto, sources in settings.sources.items()
for source in sources
2024-01-21 17:45:01 +00:00
)
)