Хочешь уверенно проходить IT-интервью?
![Готовься к IT-собеседованиям уверенно с AI-тренажёром T1!](https://media.proglib.io/banner/2025/01/28/t1.jpg)
Мы понимаем, как сложно подготовиться: стресс, алгоритмы, вопросы, от которых голова идёт кругом. Но с AI тренажёром всё гораздо проще.
💡 Почему Т1 тренажёр — это мастхэв?
- Получишь настоящую обратную связь: где затык, что подтянуть и как стать лучше
- Научишься не только решать задачи, но и объяснять своё решение так, чтобы интервьюер сказал: "Вау!".
- Освоишь все этапы собеседования, от вопросов по алгоритмам до диалога о твоих целях.
Зачем листать миллион туториалов? Просто зайди в Т1 тренажёр, потренируйся и уверенно удиви интервьюеров. Мы не обещаем лёгкой прогулки, но обещаем, что будешь готов!
Реклама. ООО «Смарт Гико», ИНН 7743264341. Erid 2VtzqwP8vqy
Веб-скрапинг – это процесс автоматического сбора информации из онлайн-источников. Для выбора нужных сведений из массива «сырых» данных, полученных в ходе скрапинга, нужна дальнейшая обработка – парсинг. В процессе парсинга выполняются синтаксический анализ, разбор и очистка данных. Результат парсинга – очищенные, упорядоченные, структурированные данные, представленные в формате, понятном конечному пользователю (или приложению).
Скрипты для скрапинга создают определенную нагрузку на сайт, с которого они собирают данные – могут, например, посылать чрезмерное количество GET запросов к серверу. Это одна из причин, по которой скрапинг относится к спорным видам деятельности. Чтобы не выходить за рамки сетевого этикета, необходимо всегда соблюдать главные правила сбора публичной информации:
- Если на сайте есть API, нужно запрашивать данные у него.
- Частота и количество GET запросов должны быть разумными.
- Следует передавать информацию о клиенте в
User-Agent
. - Если на сайте есть личные данные пользователей, необходимо учитывать настройки приватности в robots.txt.
Необходимо отметить, что универсальных рецептов скрапинга и парсинга не существует. Это связано со следующими причинами:
- Некоторые сервисы активно блокируют скраперов. Динамическая смена прокси не всегда помогает решить эту проблему.
- Контент многих современных сайтов генерируется динамически – результат обычного GET запроса из приложения к таким сайтам вернется практически пустым. Эта проблема решается с помощью Selenium WebDriver либо MechanicalSoup, которые имитируют действия браузера и пользователя.
Для извлечения данных со страниц с четкой, стандартной структурой эффективнее использовать язык запросов XPath. И напротив, для получения нужной информации с нестандартных страниц с произвольным синтаксисом лучше использовать средства библиотеки BeautifulSoup. Ниже мы подробно рассмотрим оба подхода.
Примеры скрапинга и парсинга на Python
Экосистема Python располагает множеством инструментов для скрапинга и парсинга. Начнем с самого простого примера – получения веб-страницы и извлечения из ее кода ссылки.
Скрапинг содержимого страницы
Воспользуемся модулем urllib.request стандартной библиотеки urllib для получения исходного кода одностраничного сайта example.com:
from urllib.request import urlopen
url = 'http://example.com'
page = urlopen(url)
print(page.read().decode('utf-8'))
Результат:
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
Точно такой же результат можно получить с помощью requests:
from bs4 import BeautifulSoup
import requests
url = 'http://example.com'
res = requests.get(url)
soup = BeautifulSoup(res.text,'html.parser')
print(soup)
Этот результат – те самые сырые данные, которые нужно обработать (подвергнуть парсингу), чтобы извлечь из них нужную информацию, например, адрес указанной на странице ссылки:
![🐍 Самоучитель по Python для начинающих. Часть 17: Основы скрапинга и парсинга](https://media.proglib.io/posts/2023/03/08/2dc719b7def5c3da29774b3b072fbb11.png)
Парсинг полученных данных
Извлечь адрес ссылки можно 4 разными способами – с помощью:
- Методов строк.
- Регулярного выражения.
- Запроса XPath.
- Обработки BeautifulSoup.
Рассмотрим все эти способы по порядку.
Методы строк
Это самый трудоемкий способ – для извлечения каждого элемента нужно определить 2 индекса – начало и конец вхождения. При этом к индексу вхождения надо добавить длину стартового фрагмента:
from urllib.request import urlopen
url = 'http://example.com/'
page = urlopen(url)
html_code = page.read().decode('utf-8')
start = html_code.find('href="') + 6
end = html_code.find('">More')
link = html_code[start:end]
print(link)
Результат:
https://www.iana.org/domains/example
Регулярное выражение
В предыдущей главе мы подробно рассматривали способы извлечения конкретных подстрок из текста. Точно так же регулярные выражения можно использовать для поиска данных в исходном коде страниц:
from urllib.request import urlopen
import re
url = 'http://example.com/'
page = urlopen(url)
html_code = page.read().decode('utf-8')
link = r'(https?://\S+)(?=")'
print(re.findall(link, html_code))
Результат:
https://www.iana.org/domains/example
Запрос XPath
Язык запросов XPath (XML Path Language) позволяет извлекать данные из определенных узлов XML-документа. Для работы с HTML кодом в Python используют модуль etree:
from urllib.request import urlopen
from lxml import etree
url = 'http://example.com/'
page = urlopen(url)
html_code = page.read().decode('utf-8')
tree = etree.HTML(html_code)
print(tree.xpath("/html/body/div/p[2]/a/@href")[0])
Результат:
https://www.iana.org/domains/example
Чтобы узнать путь к нужному элементу страницы, в браузерах Chrome и FireFox надо кликнуть правой кнопкой по элементу и выбрать «Просмотреть код», после чего откроется консоль. В консоли по интересующему элементу нужно еще раз кликнуть правой кнопкой, выбрать «Копировать», а затем – копировать путь XPath:
![Путь XPath](https://media.proglib.io/posts/2023/03/08/1c7d748f356f2bc01980724eb8a754c1.png)
В приведенном выше примере для извлечения ссылки к пути
/html/body/div/p[2]/a/
мы добавили указание для получения значения ссылки @href
,
и индекс [0]
, поскольку результат возвращается в виде списка. Если @href
заменить на text()
, программа вернет текст ссылки, а не сам URL:
print(tree.xpath("/html/body/div/p[2]/a/text()")[0])
Результат:
More information...
Парсер BeautifulSoup
Регулярные выражения и XPath предоставляют огромные возможности для извлечения нужной информации из кода страниц, но у них есть свои недостатки: составлять Regex-шаблоны сложно, а запросы XPath хорошо работают только на страницах с безупречной, стандартной структурой. К примеру, страницы Википедии не отличаются идеальной структурой, и использование XPath для извлечения нужной информации из определенных элементов статей, таких как таблицы infobox, часто оказывается неэффективным. В этом случае оптимальным вариантом становится BeautifulSoup, специально разработанный для парсинга HTML-кода.
Библиотека BeautifulSoup не входит в стандартный набор Python, ее нужно установить самостоятельно:
pip install beautifulsoup4
В приведенном ниже примере мы будем извлекать из исходного кода страницы уникальные ссылки, за исключением внутренних:
from bs4 import BeautifulSoup
from urllib.request import urlopen
url = 'https://webscraper.io/test-sites/e-commerce/allinone/phones'
page = urlopen(url)
html = page.read().decode('utf-8')
soup = BeautifulSoup(html, 'html.parser')
links = set()
for link in soup.find_all('a'):
l = link.get('href')
if l != None and l.startswith('https'):
links.add(l)
for link in links:
print(link)
Результат:
https://twitter.com/webscraperio
https://www.facebook.com/webscraperio/
https://forum.webscraper.io/
https://webscraper.io/downloads/Web_Scraper_Media_Kit.zip
https://cloud.webscraper.io/
https://chrome.google.com/webstore/detail/web-scraper/jnhgnonknehpejjnehehllkliplmbmhn?hl=en
При использовании XPath точно такой же результат даст следующий скрипт:
from urllib.request import urlopen
from lxml import etree
url = 'https://webscraper.io/test-sites/e-commerce/allinone/phones'
page = urlopen(url)
html_code = page.read().decode('utf-8')
tree = etree.HTML(html_code)
sp = tree.xpath("//li/a/@href")
links = set()
for link in sp:
if link.startswith('http'):
links.add(link)
for link in links:
print(link)
Имитация действий пользователя в браузере
При скрапинге сайтов очень часто требуется авторизация, нажатие кнопок «Читать дальше», переход по ссылкам, отправка форм, прокручивание ленты и так далее. Отсюда возникает необходимость имитации действий пользователя. Как правило, для этих целей используют Selenium, однако есть и более легкое решение – библиотека MechanicalSoup:
pip install MechanicalSoup
По сути, MechanicalSoup исполняет роль браузера без графического интерфейса. Помимо имитации нужного взаимодействия с элементами страниц, MechanicalSoup также парсит HTML-код, используя для этого все функции BeautifulSoup.
Воспользуемся тестовым сайтом http://httpbin.org/, на котором есть возможность отправки формы заказа пиццы:
import mechanicalsoup
browser = mechanicalsoup.StatefulBrowser()
browser.open("http://httpbin.org/")
browser.follow_link("forms")
browser.select_form('form[action="/post"]')
print(browser.form.print_summary())
В приведенном выше примере браузер MechanicalSoup перешел по внутренней ссылке http://httpbin.org/forms/post и вернул описание полей ввода:
<input name="custname"/>
<input name="custtel" type="tel"/>
<input name="custemail" type="email"/>
<input name="size" type="radio" value="small"/>
<input name="size" type="radio" value="medium"/>
<input name="size" type="radio" value="large"/>
<input name="topping" type="checkbox" value="bacon"/>
<input name="topping" type="checkbox" value="cheese"/>
<input name="topping" type="checkbox" value="onion"/>
<input name="topping" type="checkbox" value="mushroom"/>
<input max="21:00" min="11:00" name="delivery" step="900" type="time"/>
<textarea name="comments"></textarea>
<button>Submit order</button>
Перейдем к имитации заполнения формы:
browser["custname"] = "Best Customer"
browser["custtel"] = "+7 916 123 45 67"
browser["custemail"] = "trex@example.com"
browser["size"] = "large"
browser["topping"] = ("cheese", "mushroom")
browser["comments"] = "Add more cheese, plz. More than the last time!"
Теперь форму можно отправить:
response = browser.submit_selected()
Результат можно вывести с помощью print(response.text)
:
{
"args": {},
"data": "",
"files": {},
"form": {
"comments": "Add more cheese, plz. More than the last time!",
"custemail": "trex@example.com",
"custname": "Best Customer",
"custtel": "+7 916 123 45 67",
"delivery": "",
"size": "large",
"topping": [
"cheese",
"mushroom"
]
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "191",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"Referer": "http://httpbin.org/forms/post",
"User-Agent": "python-requests/2.28.1 (MechanicalSoup/1.2.0)",
"X-Amzn-Trace-Id": "Root=1-6404d82d-2a9ae95225dddaec1968ccb8"
},
"json": null,
"origin": "86.55.39.89",
"url": "http://httpbin.org/post"
}
Скрапинг и парсинг динамического контента
Все примеры, которые мы рассмотрели выше, отлично работают на статических страницах. Однако на множестве платформ используется динамический подход к генерации и загрузке контента – к примеру, для просмотра всех доступных товаров в онлайн-магазине страницу нужно не только открыть, но и прокрутить до футера. Для работы с динамическим контентом в Python нужно установить:
- Модуль Selenium.
- Драйвер Selenium WebDriver для браузера.
Если установка прошла успешно, выполнение этого кода приведет к автоматическому открытию страницы:
from selenium import webdriver
driver = webdriver.Chrome() # или webdriver.Firefox()
driver.get('https://google.com')
Бывает, что даже после установки оптимальной версии драйвера
интерпретатор Python возвращает ошибку OSError: [WinError 216] Версия
"%1" не совместима с версией Windows
. В этом случае нужно
воспользоваться модулем webdriver-manager, который самостоятельно
установит подходящий драйвер для нужного браузера:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
Имитация прокрутки страницы и парсинг данных
В качестве примера скрапинга и парсинга динамического сайта мы воспользуемся разделом тестового онлайн-магазина. Здесь расположены карточки с информацией о планшетах. Карточки загружаются ряд за рядом при прокрутке страницы:
![🐍 Самоучитель по Python для начинающих. Часть 17: Основы скрапинга и парсинга](https://media.proglib.io/posts/2023/03/08/8e0d31d35196e077f9c9470abf03bffd.png)
Пока страница не прокручена, полный HTML-код с информацией о планшетах
получить невозможно. Для имитации прокрутки мы воспользуемся скриптом 'window.scrollTo(0,
document.body.scrollHeight);'
. Цены планшетов находятся в тегах h4 класса pull-right price, а
названия моделей – в тексте ссылок a класса title. Готовый код
выглядит так:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time
from bs4 import BeautifulSoup
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager(cache_valid_range=10).install()))
url = 'https://webscraper.io/test-sites/e-commerce/scroll/computers/tablets'
driver.get(url)
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
time.sleep(5)
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
prices = soup.find_all('h4', class_='pull-right price')
models = soup.find_all('a', class_='title')
for model, price in zip(models, prices):
m = model.get_text()
p = price.get_text()
print(f'Планшет {m}, цена - {p}')
Результат:
Планшет Lenovo IdeaTab, цена - $69.99
Планшет IdeaTab A3500L, цена - $88.99
Планшет Acer Iconia, цена - $96.99
Планшет Galaxy Tab 3, цена - $97.99
Планшет Iconia B1-730HD, цена - $99.99
Планшет Memo Pad HD 7, цена - $101.99
Практика
Задание 1
Напишите программу для получения названий последних статей из блога издательства O’Reilly:
![🐍 Самоучитель по Python для начинающих. Часть 17: Основы скрапинга и парсинга](https://media.proglib.io/posts/2023/03/08/08ef7215beea0ef24bd762f79008074b.png)
Пример результата:
Sydney and the Bard
What Does Copyright Say about Generative Models?
Technology Trends for 2023
Radar Trends to Watch: February 2023
Решение:
from bs4 import BeautifulSoup
import requests
url = 'https://www.oreilly.com/radar/'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"}
res = requests.get(url, headers=headers)
soup = BeautifulSoup(res.text,'html.parser')
sp = soup.find_all('h2', class_='post-title')
for post in sp:
print(post.get_text())
Задание 2
Напишите программу для определения 10 слов, которые чаще всего встречаются в тексте сказки «Колобок» (без учета регистра). Предлоги учитывать не нужно.
Ожидаемый результат:
колобок - 32
ушел - 14
тебя - 7
коробу - 6
сусеку - 6
сметане - 5
масле - 5
покатился - 4
катится - 4
навстречу - 4
Решение:
from bs4 import BeautifulSoup
import requests
import re
url = 'https://azku.ru/russkie-narodnie-skazki/kolobok.html'
res = requests.get(url)
soup = BeautifulSoup(res.text,'html.parser')
res = soup.find_all('div', class_='entry-content')
text = res[0].get_text().split('Мне нравится')[0]
sp = re.sub(r'[-,.?!"—:]', ' ', text).lower().split()
result_dict = {word: sp.count(word) for word in sp if len(word) > 3}
max_values = sorted(result_dict.items(), key=lambda x:x[1], reverse=True)[:10]
for word, number in max_values:
print(f'{word} - {number}')
Задание 3
Напишите программу, которая на основе данных таблицы создает список цитат из фильмов, выпущенных после 1995 года.
Ожидаемый результат:
Show me the money! Покажи мне деньги! Род Тидвелл Кьюба Гудинг мл. Джерри Магуайер 1996
I see dead people. Я вижу мёртвых людей. Коул Сиэр Хэйли Джоэл Осмент Шестое чувство 1999
You had me at 'hello'. Я была твоя уже на «здрасьте». Дороти Бойд Рене Зеллвегер Джерри Магуайер 1996
My precious. Моя прелесть. Голлум Энди Серкис Властелин колец: Две крепости 2002
I’m the king of the world! Я король мира! Джек Доусон Леонардо Ди Каприо Титаник 1997
Решение:
from bs4 import BeautifulSoup
import requests
import re
url = 'https://ru.wikipedia.org/wiki/100_%D0%B8%D0%B7%D0%B2%D0%B5%D1%81%D1%82%D0%BD%D1%8B%D1%85_%D1%86%D0%B8%D1%82%D0%B0%D1%82_%D0%B8%D0%B7_%D0%B0%D0%BC%D0%B5%D1%80%D0%B8%D0%BA%D0%B0%D0%BD%D1%81%D0%BA%D0%B8%D1%85_%D1%84%D0%B8%D0%BB%D1%8C%D0%BC%D0%BE%D0%B2_%D0%B7%D0%B0_100_%D0%BB%D0%B5%D1%82_%D0%BF%D0%BE_%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B8_AFI'
res = requests.get(url).text
soup = BeautifulSoup(res,'html.parser')
table = soup.find('table', class_='wikitable')
header = table.find_all('th')
quotes = table.find_all('tr')
quotes_after_1995 = []
for i in range(1, len(quotes)):
q = quotes[i].get_text()
if int(q[-5:]) > 1995:
quotes_after_1995.append(' '.join(q.split('\n\n')[1:]).replace('\n', ''))
for quote in quotes_after_1995:
print(quote)
Задание 4
Напишите программу, которая извлекает данные о моделях, конфигурации и стоимости 117-ти ноутбуков, и записывает полученную информацию в csv файл.
Ожидаемый результат:
Модель;Описание;Цена
Asus VivoBook X441NA-GA190;Asus VivoBook X441NA-GA190 Chocolate Black, 14", Celeron N3450, 4GB, 128GB SSD, Endless OS, ENG kbd;$295.99
...
Asus ROG Strix SCAR Edition GL503VM-ED115T;Asus ROG Strix SCAR Edition GL503VM-ED115T, 15.6" FHD 120Hz, Core i7-7700HQ, 16GB, 256GB SSD + 1TB SSHD, GeForce GTX 1060 6GB, Windows 10 Home;$1799.00
Решение:
from bs4 import BeautifulSoup
import requests
url = 'https://webscraper.io/test-sites/e-commerce/allinone/computers/laptops'
res = requests.get(url)
soup = BeautifulSoup(res.text,'html.parser')
models = soup.find_all('a', class_='title')
description = soup.find_all('p', class_='description')
prices = soup.find_all('h4', class_='pull-right price')
with open('laptops.csv', 'w', encoding='utf-8') as file:
file.write(f'Модель;Описание;Цена\n')
for m, d, p in zip(models, description, prices):
file.write(f"{m['title']};{d.get_text()};{p.get_text()}\n")
Задание 5
Напишите программу для скачивания полноразмерных обложек из профилей книг на LiveLib. Обложки открываются после двойного клика по миниатюре:
![🐍 Самоучитель по Python для начинающих. Часть 17: Основы скрапинга и парсинга](https://media.proglib.io/posts/2023/03/08/da7d7c3318dc7d9f37fc14ee4ef95e51.png)
Решение:
from bs4 import BeautifulSoup
import requests
import re
url = 'https://www.livelib.ru/book/1002978643-ohotnik-za-tenyu-donato-karrizi'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"}
res = requests.get(url, headers=headers)
soup = BeautifulSoup(res.text,'html.parser')
sp = soup.find('div', class_='bc-menu__image-wrapper')
img_url = re.findall(r'(?:https\:)?//.*\.(?:jpeg)', str(sp))[0]
response = requests.get(img_url, headers=headers)
if response.status_code == 200:
file_name = url.split('-', 1)[1]
with open(file_name + '.jpeg', 'wb') as file:
file.write(response.content)
Задание 6
Напишите программу, которая составляет рейтинг топ-100 лучших триллеров на основе этого списка.
Пример результата:
1. "Побег из Шоушенка", Стивен Кинг - 4.60
2. "Заживо в темноте", Майк Омер - 4.50
3. "Молчание ягнят", Томас Харрис - 4.47
4. "Девушка с татуировкой дракона", Стиг Ларссон - 4.42
5. "Внутри убийцы", Майк Омер - 4.38
...
98. "Абсолютная память", Дэвид Болдаччи - 4.22
99. "Сломанные девочки", Симона Сент-Джеймс - 4.11
100. "Цифровая крепость", Дэн Браун - 3.98
Решение:
from bs4 import BeautifulSoup
import requests
url = 'https://www.livelib.ru/genre/%D0%A2%D1%80%D0%B8%D0%BB%D0%BB%D0%B5%D1%80%D1%8B/top'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"}
res = requests.get(url, headers=headers)
soup = BeautifulSoup(res.content,'html.parser')
titles = soup.find_all('a', class_='brow-book-name with-cycle')
authors = soup.find_all('a', class_='brow-book-author')
rating = soup.find_all('span', class_='rating-value stars-color-orange')
i = 1
for t, a, r in zip(titles, authors, rating):
print(f'{i}. "{t.get_text()}", {a.get_text()} - {r.get_text()}')
i += 1
Задание 7
Напишите программу, которая составляет топ-20 языков программирования на основе рейтинга популярности TIOBE.
Пример результата:
1. Python: 14.83%
2. C: 14.73%
3. Java: 13.56%
4. C++: 13.29%
5. C#: 7.17%
6. Visual Basic: 4.75%
7. JavaScript: 2.17%
8. SQL: 1.95%
9. PHP: 1.61%
10. Go: 1.24%
11. Assembly language: 1.11%
12. MATLAB: 1.08%
13. Delphi/Object Pascal: 1.06%
14. Scratch: 1.00%
15. Classic Visual Basic: 0.98%
16. R: 0.93%
17. Fortran: 0.79%
18. Ruby: 0.76%
19. Rust: 0.73%
20. Swift: 0.71%
Решение:
import requests
from lxml import html
url = 'https://www.tiobe.com/tiobe-index/'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"}
page = requests.get(url, headers=headers)
tree = html.fromstring(page.content)
languages, rating = [], []
for i in range(1, 21):
languages.append(tree.xpath(f'//*[@id="top20"]/tbody/tr[{i}]/td[5]/text()')[0])
rating.append(tree.xpath(f'//*[@id="top20"]/tbody/tr[{i}]/td[6]/text()')[0])
i = 1
for l, r in zip(languages, rating):
print(f'{i}. {l}: {r}')
i += 1
Задание 8
Напишите программу для получения рейтинга 250 лучших фильмов по версии IMDb. Названия должны быть на русском языке.
Пример результата:
1. Побег из Шоушенка, (1994), 9,2
2. Крестный отец, (1972), 9,2
3. Темный рыцарь, (2008), 9,0
...
248. Аладдин, (1992), 8,0
249. Ганди, (1982), 8,0
250. Танцующий с волками, (1990), 8,0
Решение:
import requests
from lxml import html
url = 'https://www.imdb.com/chart/top/'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36",
"Accept-Language": "ru-RU"}
page = requests.get(url, headers=headers)
tree = html.fromstring(page.content)
movies, year, rating = [], [], []
for i in range(1, 251):
movies.append(tree.xpath(f'//*[@id="main"]/div/span/div/div/div[3]/table/tbody/tr[{i}]/td[2]/a/text()')[0])
year.append(tree.xpath(f'//*[@id="main"]/div/span/div/div/div[3]/table/tbody/tr[{i}]/td[2]/span/text()')[0])
rating.append(tree.xpath(f'//*[@id="main"]/div/span/div/div/div[3]/table/tbody/tr[{i}]/td[3]/strong/text()')[0])
i = 1
for m, y, r in zip(movies, year, rating):
print(f'{i}. {m}, {y}, {r}')
i += 1
Задание 9
Напишите программу, которая сохраняет в текстовый файл данные о фэнтези фильмах с 10 первых страниц соответствующего раздела IMDb. Если у фильма/сериала еще нет рейтинга, следует указать N/A.
Ожидаемый результат в файле fantasy.txt – 500 записей:
Мандалорец, (2019– ), 8,7
Всё везде и сразу, (2022), 8,0
Атака титанов, (2013–2023), 9,0
Peter Pan & Wendy, (2023), N/A
Игра престолов, (2011–2019), 9,2
...
Шрэк 3, (2007), 6,1
Кунг-фу Панда 3, (2016), 7,1
Смерть ей к лицу, (1992), 6,6
Исход: Цари и боги, (2014), 6,0
Кошмар на улице Вязов 3: Воины сна, (1987), 6,6
Решение:
import requests
import mechanicalsoup
from lxml import html
import time
url = 'https://www.imdb.com/search/title/?genres=fantasy'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36",
"Accept-Language": "ru-RU"}
browser = mechanicalsoup.StatefulBrowser()
j = 51
for _ in range(10):
browser.open(url)
page = requests.get(url, headers=headers)
tree = html.fromstring(page.content)
titles, year, rating = [], [], []
for i in range(1, 51):
if tree.xpath(f'//*[@id="main"]/div/div[3]/div/div[{i}]/div[3]/p[1]/b/text()') != []:
titles.append(tree.xpath(f'//*[@id="main"]/div/div[3]/div/div[{i}]/div[3]/h3/a/text()')[0])
year.append(tree.xpath(f'//*[@id="main"]/div/div[3]/div/div[{i}]/div[3]/h3/span[2]/text()')[0])
rating.append('N/A')
else:
titles.append(tree.xpath(f'//*[@id="main"]/div/div[3]/div/div[{i}]/div[3]/h3/a/text()')[0])
year.append(tree.xpath(f'//*[@id="main"]/div/div[3]/div/div[{i}]/div[3]/h3/span[2]/text()')[0])
rating.append(tree.xpath(f'//*[@id="main"]/div/div[3]/div/div[{i}]/div[3]/div/div[1]/strong/text()')[0])
with open('fantasy.txt', 'a', encoding='utf-8') as file:
for t, y, r in zip(titles, year, rating):
file.write(f'{t}, {y}, {r}\n')
time.sleep(2)
lnk = browser.follow_link('start=' + str(j))
url = browser.url
j += 50
Задание 10
Напишите программу для получения главных новостей (на русском) с портала Habr. Каждый заголовок должен сопровождаться ссылкой на полный текст новости.
Пример вывода:
Bethesda назвала дату релиза Starfield на ПК, Xbox Series и Xbox Game Pass — 6 сентября 2023 года
https://habr.com/ru/news/t/721148/
Honda запатентовала съёмные подушки безопасности для мотоциклистов
https://habr.com/ru/news/t/721142/
...
Microsoft увольняет 689 сотрудников из своих офисов в Сиэтле
https://habr.com/ru/news/t/721010/
«Ъ»: в России образовались большие запасы бытовой техники из-за низкого спроса
https://habr.com/ru/news/t/721006/
Решение:
from bs4 import BeautifulSoup
import requests
url = 'https://habr.com/ru/news/'
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36",
"Accept-Language": "ru-RU"}
res = requests.get(url, headers=headers)
soup = BeautifulSoup(res.content,'html.parser')
articles = soup.find_all('a', class_='tm-article-snippet__title-link')
for a in articles:
print(f'{a.get_text()}\nhttps://habr.com{a.get("href")}')
Заключение
Мы рассмотрели основные приемы работы с главными Python-инструментами для скрапинга и парсинга. Способы извлечения и обработки данных варьируются от сайта к сайту – в некоторых случаях эффективнее использование XPath, в других – разбор с BeautifulSoup, а иногда может потребоваться применение регулярных выражений.
В следующей главе приступим к изучению основ ООП (объектно-ориентированного программирования).
Содержание самоучителя
- Особенности, сферы применения, установка, онлайн IDE
- Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
- Типы данных: преобразование и базовые операции
- Методы работы со строками
- Методы работы со списками и списковыми включениями
- Методы работы со словарями и генераторами словарей
- Методы работы с кортежами
- Методы работы со множествами
- Особенности цикла for
- Условный цикл while
- Функции с позиционными и именованными аргументами
- Анонимные функции
- Рекурсивные функции
- Функции высшего порядка, замыкания и декораторы
- Методы работы с файлами и файловой системой
- Регулярные выражения
- Основы скрапинга и парсинга
- Основы ООП – инкапсуляция и наследование
- Основы ООП – абстракция и полиморфизм
- Графический интерфейс на Tkinter
- Основы разработки игр на Pygame
- Основы работы с SQLite
- Основы веб-разработки на Flask
- Основы работы с NumPy
- Основы анализа данных с Pandas
Комментарии