Обработка BrokenPipeError в сценарии Selenium Python при невозможности открыть URL-адреса и загрузить их на Google Диск

Я работаю над сценарием Python, который перемещается по списку URL-адресов, делает снимки веб-страниц и затем загружает их на Google Диск с помощью Selenium, Google API и GSP. Сценарий должен попытаться открыть каждый URL-адрес пять раз; если ему не удается открыть URL-адрес после пяти попыток, предполагается, что он пропустит текущую итерацию с помощью оператора continue и перейдет к следующему URL-адресу.

Однако я сталкиваюсь с BrokenPipeError всякий раз, когда сценарию не удается открыть URL-адрес после указанных попыток. Вместо перехода к следующему URL-адресу сценарий останавливает выполнение, что не является ожидаемым поведением. Ниже приведена соответствующая часть кода:

max_attempts = 5

for record in records:
    url = record['Link']
    folder_id = record['Link to folder']
    successful_connection = False  # Flag to track if connection was successful

    for attempt in range(max_attempts):
        try:
            driver.get(url)
            time.sleep(random.uniform(1, 3))
            successful_connection = True  # Set the flag to True if successful
            break  # Exit the loop if successful
        except Exception as e:  # Catch the specific exception if possible
            print(f"Attempt {attempt + 1} of {max_attempts} failed: {str(e)}")
            time.sleep(10)  # Wait for 10 seconds before retrying

    if not successful_connection:
        print(f"Failed to connect to {url} after {max_attempts} attempts.")
        continue  # Skip the rest of the code in this loop iteration and move to the next record
    
    # If connection was successful, proceed with screenshot and upload
    current_date = datetime.now().strftime('%Y-%m-%d')
    page_width = driver.execute_script('return document.body.scrollWidth')
    page_height = driver.execute_script('return document.body.scrollHeight')
    screenshot_path = f"{current_date}-{record['Client']}-{record['Platform']}.png"
    driver.set_window_size(page_width, page_height)
    driver.save_screenshot(screenshot_path)

    # Upload to Google Drive
    file_metadata = {'name': screenshot_path, 'parents': [folder_id]}
    media = MediaFileUpload(screenshot_path, mimetype='image/png')
    file = drive_service.files().create(body=file_metadata, media_body=media, fields='id').execute()
    
    os.remove(screenshot_path)

driver.quit()

И ошибка:

    self._send_request(method, url, body, headers, encode_chunked)
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/http/client.py", line 1331, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/http/client.py", line 1280, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/http/client.py", line 1040, in _send_output
    self.send(msg)
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/http/client.py", line 1001, in send
    self.sock.sendall(data)
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/ssl.py", line 1238, in sendall
    v = self.send(byte_view[count:])
  File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/ssl.py", line 1207, in send
    return self._sslobj.write(data)
BrokenPipeError: [Errno 32] Broken pipe
Error: Process completed with exit code 1.

Я подозреваю, что проблема может быть связана со способом обработки исключений или управлением ресурсами, но я не уверен, как определить проблему или устранить ошибку BrokenPipeError. Мы будем очень признательны за любые предложения или идеи о том, что может быть причиной этой проблемы и как ее исправить.

Я попытался создать пустой PNG-файл и загрузить его на случай, если соединение окажется неудачным, но все равно получаю ту же ошибку.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Специальная обработка исключений: Перехват широкого исключения может выявить не только проблемы, связанные с подключением. Хорошей практикой является перехват более конкретных исключений, которые могут быть вызваны driver.get(), чтобы более адекватно обрабатывать различные сценарии ошибок. Например, вы можете захотеть перехватить TimeoutException для тайм-аутов, WebDriverException для общих проблем WebDriver или другие, в зависимости от вашего варианта использования.

python

from selenium.common.exceptions import TimeoutException, WebDriverException

for attempt in range(max_attempts):
    try:
        driver.get(url)
        time.sleep(random.uniform(1, 3))
        successful_connection = True
        break
    except TimeoutException as e:
        print(f"Attempt {attempt + 1} of {max_attempts} failed: Timeout - {str(e)}")
        time.sleep(10)
    except WebDriverException as e:
        print(f"Attempt {attempt + 1} of {max_attempts} failed: WebDriver issue - {str(e)}")
        time.sleep(10)
    # Add more specific exceptions as needed

Ведение журнала: Рассмотрите возможность использования модуля регистрации вместо операторов печати для регистрации. Это позволяет вам лучше контролировать уровни журналов, форматирование и направление журналов на разные выходы.

python

import logging

logging.basicConfig(level=logging.INFO)

for attempt in range(max_attempts):
    try:
        driver.get(url)
        time.sleep(random.uniform(1, 3))
        successful_connection = True
        break
    except TimeoutException as e:
        logging.error(f"Attempt {attempt + 1} of {max_attempts} failed: Timeout - {str(e)}")
        time.sleep(10)
    except WebDriverException as e:
        logging.error(f"Attempt {attempt + 1} of {max_attempts} failed: WebDriver issue - {str(e)}")
        time.sleep(10)
    # Add more specific exceptions as needed

Обработка очистки WebDriver: Убедитесь, что вы выполняете очистку WebDriver, даже если возникает исключение. Возможно, вы захотите использовать блок try...finally, чтобы убедиться, что вызывается driver.quit().

python

    try:
        # Your existing code
    finally:
        driver.quit()

Эти предложения предназначены для повышения надежности и удобства сопровождения вашего сценария. В зависимости от вашего конкретного варианта использования и требований вам может потребоваться соответствующим образом скорректировать подход к обработке и ведению журнала исключений.

Посмотрите, что вы думаете об этом:

python

import time
import random
from datetime import datetime
from selenium.common.exceptions import TimeoutException, WebDriverException
import logging

# Configure logging
logging.basicConfig(level=logging.INFO)

max_attempts = 5

for record in records:
    url = record['Link']
    folder_id = record['Link to folder']
    successful_connection = False  # Flag to track if connection was successful

    for attempt in range(max_attempts):
        try:
            driver.get(url)
            time.sleep(random.uniform(1, 3))
            successful_connection = True  # Set the flag to True if successful
            break  # Exit the loop if successful
        except TimeoutException as e:
            logging.error(f"Attempt {attempt + 1} of {max_attempts} failed: Timeout - {str(e)}")
            time.sleep(10)
        except WebDriverException as e:
            logging.error(f"Attempt {attempt + 1} of {max_attempts} failed: WebDriver issue - {str(e)}")
            time.sleep(10)
        except Exception as e:  # Catch other specific exceptions if needed
            logging.error(f"Attempt {attempt + 1} of {max_attempts} failed: {str(e)}")
            time.sleep(10)

    if not successful_connection:
        logging.error(f"Failed to connect to {url} after {max_attempts} attempts.")
        continue  # Skip the rest of the code in this loop iteration and move to the next record

    # If connection was successful, proceed with screenshot and upload
    current_date = datetime.now().strftime('%Y-%m-%d')
    page_width = driver.execute_script('return document.body.scrollWidth')
    page_height = driver.execute_script('return document.body.scrollHeight')
    screenshot_path = f"{current_date}-{record['Client']}-{record['Platform']}.png"
    driver.set_window_size(page_width, page_height)
    driver.save_screenshot(screenshot_path)

    # Upload to Google Drive
    file_metadata = {'name': screenshot_path, 'parents': [folder_id]}
    media = MediaFileUpload(screenshot_path, mimetype='image/png')
    file = drive_service.files().create(body=file_metadata, media_body=media, fields='id').execute()

    os.remove(screenshot_path)

# Ensure proper cleanup
try:
    driver.quit()
except Exception as e:
    logging.error(f"Failed to quit the WebDriver: {str(e)}")

В этом модифицированном скрипте:

Конкретные исключения, такие как TimeoutException и WebDriverException, перехватываются отдельно для лучшей обработки ошибок.

Вместо операторов печати используется журналирование для лучшего контроля и гибкости.

Блок try...finally гарантирует, что driver.quit() вызывается правильно. очистка, даже если во время выполнения возникает исключение.

Обязательно адаптируйте сценарий в соответствии с вашими конкретными требованиями и средой, в которой он работает.

Похоже, что этот пост был полностью или частично создан с помощью инструментов искусственного интеллекта. Обратите внимание, что Генеративный ИИ (например, ChatGPT) запрещен , и прочтите Справочный центр: Политика ИИ . Запрещается использовать инструменты искусственного интеллекта для создания или изменения содержания контента, который вы публикуете в Stack Overflow, даже если вы предварительно проверяете этот контент. Работа других лиц без указания авторства также является плагиатом. Читателям следует внимательно и критически просмотреть этот ответ, поскольку информация, генерируемая ИИ, часто содержит фундаментальные ошибки и дезинформацию.

Dalija Prasnikar 07.03.2024 18:43

Другие вопросы по теме