Я работаю над сценарием 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-файл и загрузить его на случай, если соединение окажется неудачным, но все равно получаю ту же ошибку.
Специальная обработка исключений: Перехват широкого исключения может выявить не только проблемы, связанные с подключением. Хорошей практикой является перехват более конкретных исключений, которые могут быть вызваны 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, даже если вы предварительно проверяете этот контент. Работа других лиц без указания авторства также является плагиатом. Читателям следует внимательно и критически просмотреть этот ответ, поскольку информация, генерируемая ИИ, часто содержит фундаментальные ошибки и дезинформацию.