Узнайте, как создать парсер на Python для сканирования всего сайта и извлечения данных с помощью веб-скрапинга.
Веб-скрапинг — это извлечение веб-данных. Парсер же — это инструмент, который выполняет веб-скрапинг и обычно представлен в виде скрипта. Python — один из самых простых и надежных языков сценариев. Кроме того, он поставляется с широким спектром библиотек для веб-скрапинга. Это делает Python идеальным языком программирования для парсинга веб-страниц. Ведь веб-скрапинг с Python занимает всего несколько строк кода.
В этом руководстве вы узнаете, как создать простой парсер Python. Он будет просматривать весь сайт, извлекая данные с каждой страницы. Затем сохранит их в CSV-файл. Это руководство поможет вам понять, какие библиотеки Python лучшие для парсинга данных, как их использовать. Следуйте нашему пошаговому плану и научитесь создавать скрипт Python для веб-скрапинга.
Содержание:
- Требования
- Лучшие библиотеки веб-скрапинга Python
- Создание парсера на Python
- Вывод
- Часто задаваемые вопросы
Требования
Чтобы создать парсер Python, вам необходимы:
Если на вашем компьютере не установлен Python, скачайте его по первой ссылке выше. Если у вас ОС Windows, обязательно установите флажок «Добавить python.exe в PATH» при установке Python, как показано ниже:
Так Windows автоматически распознает команды Python и pip в терминале. Отметим, что pip — это менеджер пакетов для Python. Он включен по умолчанию в Python 3.4 или более поздней версии. То есть вам не нужно устанавливать его вручную.
Теперь все готово для создания вашего первого парсера Python. Но сначала вам нужна библиотека веб-скрапинга Python!
Лучшие библиотеки веб-скрапинга Python
Вы можете создать сценарий парсинга страниц с нуля с помощью Python vanilla, но это не идеальное решение. Python имеет широкий выбор доступных библиотек. Для веб-скрапинга есть несколько на выбор. Давайте рассмотрим самые важные из них!
Requests
Библиотека Requests позволяет выполнять HTTP-запросы в Python. Она упрощает отправку HTTP-запросов, особенно по сравнению со стандартными HTTP-библиотеками Python. Requests играют ключевую роль в проекте веб-скрапинга Python, поскольку для соскабливания данных на веб-странице сначала нужно получить их с помощью HTTP-запроса GET. Кроме того, может потребоваться выполнение других HTTP-запросов к серверу целевого сайта.
Вы можете установить requests с помощью следующей команды pip:
pip install requests
Beautiful Soup
Библиотека Beautiful Soup Python упрощает сбор информации с веб-страниц. Она работает с любым парсером HTML или XML и предоставляет все необходимое для итерации, поиска и изменения дерева синтаксического анализа. Обратите внимание, что Beautiful Soup можно использовать с html.parser – парсером, который входит в стандартную библиотеку Python и позволяет анализировать текстовые файлы HTML. Вы можете использовать Beautiful Soup для обхода DOM и извлечения из него необходимых данных.
Вы можете установить Beautiful Soup с помощью pip следующим образом:
pip install beautifulsoup4
Selenium
Selenium — это усовершенствованная система автоматизированного тестирования с открытым исходным кодом, которая позволяет выполнять операции на веб-странице в браузере. Другими словами, вы можете использовать Selenium, чтобы заставить браузер выполнять определенные задачи. А также использовать в качестве библиотеки веб-скрапинга благодаря возможностям безголового браузера. Это веб-браузер, который работает без GUI (графического пользовательского интерфейса).
Таким образом, веб-страницы, посещаемые в Selenium, будут отображаться в реальном браузере, способном запускать JavaScript. В результате Selenium позволит парсить сайты, зависящие от JavaScript. Учитывайте, что вы не можете добиться этого с помощью requests или любого другого HTTP-клиента, потому что вам нужен браузер для запуска JavaScript, тогда как requests просто позволяют выполнять HTTP-запросы.
Selenium предоставляет все необходимое для создания парсера без потребности в других библиотеках. Вы можете установить его с помощью следующей команды pip:
pip install selenium
Создание парсера на Python
Теперь давайте узнаем, как создать парсер на Python. Цель этого руководства — научиться извлекать все данные о цитатах на сайте Quotes to Scrape. Вы научитесь извлекать текст, автора и список тегов для каждой цитаты.
Но сначала давайте взглянем на целевой сайт. Вот как выглядит веб-страница Quotes to Scrape:
Как видите, Quotes to Scrape — это не что иное, как песочница для парсинга веб-страниц. Сайт содержит разбитый на страницы список цитат. Парсер Python, который вы собираетесь создать, извлечет все цитаты на каждой странице, и предоставит их в виде данных CSV.
Теперь пришло время понять, какие библиотеки Python для парсинга лучше всего подходят для достижения этой цели. Как вы можете увидеть на картинке ниже на вкладке Network окна Chrome DevTools целевой сайт не выполняет запросов Fetch/XHR.
Другими словами, Quotes to Scrape не использует JavaScript для извлечения данных на веб-страницах. Это обычная ситуация для большинства сайтов, отображаемых на сервере. Поскольку целевой сайт не использует JavaScript для отображения страницы или извлечения данных, вам не нужен Selenium для парсинга. Вы можете использовать его, но это не обязательно.
Как вы уже узнали, Selenium открывает страницы в браузере. Поскольку это занимает время и ресурсы, Selenium вызывает расходы на производительность. Вы можете избежать этого, используя Beautiful Soup вместе с Requests. Теперь давайте узнаем, как создать простой скрипт парсинга веб-страниц на Python для извлечения данных с сайта с помощью Beautiful Soup.
Приступим
Прежде чем написать первые строки кода, вам необходимо настроить проект парсинга на Python. Технически необходим только один файл .py. Однако использование расширенной IDE (интегрированной среды разработки) упростит процесс написания кода. Здесь вы узнаете, как настроить проект Python в PyCharm 2022.2.3, но подойдет и любая другая IDE.
Откройте PyCharm и выберите «Файл > Новый проект…». Во всплывающем окне «Новый проект» выберите «Pure Python» и создайте свой проект.
Например, вы можете назвать свой проект python-web-scraper. Нажмите «Создать», и теперь у вас будет доступ к вашему пустому проекту Python. По умолчанию PyCharm инициализирует файл main.py. Вы можете переименовать его в scraper.py. Вот как теперь будет выглядеть ваш проект:
Как видите, PyCharm автоматически инициализирует для вас файл Python. Не обращайте внимания на его содержимое и удаляйте каждую строку кода, чтобы начать с нуля.
Теперь пришло время установить зависимости проекта. Вы можете установить Requests и Beautiful Soup, запустив в терминале следующую команду:
pip install requests beautifulsoup4
Эта команда установит обе библиотеки одновременно. Дождитесь завершения установки. Теперь вы готовы использовать Beautiful Soup и Requests для создания поискового робота и парсера на Python. Обязательно импортируйте две библиотеки, добавив следующие строки в начало файла скрипта scraper.py:
import requests
from bs4 import BeautifulSoup
PyCharm подсветит эти две строки серым цветом, потому что библиотеки не используются в коде. Если он подчеркнет их красным цветом, значит, что-то пошло не так в процессе установки. В этом случае попробуйте установить их снова.
Вот как теперь должен выглядеть ваш файл scraper.py. Теперь вы можете приступить к определению логики парсинга веб-страниц.
Подключение к целевому URL для сканирования
Первое, что нужно сделать в парсере, — это подключиться к целевому сайту. Сначала получите полный URL-адрес страницы из браузера. Обязательно скопируйте также раздел протокола http:// или https:// HTTP. Вот как выглядит полный URL-адрес целевого сайта:
https://quotes.toscrape.com
Теперь можете использовать запросы для загрузки страницы со следующей строкой кода:
page = requests.get('https://quotes.toscrape.com')
Эта строка просто присваивает результат метода request.get() переменной page. За сценой request.get() выполняет запрос GET, используя URL-адрес, переданный в качестве параметра. Затем он возвращает объект Response, содержащий ответ сервера на HTTP-запрос.
Если HTTP-запрос выполнен успешно, код page.status_ будет содержать 200. HTTP 200 OK – код ответа состояния, который указывает на то, что HTTP-запрос был выполнен успешно. Код состояния HTTP 4xx или 5xx будет означать ошибку. Это может произойти по нескольким причинам. Учитывайте, что многие сайты блокируют запросы без допустимого заголовка User-Agent. Это строка, которая характеризует приложение и версию операционной системы, откуда пришел запрос. Узнайте больше о User-Agent для веб-скрапинга.
Вы можете установить заголовок User-Agent в запросах следующим образом:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
}
page = requests.get('https://quotes.toscrape.com', headers=headers)
теперь запросы будут выполнять HTTP-запрос, если заголовки будут переданы в качестве параметра.
На что следует обратить внимание, так это на свойство page.text. Оно будет содержать HTML-документ, возвращенный сервером в строковом формате. Передайте свойство text в Beautiful Soup, чтобы извлечь данные из веб-страницы. Давайте узнаем, как это сделать.
Извлечение данных с помощью парсера Python
Чтобы извлечь данные с веб-страницы, сначала нужно определить элементы HTML, которые содержат нужные вам данные. В частности, необходимо найти селекторы CSS для извлечения этих элементов из DOM. Подойдут инструменты разработки от вашего браузера. В Chrome щелкните правой кнопкой мыши на интересующем вас элементе HTML и выберите Inspect (Проверить).
Как видите, HTML-элемент цитаты <div> идентифицируется классом цитаты (quote). Он содержит:
- Текст цитаты в HTML-элементе <span>
- Автор цитаты в HTML-элементе <small>
- Список тегов в элементе <div>, каждый из которых содержится в HTML-элементе <a>.
В частности, вы можете извлечь эти данные, используя следующие селекторы CSS в .quote:
.text
.author
.tags .tag
Давайте теперь узнаем, как добиться этого с помощью Beautiful Soup в Python. Во-первых, давайте передадим HTML-документ page.text конструктору BeautifulSoup():
soup = BeautifulSoup(page.text, 'html.parser')
Второй параметр указывает синтаксический анализатор, который Beautiful Soup будет использовать для анализа HTML-документа. Переменная soup теперь содержит объект BeautifulSoup. Это дерево синтаксического анализа, в результате разбора HTML-документа в page.text, с помощью встроенного в Python html.parser.
Теперь инициализируйте переменную, которая будет содержать список всех отсканированных данных.
quotes = []
Пришло время использовать soup для извлечения элементов из DOM:
quote_elements = soup.find_all('div', class_='quote')
Метод find_all() вернет список всех HTML-элементов <div>, идентифицированных классом цитаты (quote). Другими словами, эта строка кода эквивалентна применению CSS-селектора .quote для получения списка HTML-элементов цитаты на странице. Затем можно выполнить итерации по списку цитат для получения данных о цитатах, как показано ниже:
for quote_element in quote_elements:
# extracting the text of the quote
text = quote_element.find('span', class_='text').text
# extracting the author of the quote
author = quote_element.find('small', class_='author').text
# extracting the tag <a> HTML elements related to the quote
tag_elements = quote_element.find('div', class_='tags').find_all('a', class_='tag')
# storing the list of tag strings in a list
tags = []
for tag_element in tag_elements:
tags.append(tag_element.text)
Благодаря методу find() из Beautiful Soup вы можете извлечь один интересующий элемент HTML. Поскольку тегов, связанных с цитатой, больше одного, их следует хранить в списке.
Затем вы можете преобразовать эти данные в словарь и добавить их в список следующим образом:
quotes.append(
{
'text': text,
'author': author,
'tags': ', '.join(tags) # merging the tags into a "A, B, ..., Z" string
}
)
Хранение извлеченных данных в таком формате словаря облегчит доступ к вашим данным для их понимания.
Вы только что узнали, как извлечь все данные о цитатах с одной страницы. Но имейте в виду, что целевой сайт состоит из нескольких страниц. Давайте научимся сканировать весь сайт.
Реализация логики сканирования
Внизу главной страницы вы можете найти HTML-элемент «Далее →» <a>, который перенаправляет на следующую страницу целевого сайта. Этот элемент HTML содержится на всех страницах, кроме последней. Такой сценарий распространен на любом сайте с разбивкой на страницы.
Перейдя по ссылке в HTML-элементе «Далее →» <a>, вы можете легко перемещаться по всему сайту. Итак, начнем с главной и посмотрим, как пройти каждую страницу, из которой состоит целевой сайт. Вам нужно найти HTML-элемент .next <li> и извлечь относительную ссылку на следующую страницу.
Вы можете реализовать логику сканирования так:
# the url of the home page of the target website
base_url = 'https://quotes.toscrape.com'
# retrieving the page and initializing soup...
# getting the "Next →" HTML element
next_li_element = soup.find('li', class_='next')
# if there is a next page to scrape
while next_li_element is not None:
next_page_relative_url = next_li_element.find('a', href=True)['href']
# getting the new page
page = requests.get(base_url + next_page_relative_url, headers=headers)
# parsing the new page
soup = BeautifulSoup(page.text, 'html.parser')
# scraping logic...
# looking for the "Next →" HTML element in the new page
next_li_element = soup.find('li', class_='next')
Этот цикл выполняет итерации по каждой странице до тех пор, пока не останется следующая страница. В частности, он извлекает относительный URL следующей страницы и использует его для создания URL следующей страницы для сканирования. Затем загружается следующая страница, он сканирует ее и повторяет логику.
Вы только что узнали, как реализовать логику сканирования для парсинга всего сайта. Пришло время посмотреть, как преобразовать извлеченные данные в более удобный формат.
Преобразование данных в формат CSV
Рассмотрим, как преобразовать список словарей, содержащих отсканированные данные цитаты, в файл CSV. Сделать это можно с помощью следующих строк:
import csv
# scraping logic...
# reading the "quotes.csv" file and creating it
# if not present
csv_file = open('quotes.csv', 'w', encoding='utf-8', newline='')
# initializing the writer object to insert data
# in the CSV file
writer = csv.writer(csv_file)
# writing the header of the CSV file
writer.writerow(['Text', 'Author', 'Tags'])
# writing each row of the CSV
for quote in quotes:
writer.writerow(quote.values())
# terminating the operation and releasing the resources
csv_file.close()
Этот фрагмент кода записывает данные цитаты, содержащиеся в списке словарей, в файл quotes.csv. Обратите внимание, что csv является частью стандартной библиотеки Python. Таким образом, вы можете импортировать и использовать его без дополнительной зависимости. Вам просто нужно создать файл с помощью open(). Затем вы можете заполнить его функцией writerow() из объекта Writer библиотеки csv. Это позволит записать каждый словарь цитат как строку в CSV-формате в CSV-файл.
Вы перешли от необработанных данных сайта к структурированным данным в файле CSV. Процесс извлечения завершен, и теперь вы можете посмотреть на весь парсер Python.
Собираем все вместе
Вот как выглядит полный скрипт парсинга веб-страниц на Python:
import requests
from bs4 import BeautifulSoup
import csv
def scrape_page(soup, quotes):
# retrieving all the quote <div> HTML element on the page
quote_elements = soup.find_all('div', class_='quote')
# iterating over the list of quote elements
# to extract the data of interest and store it
# in quotes
for quote_element in quote_elements:
# extracting the text of the quote
text = quote_element.find('span', class_='text').text
# extracting the author of the quote
author = quote_element.find('small', class_='author').text
# extracting the tag <a> HTML elements related to the quote
tag_elements = quote_element.find('div', class_='tags').find_all('a', class_='tag')
# storing the list of tag strings in a list
tags = []
for tag_element in tag_elements:
tags.append(tag_element.text)
# appending a dictionary containing the quote data
# in a new format in the quote list
quotes.append(
{
'text': text,
'author': author,
'tags': ', '.join(tags) # merging the tags into a "A, B, ..., Z" string
}
)
# the url of the home page of the target website
base_url = 'https://quotes.toscrape.com'
# defining the User-Agent header to use in the GET request below
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
}
# retrieving the target web page
page = requests.get(base_url, headers=headers)
# parsing the target web page with Beautiful Soup
soup = BeautifulSoup(page.text, 'html.parser')
# initializing the variable that will contain
# the list of all quote data
quotes = []
# scraping the home page
scrape_page(soup, quotes)
# getting the "Next →" HTML element
next_li_element = soup.find('li', class_='next')
# if there is a next page to scrape
while next_li_element is not None:
next_page_relative_url = next_li_element.find('a', href=True)['href']
# getting the new page
page = requests.get(base_url + next_page_relative_url, headers=headers)
# parsing the new page
soup = BeautifulSoup(page.text, 'html.parser')
# scraping the new page
scrape_page(soup, quotes)
# looking for the "Next →" HTML element in the new page
next_li_element = soup.find('li', class_='next')
# reading the "quotes.csv" file and creating it
# if not present
csv_file = open('quotes.csv', 'w', encoding='utf-8', newline='')
# initializing the writer object to insert data
# in the CSV file
writer = csv.writer(csv_file)
# writing the header of the CSV file
writer.writerow(['Text', 'Author', 'Tags'])
# writing each row of the CSV
for quote in quotes:
writer.writerow(quote.values())
# terminating the operation and releasing the resources
csv_file.close()
Как видите, вы можете создать парсер веб-страниц менее чем из 100 строк кода. Этот скрипт Python позволяет сканировать весь сайт, автоматически извлекать его данные и преобразовывать в файл CSV.
Поздравляем! Теперь вы знаете, как создать парсер Python с помощью библиотек Requests и Beautiful Soup!
Запуск скрипта веб-скрапинга Python
Если вы являетесь пользователем PyCharm, запустите скрипт, нажав кнопку ниже:
Или запустите следующую команду Python в терминале внутри каталога проекта:
python scraper.py
Подождите, пока процесс завершится, и теперь у вас будет доступ к файлу quotes.csv. Откройте его. Он должен содержать следующие данные:
Вуаля! Теперь у вас есть все 100 цитат с целевого сайта в одном CSV-файле!
Вывод
Из этого руководства вы узнали, что такое парсинг веб-страниц, что вам нужно для начала работы с Python и какие библиотеки Python являются лучшими для парсинга. Также вы увидели, как использовать Beautiful Soup и Requests для создания парсера на реальном примере и убедились, что, парсинг на Python занимает всего несколько строк кода.
Тем не менее парсинг веб-страниц сопряжен с рядом проблем. В частности, все большую популярность приобретают анти-боты и анти-скрапинговые технологии. Поэтому вам нужен продвинутый автоматизированный инструмент для веб-скрапинга от Bright Data.
Чтобы избежать блокировки, мы также рекомендуем выбрать прокси-сервер в зависимости от вашего сценария использования из различных прокси-сервисов, которые предоставляет Bright Data.