Scrapy – это мощный фреймворк на Python для эффективного и масштабируемого веб-скрейпинга. Одной из наиболее частых задач при парсинге веб-страниц является извлечение ссылок. Эта статья подробно рассмотрит, как с помощью Scrapy получить текст ссылки и ее атрибут href, используя как CSS-, так и XPath-селекторы. Мы углубимся в практические аспекты, охватывая обработку относительных URL и типичные ошибки, с которыми сталкиваются разработчики при работе с scrapy парсинг ссылок.
Настройка окружения и первый Scrapy Spider
Установка Scrapy и создание проекта
Для начала работы с scrapy парсер ссылок необходимо установить фреймворк и инициализировать новый проект. Рекомендуется использовать виртуальное окружение:
-
Создание виртуального окружения:
python -m venv venv source venv/bin/activate # macOS/Linux # venv\Scripts\activate # Windows -
Установка Scrapy:
pip install scrapy -
Создание нового проекта Scrapy:
scrapy startproject link_extractor cd link_extractor
Структура Scrapy проекта и основы Spider
После создания проекта вы увидите стандартную структуру Scrapy. Основным компонентом для извлечения данных является Spider. Создадим базовый Spider в файле link_extractor/spiders/my_spider.py:
import scrapy
class MyLinkSpider(scrapy.Spider):
name = 'mylinks'
start_urls = [
'http://quotes.toscrape.com/'
]
def parse(self, response):
# Здесь будет логика для извлечения ссылок и текста
pass
В этом примере name уникально идентифицирует ваш Spider, а start_urls определяет страницы, с которых начнется scrapy парсинг ссылок. Метод parse обрабатывает ответы от этих URL.
Извлечение href с помощью CSS-селекторов
CSS-селекторы предоставляют удобный и интуитивно понятный способ выбора элементов из HTML-документа. Для python scrapy извлечь url из тегов <a> это часто является предпочтительным методом.
Использование CSS-селекторов для выбора тегов <a>
Чтобы выбрать все теги <a> на странице, можно использовать простой селектор 'a'. В Scrapy это выглядит так:
response.css('a')
Этот вызов вернет список объектов Selector, каждый из которых представляет найденный тег <a>.
Получение текста ссылки и атрибута href
Для scrapy получить атрибут href и соответствующий текст ссылки, мы можем модифицировать метод parse. scrapy css href позволяет напрямую выбирать атрибуты с помощью псевдокласса ::attr() и текст с помощью ::text.
import scrapy
class MyLinkSpider(scrapy.Spider):
name = 'mylinks'
start_urls = [
'http://quotes.toscrape.com/'
]
def parse(self, response):
for link in response.css('a'):
href = link.css('::attr(href)').get() # scrapy получить значение href
text = link.css('::text').get() # scrapy получить текст ссылки
if href and text: # Проверка на None
yield {
'text': text.strip(),
'href': response.urljoin(href) # Обработка относительных URL
}
# Пример парсинга ссылок на следующие страницы
next_page = response.css('li.next a::attr(href)').get()
if next_page is not None:
yield response.follow(next_page, self.parse)
Здесь ::attr(href) извлекает значение атрибута href, а ::text – текстовое содержимое элемента. Метод .get() возвращает первый найденный результат (строку), тогда как .getall() возвращает список всех найденных результатов. Использование response.urljoin(href) критически важно для обработки относительных URL, преобразуя их в абсолютные.
Извлечение href с помощью XPath-селекторов
XPath является еще одним мощным инструментом для навигации по XML/HTML-документам и часто используется для scrapy парсить href, когда CSS-селекторы становятся слишком сложными или недостаточно гибкими.
Использование XPath-селекторов для выбора тегов <a>
Для выбора всех тегов <a> можно использовать XPath-выражение //a. В Scrapy это выглядит так:
response.xpath('//a')
Как и в случае с CSS, это вернет список объектов Selector.
Получение текста ссылки и атрибута href
Для scrapy xpath href и текста ссылки, используются специальные синтаксисы внутри XPath. Атрибуты извлекаются с помощью @, а текст узла – с помощью text().
import scrapy
class MyLinkSpider(scrapy.Spider):
name = 'mylinks_xpath'
start_urls = [
'http://quotes.toscrape.com/'
]
def parse(self, response):
for link in response.xpath('//a'):
href = link.xpath('./@href').get() # scrapy извлечь ссылку
text = link.xpath('./text()').get() # scrapy extract href text
if href and text:
yield {
'text': text.strip(),
'href': response.urljoin(href)
}
# Пример парсинга ссылок на следующие страницы с XPath
next_page = response.xpath('//li[@class="next"]/a/@href').get()
if next_page is not None:
yield response.follow(next_page, self.parse)
Здесь ./@href выбирает атрибут href текущего элемента link, а ./text() – его текстовое содержимое. Точка . в начале указывает на поиск относительно текущего узла link.
Обработка и очистка данных
Извлечение данных – это только часть процесса. Важно также правильно обрабатывать и очищать извлеченные значения.
Обработка относительных и абсолютных URL
Веб-страницы часто содержат относительные URL (например, /next-page.html), а не полные абсолютные URL (например, http://example.com/next-page.html). При извлечении href необходимо преобразовывать относительные ссылки в абсолютные для корректного перехода или сохранения. response.urljoin() – это встроенный метод Scrapy, который автоматически обрабатывает эту задачу, используя базовый URL текущего ответа.
# Пример использования urljoin
relative_url = '/author/Steve-Martin'
absolute_url = response.urljoin(relative_url)
print(f"Абсолютный URL: {absolute_url}")
Всегда используйте response.urljoin() при извлечении href, чтобы обеспечить корректность ссылок.
Типичные ошибки и способы их решения при парсинге href
При работе с scrapy selector href и текстом ссылок могут возникнуть следующие проблемы:
-
Noneв результатеget(): Это происходит, когда селектор не находит соответствующий элемент или атрибут. Всегда проверяйте возвращаемое значение наNoneперед использованием.href = link.css('::attr(href)').get() if href is not None: # Обработка href -
Пустые строки или лишние пробелы: Текст ссылок часто содержит ведущие/завершающие пробелы или символы новой строки. Используйте метод
.strip()для их удаления.text = link.css('::text').get() if text is not None: text = text.strip() -
Отсутствие атрибута
href: Не все теги<a>обязательно имеют атрибутhref(например, якоря для JavaScript). Ваш код должен быть устойчивым к таким случаям. -
Малоинформативный текст ссылки: Иногда текст ссылки может быть пустым или содержать только иконку. В таких случаях может потребоваться извлечение дополнительной информации из родительских элементов или соседних узлов для получения контекста.
Заключение
Извлечение href и текста ссылок является фундаментальной операцией в веб-скрейпинге с помощью Scrapy. Мы рассмотрели, как scrapy взять href и scrapy получить текст ссылки, используя как CSS-, так и XPath-селекторы. Понимание того, как scrapy извлечь ссылку и правильно обрабатывать ее (особенно с response.urljoin), имеет решающее значение для создания надежных и эффективных пауков. Всегда помните о проверке на None и очистке данных, чтобы ваш scrapy парсер ссылок работал корректно даже с неидеальным HTML.