Лайфхаки

Маленькие, полезные хитрости

Обработка ошибок в парсере на python. Что не так?

19.09.2023 в 15:50

Обработка ошибок в парсере на python. Что не так?

Написал парсер на питоне. Копирует контент с чужого форума на мой форум, однако, то ли из-за таймаута на том или на моем форуме, то ли из-за проблем в соединении, парсер периодически вырубается из-за ошибок. Сейчас сделал так, чтобы парсер не вырубался, а вместо этого выводился текст в консоли и шел повтор запроса. Но это не решает проблему - эти повторы могут идти до бесконечности - а стоит закрыть и заново запустить скрипт - то все работает. Ниже прилагаю куски кода, где стоят try except. Может что-то не так сделал? Можно ли это на что-то заменить, чтобы при ошибке, происходил пропуск и дальнейшая работа скрипта? Скрипт копирует контент с нескольких форумов, поэтому важно чтобы при ошибке в соединении с одним форумом - шла работа дальше, со вторым и третьим форумом и т.д. Спасибо.

Python Requests параметры запроса. What’s Python’s Requests Library ?

Python's Requests library is apopular and powerful tool for making HTTP requests in Python. It simplifies the process of interacting with

With the Requests library, you can easily sendGET, POST, PUT, DELETE, and other types of HTTP requests. It handles tasks such as setting headers, managing cookies, handling redirects, and working with response data.

The library is widely used for tasks like web scraping, accessing RESTful APIs, and building web applications. It offers a straightforward and intuitive syntax, making it easy to understand and use.

One of the main advantages of Requests is its extensive documentation and active community support. You can find a wealth of resources, tutorials, and examples online to help you learn and use the library effectively.

In summary, Python’s Requests library is a valuable tool for performing HTTP requests in Python. It simplifies the process, provides a user-friendly API, and is widely adopted in the Python community.

Why learn Python requests module?

The Python Requestsmodule is worth learning due to its numerous advantages and functionalities. Firstly, it provides a simplified and user-friendly interface for making HTTP requests compared to the built-in libraries. This means you can easily perform common HTTP operations likeGET, POST, PUT, and DELETEwith just a few lines of code.

The module offers flexibility and extensibility, allowing you to handle various aspects of HTTP requests and responses. It supportsauthentication methods, cookies, sessions, SSL verification, and more. Additionally, Requests has extensive documentation and a large community, making it easy to find resources and examples online.

Learning the Requests module is particularly useful when working withweb APIs. It simplifies the process of interacting with APIs, making it easier to retrieve data and integrate it into your applications. Many web services provide documentation and examples using the Requests library, further facilitating the learning process.

Moreover, Requests is cross-platform compatible, allowing you to write code that works seamlessly on different operating systems. Its Pythonic and elegant design follows the principles of readability and simplicity, making it a joy to work with.

Overall, mastering the Python Requests module empowers you to handleHTTP requests effectively, interact with web services, and build robust applications. Its simplicity, versatility, and extensive community support make it a valuable tool for any Python developer.

Перехват исключений python. Перехватчики исключений

Всякий раз, когда возникает исключение, которое не обрабатывается в блоке try/except, вызывается функция, назначенная sys.excepthook. Эта функция, называемая перехватчиком исключения, применяется для вывода любых полезных сведений о происшествии в стандартный поток вывода. Для этого она пользуется тремя получаемыми ей аргументами — type (класс исключения), value (экземпляр исключения) иtraceback(объект трассировки).Разберём минимальный пример, демонстрирующий работу этого механизма:

import sys def exception_hook(exc_type, exc_value, tb):     print('Traceback:')     filename = tb.tb_frame.f_code.co_filename     name = tb.tb_frame.f_code.co_name     line_no = tb.tb_lineno     print(f"File {filename} line {line_no}, in {name}")     # Класс и экземпляр исключения     print(f"{exc_type.name}, Message: {exc_value}") sys.excepthook = exception_hook

Тут мы применяем вышеупомянутые аргументы для того чтобы вывести основные данные трассировки, имеющие отношение к исключению. А именно, объект трассировки (tb) используется для работы со сведениями о трассировке кадров стека. Там содержатся данные, описывающие место возникновения исключения — имя файла (f_code.co_filename), имя функции/модуля (f_code.co_name) и номер строки (tb_lineno).

Кроме того, мы выводим и сведения о самом исключении, пользуясь переменнымиexc_type и exc_value.

Теперь мы можем вызвать функцию, которая вызывает некое исключение. При наличии такого перехватчика мы увидим сообщение, показанное в нижней части следующего фрагмента кода:

def do_stuff():     # … сделать что-то такое, что вызывает исключение     raise ValueError("Some error message") do_stuff() Traceback: File /home/some/path/exception_hooks.py line 22, in ValueError, Message: Some error message

Здесь имеются лишь некоторые сведения об исключении. Для того чтобы увидеть всю информацию, необходимую для отладки кода, а так же — чтобы получить полное представление о том, где и почему произошло исключение, нам нужно поглубже «зарыться» в объект трассировки:

def exception_hook(exc_type, exc_value, tb):     local_vars = {}     while tb:         filename = tb.tb_frame.f_code.co_filename         name = tb.tb_frame.f_code.co_name         line_no = tb.tb_lineno         print(f"File {filename} line {line_no}, in {name}")         local_vars = tb.tb_frame.f_locals         tb = tb.tb_next     print(f"Local variables in top frame: {local_vars}") … File /home/some/path/exception_hooks.py line 41, in File /home/some/path/exception_hooks.py line 7, in do_stuff Local variables in top frame: {'some_var': 'data'}

Как видите, объект трассировки (tb), на самом деле, представляет собой связный список произошедших исключений — стектрейс. Этот факт позволяет нам пройтись по данному списку с помощью tb_next и вывести сведения о каждом кадре стека. Более того — можно, воспользовавшись атрибутом tb_frame.f_locals, вывести в консоль локальные переменные. Это способно оказать нам помощь при отладке кода.

Просмотр содержимого объекта трассировки, как мы уже видели, имеет смысл, но получаемые данные плохо организованы, их, по мере роста масштабов задачи, всё сложнее и сложнее воспринимать. Поэтому лучше будет воспользоваться модулем traceback, в котором имеется множество вспомогательных функций, нацеленных на извлечение информации об исключениях.

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

Игнорирование ошибок python. Как устроен механизм исключений

В Python есть встроенные исключения, которые появляются после того как приложение находит ошибку. В этом случае текущий процесс временно приостанавливается и передает ошибку на уровень вверх до тех пор, пока она не будет обработано. Если ошибка не будет обработана, программа прекратит свою работу (а в консоли мы увидим Traceback с подробным описанием ошибки).

‍♂️ Пример : напишем скрипт, в котором функция ожидает число, а мы передаём сроку (это вызовет исключение "TypeError"):

def b(value): print("-> b") print(value + 1) # ошибка тут def a(value): print("-> a") b(value) a("10") > -> a > -> b > Traceback (most recent call last): > File "test.py", line 11, in > a("10") > File "test.py", line 8, in a > b(value) > File "test.py", line 3, in b > print(value + 1) > TypeError: can only concatenate str (not "int") to str

В данном примере мы запускаем файл " test.py " (через консоль). Вызывается функция " a ", внутри которой вызывается функция " b ". Все работает хорошо до сточки print(value + 1) . Тут интерпретатор понимает, что нельзя конкатенировать строку с числом, останавливает выполнение программы и вызывает исключение "TypeError".

Далее ошибка передается по цепочке в обратном направлении: " b " → " a " → " test.py ". Так как в данном примере мы не позаботились обработать эту ошибку, вся информация по ошибке отобразится в консоли в виде Traceback.

Traceback (трассировка) — это отчёт, содержащий вызовы функций, выполненные в определенный момент. Трассировка помогает узнать, что пошло не так и в каком месте это произошло.

Traceback лучше читать снизу вверх ↑

Пример Traceback в Python

В нашем примере Traceback содержится следующую информацию (читаем снизу вверх):

    TypeError — тип ошибки (означает, что операция не может быть выполнена с переменной этого типа); can only concatenate str (not "int") to str — подробное описание ошибки (конкатенировать можно только строку со строкой);
  1. Стек вызова функций (1-я линия — место, 2-я линия — код). В нашем примере видно, что в файле "test.py" на 11-й линии был вызов функции "a" со строковым аргументом "10". Далее был вызов функции "b". print(value + 1) это последнее, что было выполнено — тут и произошла ошибка.
  2. most recent call last — означает, что самый последний вызов будет отображаться последним в стеке (в нашем примере последним выполнился print(value + 1) ).

В Python ошибку можно перехватить, обработать, и продолжить выполнение программы — для этого используется конструкция try … except … .

Try except python в цикле. Обработка исключений

При выполнении заданий к параграфам вы, скорее всего, нередко сталкивались с возникновением различных ошибок. В этом параграфе мы изучим подход, который позволяет обрабатывать ошибки после их возникновения.

Напишем программу, которая будет считать обратные значения для целых чисел из заданного диапазона и выводить их в одну строку с разделителем ';'. Один из вариантов кода для решения этой задачи выглядит так:

Программа получилась в одну строчку за счёт использования списочных выражений. Однако при вводе диапазона чисел, включающего в себя 0 (например, от -1 до 1), программа выдаст следующую ошибку:

В программе произошла ошибка «деление на ноль». Такая ошибка, возникающая при выполнении программы и останавливающая её работу, называется исключением .

Попробуем в нашей программе избавиться от возникновения исключения деления на ноль. Пусть при попадании 0 в диапазон чисел обработка не производится и выводится сообщение «Диапазон чисел содержит 0». Для этого нужно проверить до списочного выражения наличие нуля в диапазоне:

Теперь для диапазона, включающего в себя 0, например от -2 до 2, исключенияZeroDivisionErrorне возникнет. Однако при вводе строки, которую невозможно преобразовать в целое число (например, «a»), будет вызвано другое исключение:

ValueError: invalid literal for int() with base 10: 'a'

Произошло исключениеValueError. Для борьбы с этой ошибкой нам придётся проверить, что строка состоит только из цифр. Сделать это нужно до преобразования в число. Тогда наша программа будет выглядеть так:

start = input () end = input () # Метод lstrip("-"), удаляющий символы "-" в начале строки, нужен для учёта # отрицательных чисел, иначе isdigit() вернёт для них False if not (start.lstrip( "-" ).isdigit() and end.lstrip( "-" ).isdigit()): print ( " ввести два числа." ) else : interval = range ( int (start), int (end) + 1 ) if 0 in interval: print ( "Диапазон чисел содержит 0." ) else : print ( ";" .join( str ( 1 / x) for x in interval))

Теперь наша программа работает без ошибок и при вводе строк, которые нельзя преобразовать в целое число.

Подход, который был нами применён для предотвращения ошибок, называется Look Before You Leap (LBYL), или «Посмотри перед прыжком». В программе, реализующей такой подход, проверяются возможные условия возникновения ошибок до исполнения основного кода.

Подход LBYL имеет недостатки. Программу из примера стало сложнее читать из-за вложенного условного оператора. Проверка условия, что строка может быть преобразована в число, выглядит даже сложнее, чем списочное выражение. Вложенный условный оператор не решает поставленную задачу, а только лишь проверяет входные данные на корректность. Легко заметить, что решение основной задачи заняло меньше времени, чем составление условий проверки корректности входных данных.

Существует другой подход для работы с ошибками: Easier to Ask Forgiveness than Permission (EAFP), или «Проще попросить прощения, чем разрешения». В этом подходе сначала исполняется код, а в случае возникновения ошибок происходит их обработка. Подход EAFP реализован в Python в виде обработки исключений.

Обработчик ошибок python. Что такое исключения

Работа программиста во многом связана с возникающими в коде ошибками. Их приходится находить и исправлять. Особенно опасны так называемые гейзенбаги – ошибки, которые сложно воспроизвести. Так же существуют скрытые ошибки, их ещё можно назвать логическими. Ещё есть ошибки, которые и вовсе не зависят от программы. Представьте, у Вас есть программа-скрапер, которая автоматически скачивает картинки из соцсети. Заходит она на очередную страницу… А сервер сети поломался. Программа выдаст ошибку.

Если говорить именно о Питоне, то сложность ещё и в том, что это не компилируемый, а интерпретируемый язык, то есть код выполняется «на лету», строка за строкой. Это означает, что у Пайтон-программиста нет возможности отловить ошибки на этапе компиляции. Ещё одна сложность заключается в том, что Python – язык со строгой, но динамической типизацией. Частично это решается в последних версиях языка средством под названием «аннотирование типов», но полностью проблемы не устраняет.

И так, существуют следующие виды ошибок:

  • Синтаксические – когда программист нарушает правила самого языка, к примеру, допускает опечатку в ключевом слове;
  • Логические – когда в коде используется не верная логика;
  • Ввода – когда программист предполагал от пользователя ввода одних данных, а введены другие. К примеру, создатель сайта задумывал, что число в форме будет указано с использованием точки в качестве разделителя, а пользователь ввёл «3,14». Именно этот вид ошибок – излюбленная лазейка хакеров.

Синтаксические ошибки – самые простые, поскольку интерпретатор сам сообщит Вам о них при попытке запустить скрипт.

Простой пример, напечатали команду print с большой буквы:

Print ( 'Hello World!' ) # Вывод Traceback (most recent call last): File "C:/Users/ivand/PycharmProjects/pythonProject/main.py", line 1, in Print('Hello World!') NameError: name 'Print' is not defined   Process finished with exit code 1

Логические ошибки – самые сложные в обработке. Сложность в том, что скрипт запускается и не выдаёт никаких исключений, но результат работы отличается от ожидаемого. В чём причина и где её искать? Понятно, что использован не правильный алгоритм. В таких ситуациях можно посоветовать разбить алгоритм на части и проверять значение переменных в контрольных точках. Вот пример такой ошибки:

from random import randint random_list = 5 sorted_list = for i in range(random_list): sorted_list.append(randint(1, 99)) print(sorted_list) for i in range(random_list - 1): for j in range(random_list - i - 1): if sorted_list > sorted_list: sorted_list = sorted_list print(sorted_list) # Вывод:  

В этом примере программист хотел сделать сортировку пузырьком, но допустил ошибку. А Вы сможете её найти?

Ошибки ввода, как уже говорилось, это ошибки, чаще всего возникающие из-за того, что программист и пользователь не поняли друг друга. Вот код примера, приведённого выше:

x_var = input ( 'Введите число и мы его разделим на 10 \n' ) print ( 'Результат деления:', float ( x_var ) / 10 ) # Вывод:   Введите число и мы его разделим на 10 3,14 Traceback (most recent call last): File "C:/Users/ivand/PycharmProjects/pythonProject/main.py", line 2, in print('Результат деления:', float(x_var) / 10) ValueError: could not convert string to float: '3,14'

Как вы видите, интерпретатор «выбрасывает» исключение «ValueError» — ошибка значения и останавливает выполнение кода.

Try except python вывести ошибку. Синтаксис обработки исключений python

Обработка исключений в Python осуществляется с помощью блокаtry-except. Код, который может вызвать исключение, помещается в блокtry, а код, который обрабатывает исключение, помещается в блокexcept. Кроме того, можно использовать блокelseдля выполнения кода в случае, если исключение не было вызвано, и блокfinallyдля выполнения кода независимо от того, было вызвано исключение или нет.

Синтаксис блокаtry-exceptвыглядит следующим образом:

try: # блок кода, который может вызвать исключение except Имя_исключения_1: # код обработки исключения Имя_исключения_1 except Имя_исключения_2: # код обработки исключения Имя_исключения_2 … except Имя_исключения_n: # код обработки исключения Имя_исключения_n else: # блок кода, который будет выполнен, если исключение не было вызвано finally: # блок кода, который будет выполнен в любом случае

Блокexceptможет содержать несколько имен исключений, разделенных запятыми, для обработки нескольких типов исключений одновременно. Если имя исключения не указано, будет обработано любое возникшее исключение.

Пример:

try: # блок кода, который может вызвать исключение except Имя_исключения as e: # код обработки исключения print(e) # вывод информации об исключении else: # блок кода, который будет выполнен, если исключение не было вызвано finally: # блок кода, который будет выполнен в любом случае

В блокеexceptможно использовать переменную для получения информации об исключении. Эта переменная обычно называется «e» или «exception», но может иметь любое другое имя. В примере мы выводим информацию об исключении с помощью функцииprint().

Python http request. Использование Python для работы с API

API библиотеки requests позволяет разработчикам писать код для взаимодействия с REST API. Это дает им возможность отправлять HTTP-запросы с помощью Python, не беспокоясь о сложностях, которые обычно возникают при выполнении таких задач (например, ручное добавление строк запроса к URL-адресам, кодирование форм данных PUT и POST и т. д.).

Несмотря на то, что библиотека requests считается де-факто стандартом для создания HTTP-запросов в Python, она не является частью стандартной библиотеки Python и ее необходимо установить.

Наиболее естественно сделать это при помощи менеджера пакетов pip:

python -m pip install requests

Этот код представляет собой команду, которую можно запустить в терминале или в командной строке. Флаг-mуказывает интерпретатору Python запустить модуль pip как скрипт, аrequest— это имя устанавливаемого пакета. После выполнения этой команды библиотека requests будет установлена ​​и доступна для использования в среде Python.

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

Теперь, когда у нас установлен модуль requests, давайте посмотрим, как он работает.

Делаем GET-запрос

Мы уже говорили, что GET — это один из наиболее распространенных HTTP-запросов, с которыми вы столкнетесь при работе с REST API. Он позволяет вам (то есть клиенту) получать данные с веб-серверов.

Важно отметить, что GET — это операция только для чтения. Это означает, что она подходит только для доступа к существующим ресурсам, но не должна использоваться для их изменения.

Чтобы продемонстрировать, как работает модуль запроса, мы будем использовать JSONPlaceholder — свободно доступный API, используемый для тестирования и прототипирования.

Рассмотрим следующий код:

import requests # Конечная точка API url = "https://jsonplaceholder.typicode.com/posts/1" # GET-запрос к API response = requests.get(url) # Выводим ответ в консоль response_json = response.json() print(response_json) # Результат """ {'userId': 1, 'id': 1, 'title': 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 'body': 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto'} """

В приведенном выше коде мы сделали следующее:

  1. Определили конечную точка API для извлечения данных.
  2. Для получения данных из определенной конечной точки использовали методrequest.get(url).
  3. Мы использовали методresponse.json()для хранения данных ответа в объекте словаря. Обратите внимание, что это работает только потому, что результат записывается в формате JSON — иначе бы возникла ошибка.
  4. Последний шаг — выводим данные ответа в консоль в формате JSON .

Код состояния, возвращенный нам API, мы можем проверить следующим образом:

# Print status code from original response (not JSON) print(response.status_code) # Результат """ 200 """

Результат показывает, что код состояния равен 200. Это значит, что запрос выполнен успешно.

Категории: Ошибки в парсере