Лучший опыт

Python стал языком, широко исп? ... Парсинг с помощью Python Requests

Парсинг с помощью Python Requests...

Python стал языком, широко используемым разработчиками, потому что он прост, эффективен и гибок. Здесь мы узнаем, как скреативить веб-сайты с помощью Python. Мы изучим несколько основных концепций, но основное внимание мы уделим парсингу в Python с помощью библиотеки Requests.Проще говоря, парсинг означает получение содержимого сайта и извлечение из него нужных данных. Почти все языки программирования предоставляют поддержку для автоматизации этого процесса. Аналогичным образом, в Python также есть библиотеки, позволяющие сделать этот процесс проще и быстрее.

Содержание скрыть

Почему Python используется для парсинга?

Существует множество причин, по которым вам следует использовать Python для парсинга. Вот несколько из них:

  • Python имеет огромное сообщество, которое предоставляет сотни статей и документации для новичков. Это облегчает работу новичков, и они могут быстро освоить язык.
  • Python славится своей читабельностью, что облегчает понимание и написание кода.
  • В нем есть предопределенные функции, что означает, что нам не нужно писать функции. Это экономит время и делает процесс более быстрым.
  • Нам не нужно определять типы данных: просто определите переменную и присвойте ей значение любого типа.
  • Он предоставляет инструменты обработки и визуализации данных, что упрощает их анализ и структурирование.

Какие лучшие инструменты и библиотеки Python для парсинга?

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

  • Scrapy: Фреймворк для парсинга, который предоставляет полный набор инструментов для парсинга и помогает структурировать данные.
  • BeautifulSoup: Используется для разбора HTML- и XML-документов. Он создает разобранное дерево для веб-страниц и позволяет извлекать данные.
  • Selenium: Инструмент для парсинга и автоматизации, поддерживающий множество браузеров, таких как Chrome, Firefox и Edge.
  • PyQuery: Библиотека Python, использующая jQuery-подобный синтаксис. Она использует ElementTree Python API, позволяя нам манипулировать и извлекать данные из HTML-документов.
  • Newspaper3k: Предназначена для поиска новостных сайтов. Он построен на основе таких библиотек, как BeautifulSoup и lxml. Он автоматически обнаруживает и извлекает новостное содержимое, а также может обрабатывать пагинацию.
  • Requests: Библиотека Python, которая позволяет нам делать HTTP-запросы для получения веб-страниц и манипулирования ими.

В этой статье мы сосредоточимся на библиотеке Requests. Итак, давайте начнем наше путешествие.

Начало работы с Python Requests

Библиотека Python Requests сделала HTTP-запросы очень простыми, потому что она очень легкая и эффективная, что делает ее отличным выбором для парсинга. Это самый скачиваемый пакет Python, и на это есть веская причина. Он отлично справляется с задачами, которые раньше были сложными и запутанными. Именно поэтому девиз библиотеки Requests — «HTTP для людей».

Как настроить Python Requests?

Давайте установим библиотеку, чтобы мы могли ее использовать. Откройте терминал или командную строку и введите следующую команду, чтобы создать новый каталог и файл Python.

mkdir pythonRequests
cd pythonRequests
touch main.py

Мы будем использовать pip3 для установки Requests:

pip3 install requests

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

pip3 show requests

Это должно вывести имя библиотеки и другую информацию. После завершения установки мы готовы к выполнению HTTP-запросов.

Вам нужно быть осторожным при установке пакетов через pip. Если вы используете Python 3 или выше, вам необходимо использовать pip3 вместе с ним. В противном случае это создаст проблемы.

Как отправлять HTTP-запросы с помощью библиотеки Requests?

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

  • GET: Метод GET позволяет нам получить информацию с веб-сайта.
  • POST: Метод POST позволяет нам отправлять информацию обратно на сервер, например, отправлять формы.
  • PUT: Метод PUT используется для обновления существующих данных.
  • DELETE: Этот метод используется для удаления данных с сервера.

Эти методы работают так же, как и разговор с сервером. В ответ на эти методы мы также получаем ответ от сервера. Этот ответ приходит с различными кодами, называемыми кодами состояния. Например, сервер возвращает 200, когда у него есть конкретная запрошенная вещь или файл; 404 означает, что у него нет ничего, связанного с запросом, и так далее.

Теперь наступает момент, когда вы делаете HTTP-запросы. Просто создайте объект Request, используя соответствующий метод для выполнения запроса. Допустим, вы просто хотите получить данные с веб-сайта; используйте для этого метод GET.

import requests  response = requests.get('https://www.lipsum.com/')  print(response.status_code)  print(response.content)

Этот код отправляет GET-запрос на сайт Lorem Ipsum и печатает код состояния и содержимое ответа.

Здесь необходимо упомянуть одну вещь: библиотека Requests — это отличный инструмент для выполнения HTTP-запросов, но она не предназначена для разбора HTML-страниц и получения информации. Если вы хотите сделать это, вам нужно использовать ее вместе с другими библиотеками, например, Beautiful Soup.

Обработка HTTP-ответов с помощью Requests

Получив ответ, вы можете применить к нему различные методы; ниже приведены некоторые из них:

  • response.status_code: Этот метод возвращает код состояния ответа.
  • response.content: Метод content используется для получения содержимого в байтах.
  • response.text: Этот метод используется для получения содержимого в виде текста Unicode.
  • response.json(): Этот метод полезен, когда ответ находится в формате JSON. Он возвращает данные в виде словаря.
  • response.headers(): Этот метод дает нам заголовки, содержащие такую информацию, как тип данных, длина и кодировка; это метаданные — информация об информации.

Reply.content и response.text извлекают данные в различных форматах. response.content полезен при работе с изображениями или pdf. response.text помогает нам извлекать данные в виде HTML.

Давайте сделаем запрос и посмотрим, будет ли он успешным.

import requests
response = requests.get("https://www.wikipedia.org")
if response.status_code == 200:
print("It's a successful Get requested")
else:
print("The server returned the Status code: ", response.status_code)

Этот код отправляет GET-запрос на веб-сайт. Он возвращает «Это успешный Get requested», если ответ успешный. В противном случае он печатает «The server returned the Status code:» с кодом состояния.

Как библиотека Requests обрабатывает различные типы данных

При извлечении данных с веб-сайтов мы можем взаимодействовать с различными типами данных. Requests специально предоставляет встроенные методы для работы с различными типами данных. Вот некоторые из них с примерами.

HTML

После выполнения запроса к веб-сайту, если сервер возвращает HTML-файл веб-страницы, вот как это можно сделать:

import requests
response = requests.get("https://www.wikipedia.org")
htmlResponse = response.text
print(htmlResponse)

Код отправляет GET-запрос на сайт Википедии и преобразует ответ в HTML.

JSON

Допустим, вы извлекаете набор данных в JSON: библиотека Requests предоставляет функцию, которая автоматически преобразует данные в словарь Python.

import requests  response=requests.get("https://jsonplaceholder.typicode.com/posts/1")  jsonResponse = response.json()  print(jsonResponse) 

Код отправляет GET-запрос на сайт jsonplaceholder и возвращает данные в виде словаря Python.

Бинарные данные

Библиотека Requests предоставляет поддержку для работы с двоичными данными или содержимым в байтах, например, изображениями или pdf-файлами. Допустим, вы хотите загрузить логотип Google:

import requests
response = requests.get("https://xmldatafeed.com/wp-content/uploads/2023/06/googlelogo_light_color_272x92dp-1.png")
googleLogo = response.content
with open("logo.png", "wb") as file:
file.write(googleLogo)

Этот код отправляет GET-запрос на указанную ссылку и возвращает ответ в байтах. Здесь используется метод open() для записи данных в режиме wb (Write Binary), который открывает файл logo.png и записывает данные в этот файл.

Метод open() открывает файл, предоставленный в качестве аргумента. Если файл отсутствует, он создает файл с тем же именем и записывает данные в него.

Как происходит разбор и извлечение HTML-данных

Как мы уже видели, библиотека Requests позволяет только получить данные сайта, но не обеспечивает поддержку разбора этих данных. Поэтому для этого нам нужна другая библиотека. В этом руководстве нам поможет Beautiful Soup. Чтобы установить Beautiful Soup в свой проект, просто введите следующую команду в командной строке и нажмите Enter.

pip3 install beautifulsoup4

Теперь вы готовы разбирать и извлекать данные с любого веб-сайта. Допустим, вам нужны все заголовки блогов с сайта Apify.

Код для этого выглядит следующим образом:

import requests
from bs4 import BeautifulSoup
response = requests.get("https://blog.apify.com/")
# Создаем объект BeautifulSoup путем разбора содержимого
soup = BeautifulSoup(response.content, "html.parser")
# Найдите все элементы с классом "post-title" и заголовком "h2"
postTitles = soup.find_all("h2", class_="post-title")
# Пройдитесь по списку всех заголовков постов
for postTitle in postTitles:
print(postTitle.text.strip())

Этот код отправляет GET-запрос на сайт Apify, разбирает HTML-содержимое с помощью Beautiful Soup и находит все заголовки блогов.

Какие проблемы возникают при парсинге с помощью Python Requests?

Каждый инструмент имеет свои функциональные возможности и ограничения. Ограничения есть и у Python Requests. Давайте рассмотрим некоторые из них.

  • Все запросы синхронны, то есть каждый запрос будет блокировать выполнение программы. Это может вызвать проблемы при выполнении большого количества запросов. Чтобы избежать этого, можно использовать библиотеки Asyncio и gevent Python. Эти библиотеки позволяют выполнять асинхронные запросы.
  • Библиотека Python Requests предназначена только для выполнения HTTP или HTTPS запросов. Она не обеспечивает поддержку протоколов, отличных от HTTTP. Для выполнения не-HTTP запросов, таких как FTP или SSH, необходимо использовать другие библиотеки Python, например ftplib или paramiko.
  • Он загружает весь ответ в память. Это может вызвать проблемы при работе с файлами большого размера. Для загрузки файлов по частям вы можете передать параметр stream или использовать другие библиотеки, например wget или urllib3.
  • Она не обрабатывает повторные запросы автоматически. Попробуйте использовать библиотеку requests-retry, которая предоставляет декоратор повторных попыток для библиотеки Requests.

Расширенные методы парсинга

Python Requests предоставляет некоторые расширенные возможности, такие как работа с cookies, аутентификация, управление сессиями и т.д. Их можно использовать, чтобы избежать блокировки и повысить эффективность парсинга.

Как работать с файлами Cookies в Python Requests?

Cookie — это небольшой фрагмент текста, отправляемый с сайта пользователю. Он хранится в браузере пользователя для запоминания информации, например, товаров в корзине и данных для входа в систему. Таким образом, в следующий раз, когда вы добавляете товар в корзину или регистрируетесь где-то и случайно закрываете окно браузера, вы откроете сайт и найдете то же состояние. Это делается с помощью файлов cookie. Они поддерживают состояние веб-сайта. Они также используются для отслеживания поведения пользователей, например, какие страницы они посещают и как долго остаются на сайте.

С помощью Python Requests мы можем получить доступ к файлам cookie и добавить их. Давайте посмотрим, как мы можем получить доступ к файлам cookie:

import requests  # отправляем GET-запрос  response = requests.get('https://stackoverflow.com/')  # Получить файлы cookie из ответа  cookies = response.cookies  print(cookies)

Этот код отправляет GET-запрос на сайт StackOverflow и получает от него файлы cookie. Теперь, допустим, мы хотим отправить cookies на сайт httpbin. Параметр cookies в запросе позволяет нам отправить cookies обратно на сервер.

import requests
# Создаем словарь cookie
cookies = {'exampleCookie': '123456789'}
response = requests.get('http://httpbin.org/cookies', cookies=cookies)
print(response.text)

Этот код отправляет Get запрос и cookies в качестве параметра. Сервер получит cookies из запроса и обработает их в соответствии со своей собственной реализацией.

Как аутентифицироваться с помощью Python Requests?

Для аутентификации веб-сайтов Requests предоставляет поддержку автоматической аутентификации. Нам просто нужно указать имена полей с правильными учетными данными, и БУМ! Requests автоматически находит форму, заполняет поля и нажимает кнопку входа. Это так просто.

Вот как это делается:

import requests  # Login credentials  credentials = {      'email': 'yourEmail',      'password': 'yourPassword'  }    response = requests.post('https://newsapi.org/login', data=credentials)    if response.status_code == 200:      homePage = response.text      print('Authentication Successful!')  else:      print('Authentication failed!') 

Этот код отправляет POST-запрос на сайт news api с учетными данными для аутентификации. Он сохраняет HTML домашней страницы в переменной homePage и печатает «Authentication Successful!», если аутентификация прошла успешно; в противном случае печатается «Authentication failed!». Вы все еще можете опубликовать свои учетные данные, используя запрос GET и включив их в строку запроса. Обычно это не рекомендуется, поскольку строка запроса может быть видна третьим лицам и может кэшироваться посредниками, такими как прокси-серверы или серверы кэширования.

Как работает управление сеансами в Requests?

Сессия может использоваться для хранения информации о пользователе на сервере в течение всего времени его взаимодействия с веб-сайтом. Вместо того, чтобы хранить изменяющуюся информацию о пользователе через cookies в браузере, сервер присваивает браузеру уникальный идентификатор и хранит некоторые временные переменные. Каждый раз, когда браузер делает запрос, сервер получает идентификатор и извлекает переменные. В контексте парсинга иногда требуется аутентификация веб-сайта и переход к различным маршрутам. Сессии используются для сохранения производительности и информации о состоянии между этими страницами.

Вот пример, в котором мы сначала войдем в систему, а затем попытаемся зайти на страницу подписки.

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

Мы также извлечем текущий план со страницы подписки.

import requests  from bs4 import BeautifulSoup  # create session object  session = requests.Session()  # Login credentials  credentials = {      'email': 'yourEmail',      'password': 'yourPassword'  }    response = session.post('https://newsapi.org/login', data=credentials)  # Show an error if the status_code is not 200  if response.status_code != 200:      print("Login failed.")  else:  	subscriptionResponse = 		session.get('https://newsapi.org/account/manage-subscription')    soup = BeautifulSoup(subscriptionResponse.content, 'html.parser')    subscriptionPlan = soup.find('div', class_ = 'mb2')    #If the subscriptionPlan is not found    if subscriptionPlan is not None:        print(subscriptionPlan.text.strip())    else:        print("Failed to find plan element.")  

Как использовать прокси-серверы в Python Requests?

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

Вот пример использования прокси с помощью Requests:

import requests    # Different proxies  proxies = {     'http': 'http://103.69.108.78:8191',     'http': 'http://198.199.86.11:8080',     'http': 'http://200.105.215.22:33630',  }    # Make four GET requests  for i in range(4):    response = requests.get('https://httpbin.org', proxies=proxies)  # Print **Request successful** if the status code is **200**    if response.status_code == 200:      print("Request successful")  # Print **Request failed** otherwise    else:      print("Request failed") 

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

Агенты-пользователи

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

import requests  headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'}  response = requests.get('https://apify.com/', headers=headers)  if response.status_code == 200:      print("Request successful")  # Print Request failed otherwise  else:    print("Request failed") 

Этот код отправляет GET-запрос на HTTP-сайт с использованием user-agents и печатает сообщение в соответствии с ответом. Генерация User-агентов Online позволяет вам также генерировать User-агенты.

Дросселирование и ограничение скорости

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

import requests
# Импортируйте библиотеку времени, чтобы добавить задержки между запросами
import time
# Сделайте 10 запросов
for i in range(10):
response = requests.get('https://blog.apify.com/')
# Добавьте 1-секундную задержку между запросами
time.sleep(1)
if response.status_code == 200:
print("Запрос успешен")
# В противном случае вывести запрос не удалось
else:
print("Запрос не прошел")

Этот код отправляет 10 GET-запросов в Apify с 1-секундной задержкой между каждым запросом.

Тестирование и отладка парсинга с помощью Requests

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

Каковы распространенные ошибки при парсинге?

Вот несколько ошибок, которые могут повлиять на наши скрипты парсинга.

  1. 400 Bad Request: Этот код состояния означает, что на стороне пользователя что-то не так, и сервер не может это понять. Например, некорректное обрамление сообщения запроса, неправильный синтаксис запроса или обманчивая маршрутизация запроса. Мы можем подтвердить правильность URL или заголовков.
  2. 401 Unauthorized: Эта ошибка возникает, когда мы пытаемся получить доступ к ресурсу, требующему определенной аутентификации. Поэтому, если мы используем какие-то учетные данные, нам нужно перепроверить их.
  3. 403 Forbidden: Эта ошибка возникает, когда сервер отказывает в доступе пользователю или скрипту, пытающемуся получить доступ к сайту. Мы будем видеть эту ошибку много раз при парсинге. Мы можем использовать пользовательские агенты, заголовки запросов или вращающиеся прокси, чтобы избежать этой ошибки.
  4. 404 Not Found: Эта ошибка возникает, когда мы пытаемся получить доступ к ресурсу, который недоступен или, возможно, был удален. Эта ошибка также возникает, когда URL неверен.
  5. 500 Internal Server Error (Внутренняя ошибка сервера): Эта ошибка возникает, когда сервер сталкивается с непредвиденным условием, которое не позволяет ему выполнить запрос.
  6. 501 Not Implemented: Эта ошибка указывает на то, что сервер не поддерживает функциональность, о которой мы просили в запросе.

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