Пишем простой парсер сайта для WordPress

Сегодня хочу написать статью, о том как можно с помощью простого php скрипта спарсить какой-нибудь сайт, и добавить его в WordPress записи. Я не буду создавать плагин, использовать классы и ООП, и создам обычный файл в корне сайта parser.php.
В файле parser.php в первую очередь нужно подключить функционал WordPress, для того чтобы можно было с ним работать напрямую.
<?php //Подключаем функции wordpress require( dirname( __FILE__ ) . '/wp-blog-header.php' );
В качестве источника я выбрал сайт «Работы.ру», и решил спарсить у них новые вакансии, надеюсь они не обидятся:).
В первую очередь нужно проверить как реагирует их сайт на самую простую функцию file_get_contents. Понятное дело что контент страницы можно получить с помощью Curl и или готовых библиотек, например Snoopy.class.php.
print_r(file_get_contents("https://www.rabota.ru/vacancy"));
Если сайт разрешил парсить, то на странице paser.php загрузится контент страницы источника с новыми вакансиями.

Теперь нужно узнать HTML код каждого блока с новой вакансией, чтобы создать регулярное выражение. Сделать это можно либо с помощью исходного кода, либо с помощью инструмента для веб-разработчика «Инспектор». Я же рекомендую использовать именно «Исходный код», так как в тэгах между атрибутами, зачастую прячутся лишние пробелы.

С помощью инспектора, я нашёл блоки с: Названием вакансии (1), фирма (2), цена (3), и описание (4), сам же блок с вакансией находится внутри тэга section , который имеет css класс «list-vacancies__item premium «. Обратите внимание с пробелом после premium
Продолжаем разработку кода.
//Подключаем функции wordpress
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
function my_parser($url){
$content=file_get_contents($url);
$match='#<section class="list-vacancies__item premium ">(.*)</section>#isU';
preg_match_all($match,$content,$out);
my_parser_while($out[0]);
}
Внутри функции my_parser, мы записываем в переменную контент с сайта «Работы», затем создаём шаблон для регулярного выражения, и подключаем функцию my_parser_while в которую передаём массив с блоками новых вакансий.
Функция preg_match_all запишет в массив все найденные совпадения, если они соответствуют шаблону
#<section class="list-vacancies__item premium ">(.*)</section>#isU
Внутри функции my_parser_while мы разбираем каждый блок с вакансией и вытаскиваем с помощью preg_match:
- Наименование
- Компанию
- Цену
- Описание
Эти поля мы избавляем от лишних пробелов, и HTML тегов, для этой задачи служат две php функции trim() и strip_tags(). В WordPress можно использовать esc_html()
function my_parser_while($out){
$array=array();
foreach($out as $job){
//А теперь вытаскиваем с помощью preg_match название вакансии
preg_match('#<a?.*class="js-vacancy-item-title list-vacancies__title"?.*>(.*)<sup>?.*</a>#isU',$job,$title);
//Название компании
preg_match('#<a?.*class="list-vacancies__company-title"?.*>(.*)</a>#isU',$job,$company);
//Цена
preg_match('#<div class="list-vacancies__salary?.*"?.*>(.*)</div>#isU',$job,$price);
//Описание
preg_match('#<div class="list-vacancies__desc indent-small">(.*)<\/div>#isU',$job,$opisanie);
//Создаём переменные и делаем их обработку. Убираем HTML теги и лишние пробелы.
$title=trim(strip_tags($title[1]));
$company=trim(strip_tags($company[1]));
$price=trim(strip_tags($price[1]));
$opisanie=trim(strip_tags($opisanie[1]));
//Создадим массив, чтобы показать его на странице
$array[]=array(
'title'=>$title,
'company'=>$company,
'price'=>$price,
'opisanie'=>$opisanie
);
//Создаём условие, если одно из полей пустое, то импорта не будет
if(!empty($title) and !empty($company) and !empty($price) and !empty($opisanie)){
my_parser_insert($title,$company,$price,$opisanie);
}
}
print_r($array);
}
Внутри цикла я подключил функцию my_parser_insert, которая добавит в базу данных новые записи. Как выглядит эта функция.
function my_parser_insert($title,$company,$price,$opisanie){
$post = array(
'post_author' => 1,
'post_content' => $opisanie,
'post_name' => $title,
'post_status' => 'publish',
'post_title' => $title,
'post_type' => 'post',
'post_category' => array(),
'meta_input' => array('price'=>$price,'company'=>$company),
wp_insert_post($post);
}
В WordPress существует функция wp_insert_post($args), которая создаёт записи или страницы, всё зависит от переданного массива с настройками.
- post_author — ID Автора поста. ID администратора по умолчанию = 1
- post_content — Полное описание
- post_name — URL будущей страницы
- post_status — Статус добавляемого материала. draft, publish, pending, future, private
- post_title — Название записи или страницы
- post_type — Куда добавлять (Записи или страницы). Может принимать массив, например array(‘post’,’page’)
- post_category — ID рубрики, но так как я не знаю ID ваших категорий, то оставляем пустой массив
- meta_input — Создание произвольных полей в таблице wp_postmeta
Это лишь часть полей, которые можно передавать, на просторах интернета можно найти полный список, но нам же этого вполне достаточно.
Обратите внимание, что ЦЕНА, и НАЗВАНИЕ КОМПАНИИ были добавлены в таблицу wp_postmeta (Произвольные поля), так как по умолчанию в админке WordPress они не существуют.
Для запуска парсера в самом конце напишем:
my_parser("https://www.rabota.ru/vacancy");А теперь объединим весь функционал и запустим скрипт, а потом посмотрим, что именно у нас получилось на странице «Записи» в админ.панели WordPress.
<?php
//Подключаем функции wordpress
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
//print_r(file_get_contents("https://www.rabota.ru/vacancy"));
function my_parser($url){
$content=file_get_contents($url);
$match='#<section class="list-vacancies__item?.*premium?.*"?.*>(.*)</section>#isU';
preg_match_all($match,$content,$out);
my_parser_while($out[0]);
}
function my_parser_while($out){
$array=array();
foreach($out as $job){
//А теперь вытаскиваем с помощью preg_match название вакансии
preg_match('#<a?.*class="js-vacancy-item-title list-vacancies__title"?.*>(.*)<sup>?.*</a>#isU',$job,$title);
//Название компании
preg_match('#<a?.*class="list-vacancies__company-title"?.*>(.*)</a>#isU',$job,$company);
//Цена
preg_match('#<div class="list-vacancies__salary?.*"?.*>(.*)</div>#isU',$job,$price);
//Описание
preg_match('#<div class="list-vacancies__desc indent-small">(.*)<\/div>#isU',$job,$opisanie);
//Создаём переменные и делаем их обработку. Убираем HTML теги и лишние пробелы.
$title=trim(strip_tags($title[1]));
$company=trim(strip_tags($company[1]));
$price=trim(strip_tags($price[1]));
$opisanie=trim(strip_tags($opisanie[1]));
//Создадим массив, чтобы показать его на странице
$array[]=array(
'title'=>$title,
'company'=>$company,
'price'=>$price,
'opisanie'=>$opisanie
);
//Создаём условие, если одно из полей пустое, то импорта не будет
if(!empty($title) and !empty($company) and !empty($price) and !empty($opisanie)){
my_parser_insert($title,$company,$price,$opisanie);
}
}
print_r($array);
}
function my_parser_insert($title,$company,$price,$opisanie){
$post = array(
'post_author' => 1,
'post_content' => $opisanie,
'post_name' => $title,
'post_status' => 'publish',
'post_title' => $title,
'post_type' => 'post',
'post_category' => array( ),
'meta_input' => array( 'price'=>$price,'company'=>$company ),
);
wp_insert_post($post);
}
my_parser("https://www.rabota.ru/vacancy");После запуска скрипта, в браузере должен отобразиться массив с вакансиями, для этого я специально добавил в него все данные
$array[]=array(
'title'=>$title,
'company'=>$company,
'price'=>$price,
'opisanie'=>$opisanie
);
Давайте посмотрим, что скрипт добавил в админку на страницу «Записи». А он добавил 10 вакансий (Без рубрики), на скриншоте всё не поместилось. На выполнение скрипта понадобилось около 3 секунд.

Внутри же самой записи, мы можем посмотреть Произвольные поля, в нашем случае это Цена, и Название компании,а так же Описание.

Если спарсить нужно небольшое кол-во товаров или блоков, то данного скрипта вполне достаточно.
Минусы
В базу данных wordpress будут добавлены дубликаты вакансий, так как нет проверки существующей записи. Для решения задачи, можно передавать в postmeta, id вакансии с сайта, и сверять.

