Как обходить ошибку «слишком много открытых файлов» при использовании Playwright?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как обходить ошибку «слишком много открытых файлов» при использовании Playwright?

Сообщение Anonymous »

Я использую драматург для ползания. У меня есть функция очистки, которая использует Playwright, и реализовал объект Python, который использует эту функцию для ползания веб-сайтов в поисках хлеба.

Код: Выделить всё

import logging
from collections import deque

from playwright.async_api import Browser, BrowserContext, async_playwright

async def fetch_page_content(
url: str,
browser: Browser = None,
context: BrowserContext = None,
open_pages: deque = None,
max_open_pages: int = 100,
timeout: int = 60000,
headless: bool = True,
logger: logging.Logger = None,
) -> str | None:
should_close_browser = browser is None
should_close_context = context is None

if should_close_browser:
p = await async_playwright().start()
browser = await p.chromium.launch(headless=headless)

if should_close_context:
context = await browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
)

if open_pages is not None:
if len(open_pages) >= max_open_pages:
old_page = open_pages.popleft()
await old_page.close()

page = await context.new_page()

if open_pages is not None:
open_pages.append(page)

try:
response = await page.goto(url, timeout=timeout, wait_until="load")
if not response or response.status >= 400:
if logger:
logger.error(f"Failed to fetch {url}")
return None
html = await page.content()
return html
except Exception as e:
if logger:
logger.warning(f"Error fetching {url}: {e}")
return None
finally:
await page.close()
if open_pages is not None and page in open_pages:
open_pages.remove(page)
if should_close_context:
await context.close()
if should_close_browser:
await browser.close()
< /code>
Внутри моего гусеница часть, которая использует эту функцию, заключается в следующем: < /p>

async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context()

total_pages = 0

while self.queue:
batch = []
for _ in range(self.parallel_requests):
if not self.queue:
break

url, depth = self.queue.popleft()

if url in self.visited_urls or depth >  self.max_depth:
continue

should_skip_url_, reason = should_skip_url(url=url)

if should_skip_url_:
self.logger.info(f"Skipping {url}: {reason}")
continue

total_pages += 1
self.logger.info(f"[{total_pages}] Crawling: {url} (Depth: {depth})")

self.visited_urls.add(url)
batch.append((url, depth))

self.logger.info(f"open_pages size before fetching batch: {len(self.open_pages)}")
tasks = [
fetch_page_content(
url=url,
context=context,
open_pages=self.open_pages,
max_open_pages=self.max_open_pages,
logger=self.logger,
)
for url, depth in batch
]

html_results = await asyncio.gather(*tasks, return_exceptions=True)
self.logger.info(f"open_pages size after fetching batch: {len(self.open_pages)}")

for (url, depth), html_result in zip(batch, html_results):
processing_successful = await self.process_and_save_fetched_html(url=url, html=html_result)
if not processing_successful:
continue

links = await self.extract_links(html=html_result, base_url=url)
await self.validate_and_enqueue_links(url=url, links=links, depth=depth)

if total_pages % self.restart_interval == 0 and total_pages != 0:
self.logger.info("Restarting browser and context...")
await context.close()
await browser.close()
browser = await p.chromium.launch(headless=True)
context = await browser.new_context()
То, что я пробовал, следующим образом:

[*] Ограничение ограничения с использованием более низких значений parallel_requests .
вручную закрыть страницы, используя open_pages deque. интервал. Я бы предпочел не повышать значения системы для максимальных открытых страниц и позаботиться о ней на уровне кода, если это возможно.

Подробнее здесь: https://stackoverflow.com/questions/795 ... playwright
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Многопроцессорность Python вызывает ошибку OSError: [Errno 24] Слишком много открытых файлов
    Anonymous » » в форуме Python
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • При экспорте иногда появляется «Слишком много открытых файлов».
    Гость » » в форуме Linux
    0 Ответы
    25 Просмотры
    Последнее сообщение Гость
  • Rust-Lang Abstarct доменный сокет unix, слишком много открытых файлов [максимальное количество сокетов] [закрыто]
    Anonymous » » в форуме Linux
    0 Ответы
    62 Просмотры
    Последнее сообщение Anonymous
  • AWS Lambda: IOException: слишком много открытых файлов
    Anonymous » » в форуме C#
    0 Ответы
    38 Просмотры
    Последнее сообщение Anonymous
  • AWS Lambda: IOException: слишком много открытых файлов
    Гость » » в форуме C#
    0 Ответы
    35 Просмотры
    Последнее сообщение Гость

Вернуться в «Python»