Разбор содержимого HTML с помощью BeautifulSoup
При работе с веб-данными вы часто будете сталкиваться с ответами HTML. Для разбора HTML библиотека BeautifulSoup в Python — отличный инструмент. На этом шаге мы узнаем, как извлекать информацию из ответов HTML.
Установка BeautifulSoup
Сначала установим BeautifulSoup и его HTML-парсер:
pip install beautifulsoup4
Базовый разбор HTML
Давайте создадим файл с именем parse_html.py для получения и разбора веб-страницы:
import requests
from bs4 import BeautifulSoup
## Make a request to a webpage
url = "https://www.example.com"
response = requests.get(url)
## Check if the request was successful
if response.status_code == 200:
## Parse the HTML content
soup = BeautifulSoup(response.text, 'html.parser')
## Extract the page title
title = soup.title.text
print(f"Page title: {title}")
## Extract all paragraphs
paragraphs = soup.find_all('p')
print(f"\nNumber of paragraphs: {len(paragraphs)}")
## Print the text of the first paragraph
if paragraphs:
print(f"\nFirst paragraph text: {paragraphs[0].text.strip()}")
## Extract all links
links = soup.find_all('a')
print(f"\nNumber of links: {len(links)}")
## Print the href attribute of the first link
if links:
print(f"First link href: {links[0].get('href')}")
else:
print(f"Request failed with status code: {response.status_code}")
Запустите этот скрипт, чтобы увидеть, как извлечь основную информацию из HTML-страницы:
python parse_html.py
Вы должны увидеть вывод, показывающий заголовок страницы, количество абзацев, текст первого абзаца, количество ссылок и URL-адрес первой ссылки.
Поиск конкретных элементов
Теперь давайте посмотрим, как найти конкретные элементы с помощью CSS-селекторов. Создайте файл с именем html_selectors.py:
import requests
from bs4 import BeautifulSoup
## Make a request to a webpage with more complex structure
url = "https://quotes.toscrape.com/"
response = requests.get(url)
## Check if the request was successful
if response.status_code == 200:
## Parse the HTML content
soup = BeautifulSoup(response.text, 'html.parser')
## Find all quote elements
quote_elements = soup.select('.quote')
print(f"Number of quotes found: {len(quote_elements)}")
## Process the first 3 quotes
print("\nFirst 3 quotes:")
for i, quote_element in enumerate(quote_elements[:3], 1):
## Extract the quote text
text = quote_element.select_one('.text').text
## Extract the author
author = quote_element.select_one('.author').text
## Extract the tags
tags = [tag.text for tag in quote_element.select('.tag')]
## Print the information
print(f"\nQuote #{i}")
print(f"Text: {text}")
print(f"Author: {author}")
print(f"Tags: {', '.join(tags)}")
else:
print(f"Request failed with status code: {response.status_code}")
Запустите этот скрипт, чтобы увидеть, как использовать CSS-селекторы для извлечения конкретных элементов:
python html_selectors.py
Вы должны увидеть вывод, показывающий информацию о первых трех цитатах, включая текст цитаты, автора и теги.
Создание простого веб-скребка
Давайте объединим все вместе, чтобы создать простой веб-скребок, который извлекает структурированные данные с веб-страницы. Создайте файл с именем quotes_scraper.py:
import requests
from bs4 import BeautifulSoup
import json
import os
def scrape_quotes_page(url):
## Make a request to the webpage
response = requests.get(url)
## Check if the request was successful
if response.status_code != 200:
print(f"Request failed with status code: {response.status_code}")
return None
## Parse the HTML content
soup = BeautifulSoup(response.text, 'html.parser')
## Extract all quotes
quotes = []
for quote_element in soup.select('.quote'):
## Extract the quote text
text = quote_element.select_one('.text').text.strip('"')
## Extract the author
author = quote_element.select_one('.author').text
## Extract the tags
tags = [tag.text for tag in quote_element.select('.tag')]
## Add the quote to our list
quotes.append({
'text': text,
'author': author,
'tags': tags
})
## Check if there's a next page
next_page = soup.select_one('.next a')
next_page_url = None
if next_page:
next_page_url = 'https://quotes.toscrape.com' + next_page['href']
return {
'quotes': quotes,
'next_page': next_page_url
}
## Scrape the first page
result = scrape_quotes_page('https://quotes.toscrape.com/')
if result:
## Print information about the quotes found
quotes = result['quotes']
print(f"Found {len(quotes)} quotes on the first page")
## Print the first 2 quotes
print("\nFirst 2 quotes:")
for i, quote in enumerate(quotes[:2], 1):
print(f"\nQuote #{i}")
print(f"Text: {quote['text']}")
print(f"Author: {quote['author']}")
print(f"Tags: {', '.join(quote['tags'])}")
## Save the quotes to a JSON file
output_dir = '/home/labex/project'
with open(os.path.join(output_dir, 'quotes.json'), 'w') as f:
json.dump(quotes, f, indent=2)
print(f"\nSaved {len(quotes)} quotes to {output_dir}/quotes.json")
## Print information about the next page
if result['next_page']:
print(f"\nNext page URL: {result['next_page']}")
else:
print("\nNo next page available")
Запустите этот скрипт, чтобы извлечь цитаты с веб-сайта:
python quotes_scraper.py
Вы должны увидеть вывод, показывающий информацию о цитатах, найденных на первой странице, и цитаты будут сохранены в файл JSON с именем quotes.json.
Проверьте файл JSON, чтобы увидеть структурированные данные:
cat quotes.json
Файл должен содержать массив JSON-объектов цитат, каждый из которых имеет свойства text, author и tags.