Парсинг данных — один из самых востребованных инструментов для сайтов на WordPress. С его помощью можно автоматически наполнять сайт актуальным контентом: курсами валют, новостями, прогнозами погоды, товарами поставщиков и многим другим. В этой статье разберём, какие готовые плагины существуют, в каких случаях стоит написать собственный парсер на PHP, и рассмотрим четыре практических сценария интеграции парсинга в WordPress.
Если вы хотите глубже разобраться в самой технологии разбора данных — рекомендуем отдельный материал «Парсер на PHP», где подробно описаны принципы работы, библиотеки (cURL, Guzzle, Simple HTML DOM, Symfony DomCrawler) и типичные подводные камни. Здесь же мы делаем акцент именно на интеграции с WordPress.
Что такое парсинг в контексте WordPress
Парсинг (web scraping) — это автоматический сбор данных с внешних источников: сайтов, API, RSS-лент, прайс-листов. В WordPress эти данные обычно нужно не просто получить, но и:
- сохранить в базу данных (как записи, товары, метаполя или опции);
- закэшировать, чтобы не нагружать внешний источник и собственный сервер;
- обновлять по расписанию (через
wp_cronили системный cron); - вывести на фронтенд (через шорткоды, виджеты или блоки Gutenberg).
Именно поэтому «парсер для WordPress» — это не просто скрипт, который что-то скачивает, а полноценный модуль, встроенный в экосистему движка.
Обзор существующих плагинов
Прежде чем писать собственное решение, имеет смысл оценить готовые плагины. Они закрывают многие типовые задачи без единой строчки кода.
WP All Import
Один из самых мощных инструментов импорта. Принимает XML, CSV и форматы прайс-листов, позволяет визуально сопоставить (маппинг) поля источника с полями записей, товаров WooCommerce, пользователей. Поддерживает импорт по расписанию и обновление уже импортированных записей. Хорошо подходит для сценария с товарами поставщика, но требует, чтобы источник отдавал структурированный фид.
Плюсы: гибкий маппинг, дружелюбный интерфейс, надёжное обновление. Минусы: продвинутые возможности — в платной версии; не «парсит» произвольные HTML-страницы без подготовленного фида.
Content Egg
Плагин-агрегатор для партнёрского и контентного маркетинга: умеет подтягивать товары, цены, отзывы и другой контент из множества источников и API. Часто используется для сравнения цен и наполнения карточек.
Плюсы: много готовых модулей-источников, шаблоны вывода. Минусы: заточен под определённые сценарии (партнёрки, маркетплейсы), своя логика вывода.
WP RSS Aggregator / Feedzy
Специализированные плагины для импорта RSS- и Atom-лент. Позволяют объединять несколько лент, фильтровать по ключевым словам, превращать элементы ленты в записи WordPress.
Плюсы: простая настройка под новости и RSS, фильтрация и дедупликация. Минусы: ограничены форматом ленты — для произвольного HTML не подойдут.
Универсальные скрейперы (WP Content Pilot, Scraper-плагины)
Существуют плагины, которые умеют забирать данные с произвольных страниц по CSS-селекторам. Они ближе всего к «настоящему» парсеру, но любая смена вёрстки источника ломает настройки, а сложную логику постобработки в них реализовать тяжело.
Когда плагинов недостаточно
Готовые решения отлично работают, пока ваша задача типовая. Но как только появляется нестандартный источник, сложная логика преобразования, авторизация на стороне поставщика или специфические требования к кэшированию — гибкости плагина перестаёт хватать. В этом случае пишут собственный парсер.
Свой парсер на PHP внутри WordPress
Главное преимущество собственного решения — полный контроль. Вы сами решаете, как получать данные, как их чистить, где хранить и когда обновлять. WordPress даёт для этого удобный инструментарий, и использовать «голый» file_get_contents совсем не обязательно.
Базовые «кирпичики», на которых строится любой парсер для WordPress:
// 1. Получение данных — через встроенный HTTP API WordPress
$response = wp_remote_get( 'https://example.com/data', array(
'timeout' => 15,
'headers' => array( 'User-Agent' => 'MySiteBot/1.0' ),
) );
if ( is_wp_error( $response ) ) {
error_log( 'Ошибка запроса: ' . $response->get_error_message() );
return;
}
$body = wp_remote_retrieve_body( $response );
// 2. Кэширование — через Transients API, чтобы не дёргать источник на каждый показ
function my_get_cached_data() {
$cache_key = 'my_parser_data';
$data = get_transient( $cache_key );
if ( false === $data ) {
$data = my_fetch_and_parse(); // ваша функция парсинга
set_transient( $cache_key, $data, HOUR_IN_SECONDS );
}
return $data;
}
// 3. Обновление по расписанию — через WP-Cron
add_action( 'init', function () {
if ( ! wp_next_scheduled( 'my_parser_update' ) ) {
wp_schedule_event( time(), 'hourly', 'my_parser_update' );
}
} );
add_action( 'my_parser_update', 'my_fetch_and_parse' );
Детальный разбор библиотек разбора HTML, обработки кодировок, обхода защиты и построения устойчивого парсера вынесен в отдельный материал «Парсер на PHP». Ниже мы опираемся на эти принципы и показываем именно WordPress-специфику.
Теперь перейдём к конкретным сценариям.
Сценарий 1. Парсинг курсов валют
Типовая задача интернет-магазина или информационного сайта — показывать цены сразу в нескольких валютах и автоматически их конвертировать. Источником служат официальные данные центрального банка (например, сайт ЦБ, отдающий курсы в XML).
Логика простая: раз в сутки забираем XML с курсами, разбираем его, сохраняем в опции WordPress и используем при выводе цен.
function parse_currency_rates() {
$url = 'https://example-cbr.ru/scripts/XML_daily.asp'; // абстрактная ссылка на ЦБ
$response = wp_remote_get( $url, array( 'timeout' => 15 ) );
if ( is_wp_error( $response ) ) {
return;
}
$xml = simplexml_load_string( wp_remote_retrieve_body( $response ) );
if ( false === $xml ) {
return;
}
$rates = array();
foreach ( $xml->Valute as $valute ) {
$code = (string) $valute->CharCode; // USD, EUR ...
$value = (float) str_replace( ',', '.', $valute->Value );
$nominal = (int) $valute->Nominal;
$rates[ $code ] = $value / $nominal; // курс за 1 единицу
}
update_option( 'my_currency_rates', $rates );
update_option( 'my_currency_rates_updated', current_time( 'mysql' ) );
}
add_action( 'my_currency_update', 'parse_currency_rates' );
Конвертация цены в нужную валюту:
function convert_price( $rub_amount, $currency = 'USD' ) {
$rates = get_option( 'my_currency_rates', array() );
if ( empty( $rates[ $currency ] ) ) {
return $rub_amount;
}
return round( $rub_amount / $rates[ $currency ], 2 );
}
И шорткод для вывода курса на странице:
add_shortcode( 'currency_rate', function ( $atts ) {
$atts = shortcode_atts( array( 'code' => 'USD' ), $atts );
$rates = get_option( 'my_currency_rates', array() );
$code = strtoupper( $atts['code'] );
return isset( $rates[ $code ] )
? esc_html( number_format( $rates[ $code ], 2 ) . ' ₽' )
: '—';
} );
// Использование: [currency_rate code="EUR"]
Полный разбор форматов XML/JSON центробанков, обработки нескольких валют и построения кросс-курсов вынесен в специальный материал «Парсинг курсов валют».
Сценарий 2. Парсинг новостей и RSS
Второй популярный сценарий — автоматическое наполнение сайта новостями. Здесь у WordPress есть приятный бонус: ядро уже содержит встроенный парсер лент fetch_feed() на базе библиотеки SimplePie. Это самый надёжный способ работать с RSS, не изобретая велосипед.
function import_news_from_rss( $feed_url ) {
include_once ABSPATH . WPINC . '/feed.php';
$feed = fetch_feed( $feed_url );
if ( is_wp_error( $feed ) ) {
return;
}
$max_items = $feed->get_item_quantity( 10 );
$items = $feed->get_items( 0, $max_items );
foreach ( $items as $item ) {
$guid = $item->get_id();
// Защита от дублей — ищем запись с таким же исходным GUID
$existing = get_posts( array(
'meta_key' => '_source_guid',
'meta_value' => $guid,
'post_type' => 'post',
'fields' => 'ids',
) );
if ( $existing ) {
continue;
}
$post_id = wp_insert_post( array(
'post_title' => sanitize_text_field( $item->get_title() ),
'post_content' => wp_kses_post( $item->get_content() ),
'post_date' => $item->get_date( 'Y-m-d H:i:s' ),
'post_status' => 'draft', // на модерацию, чтобы избежать мусора
'post_type' => 'post',
) );
if ( $post_id && ! is_wp_error( $post_id ) ) {
update_post_meta( $post_id, '_source_guid', $guid );
}
}
}
Запускаем импорт по расписанию:
add_action( 'my_news_import', function () {
import_news_from_rss( 'https://example.com/feed/' );
} );
Если же источник не отдаёт RSS, а новости приходится вытаскивать прямо из HTML-страницы по селекторам — это уже полноценный скрейпинг с разбором вёрстки. Такие проекты мы выполняем как парсинг новостей под ключ: настраиваем извлечение заголовков, дат, изображений и текста с произвольных сайтов с учётом их структуры.
Тонкости работы с лентами, форматы RSS 2.0 и Atom, фильтрацию и объединение нескольких источников мы разбираем в отдельной статье про RSS.
Сценарий 3. Парсинг прогноза погоды
Виджет погоды — частый запрос для региональных порталов, сайтов отелей, турагентств. Данные обычно берут из погодного API, которое отдаёт JSON. Задача в контексте WordPress — аккуратно встроить этот виджет на сайт: получить прогноз, закэшировать его на короткий срок и вывести через шорткод или блок.
function get_weather( $city = 'Moscow' ) {
$cache_key = 'weather_' . sanitize_key( $city );
$weather = get_transient( $cache_key );
if ( false !== $weather ) {
return $weather; // отдаём из кэша
}
$url = add_query_arg( array(
'q' => $city,
'units' => 'metric',
'lang' => 'ru',
'appid' => 'YOUR_API_KEY',
), 'https://api.example-weather.com/data/forecast' );
$response = wp_remote_get( $url, array( 'timeout' => 10 ) );
if ( is_wp_error( $response ) ) {
return null;
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
$weather = array(
'temp' => $data['main']['temp'] ?? null,
'description' => $data['weather'][0]['description'] ?? '',
'icon' => $data['weather'][0]['icon'] ?? '',
);
// Погода меняется часто — кэшируем на 30 минут
set_transient( $cache_key, $weather, 30 * MINUTE_IN_SECONDS );
return $weather;
}
Шорткод для вставки виджета в любой пост или страницу:
add_shortcode( 'weather', function ( $atts ) {
$atts = shortcode_atts( array( 'city' => 'Moscow' ), $atts );
$weather = get_weather( $atts['city'] );
if ( empty( $weather ) ) {
return '<span class="weather-error">Погода недоступна</span>';
}
return sprintf(
'<div class="weather-widget">
<span class="weather-city">%s</span>
<span class="weather-temp">%s°C</span>
<span class="weather-desc">%s</span>
</div>',
esc_html( $atts['city'] ),
esc_html( round( $weather['temp'] ) ),
esc_html( $weather['description'] )
);
} );
// Использование: [weather city="Saint Petersburg"]
Ключевые моменты именно для WordPress: короткий TTL кэша (погода быстро устаревает), вывод через шорткод/виджет и обязательное экранирование данных перед выводом.
Полное руководство по источникам погодных данных, разбору многодневных прогнозов и обработке геолокации читайте в материале про парсинг прогнозов погоды — здесь мы рассмотрели его именно в контексте встраивания на сайт WordPress.
Сценарий 4. Парсинг сайта поставщика и импорт товаров в WooCommerce
Самый комплексный сценарий — автоматическое наполнение интернет-магазина товарами поставщика. Источником может быть прайс-лист (CSV/XML/YML) или сам сайт поставщика, который приходится разбирать по HTML. Результат импортируется в WooCommerce как товары с ценами, остатками, изображениями и категориями.
Разберём импорт из структурированного фида (наиболее устойчивый вариант):
function import_supplier_products() {
// Защита от параллельного запуска
if ( get_transient( 'import_lock' ) ) {
return;
}
set_transient( 'import_lock', 1, 10 * MINUTE_IN_SECONDS );
$response = wp_remote_get( 'https://supplier.example.com/price.xml', array(
'timeout' => 60,
) );
if ( is_wp_error( $response ) ) {
delete_transient( 'import_lock' );
return;
}
$xml = simplexml_load_string( wp_remote_retrieve_body( $response ) );
foreach ( $xml->offer as $offer ) {
$sku = (string) $offer->sku;
$name = (string) $offer->name;
$price = (float) $offer->price;
$stock = (int) $offer->stock;
upsert_product( $sku, $name, $price, $stock, (string) $offer->picture );
}
delete_transient( 'import_lock' );
}
Функция «создать или обновить» товар (upsert) — она ищет товар по артикулу (SKU) и либо обновляет существующий, либо создаёт новый:
function upsert_product( $sku, $name, $price, $stock, $image_url = '' ) {
$product_id = wc_get_product_id_by_sku( $sku );
if ( $product_id ) {
// Товар уже есть — обновляем только цену и остаток
$product = wc_get_product( $product_id );
} else {
// Новый товар
$product = new WC_Product_Simple();
$product->set_sku( $sku );
$product->set_name( $name );
// Изображение подгружаем только при создании
if ( $image_url ) {
$attach_id = media_sideload_image( $image_url, 0, $name, 'id' );
if ( ! is_wp_error( $attach_id ) ) {
$product->set_image_id( $attach_id );
}
}
}
$product->set_regular_price( (string) $price );
$product->set_stock_quantity( $stock );
$product->set_manage_stock( true );
$product->set_stock_status( $stock > 0 ? 'instock' : 'outofstock' );
$product->save();
}
Запуск импорта по расписанию (например, дважды в сутки):
add_action( 'init', function () {
if ( ! wp_next_scheduled( 'supplier_import_event' ) ) {
wp_schedule_event( time(), 'twicedaily', 'supplier_import_event' );
}
} );
add_action( 'supplier_import_event', 'import_supplier_products' );
На что обратить внимание в этом сценарии:
- Идентификация по SKU. Артикул — самый надёжный ключ для сопоставления товаров между поставщиком и магазином.
- Изображения подгружаем один раз.
media_sideload_image()— затратная операция, повторять её при каждом обновлении не нужно. - Пакетная обработка. Большие прайсы (десятки тысяч позиций) лучше обрабатывать порциями (batch), чтобы не упереться в лимиты времени и памяти PHP.
- Снятие с публикации. Товары, исчезнувшие из прайса поставщика, имеет смысл переводить в статус «нет в наличии», а не удалять.
Если же поставщик не отдаёт фид и приходится разбирать карточки товаров прямо с HTML-страниц его сайта — это более трудоёмкая задача со своими нюансами (пагинация, динамическая подгрузка, защита от ботов). Принципы такого разбора подробно описаны в материале «Парсер на PHP».
Технические рекомендации
Несколько универсальных правил, которые сделают любой парсер для WordPress надёжнее:
- Используйте HTTP API WordPress (
wp_remote_get/wp_remote_post) вместоfile_get_contentsи «сырого» cURL — он учитывает настройки прокси, таймауты и фильтры движка. - Кэшируйте через Transients API. Это снижает нагрузку и на ваш сервер, и на источник.
- Не парсите на лету при загрузке страницы. Тяжёлый парсинг должен идти в фоне по cron, а фронтенд читает уже готовые данные.
- Замените WP-Cron на системный cron для тяжёлых задач: WP-Cron срабатывает только при посещении сайта и не подходит для длительного импорта.
- Всегда экранируйте данные перед выводом (
esc_html,esc_url,wp_kses_post) — внешний источник нельзя считать доверенным. - Логируйте ошибки и проверяйте
is_wp_error()на каждом шаге: внешний источник может быть недоступен, сменить формат или отдать мусор. - Соблюдайте правовые и этические нормы: уважайте
robots.txt, лимиты запросов и условия использования источника.
Заключение
Парсинг — мощный способ автоматизировать наполнение сайта на WordPress. Для типовых задач часто достаточно готовых плагинов вроде WP All Import или Feedzy. Но как только источник или логика обработки становятся нестандартными, собственный парсер на PHP даёт несравнимо больше контроля и гибкости.
Мы рассмотрели четыре практических сценария — курсы валют, новости и RSS, прогноз погоды и импорт товаров поставщика в WooCommerce, — и показали, как встроить каждый из них в экосистему WordPress с помощью HTTP API, транзиентов и cron.
Хотите глубже разобраться в самой технологии разбора данных — начните с базового материала «Парсер на PHP». А если нужен готовый парсер под вашу задачу — мы возьмём её на себя, от настройки парсинга новостей до полноценного импорта каталога поставщика.