Пишем простой парсер сайта для 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 вакансии с сайта, и сверять.