itstnd@yandex.ru

Консультации

Разработка и поддержка сайтов

Простой парсер для wordpress

 php, web, wordpress    

Сегодня хочу написать статью, о том как можно с помощью простого php скрипта спарсить какой-нибудь сайт, и добавить его в WordPress записи. Я не буду создавать плагин, использовать классы и ООП, и создам обычный файл в корне сайта parser.php.

В файле parser.php в первую очередь нужно подключить функционал WordPress, для того чтобы можно было с ним работать напрямую.

  1. <?php
  2. //Подключаем функции wordpress
  3. require( dirname( __FILE__ ) . ‘/wp-blog-header.php’ );

В качестве источника я выбрал сайт «Работы.ру», и решил спарсить у них новые вакансии, надеюсь они не обидятся:).

В первую очередь нужно проверить как реагирует их сайт на самую простую функцию file_get_contents. Понятное дело что контент страницы можно получить с помощью Curl и или готовых библиотек, например Snoopy.class.php.

  1. print_r(file_get_contents(«https://www.rabota.ru/vacancy»));

Если сайт разрешил парсить, то на странице paser.php загрузится контент страницы источника с новыми вакансиями.

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

С помощью инспектора, я нашёл блоки с: Названием вакансии (1), фирма (2), цена (3), и описание (4), сам же блок с вакансией находится внутри тэга section , который имеет css класс «list-vacancies__item premium «. Обратите внимание с пробелом после premium

Продолжаем разработку кода.

  1. //Подключаем функции wordpress
  2. require( dirname( __FILE__ ) . ‘/wp-blog-header.php’ );
  3. function my_parser($url){
  4. $content=file_get_contents($url);
  5. $match=‘#<section class=»list-vacancies__item premium «>(.*)</section>#isU’;
  6. preg_match_all($match,$content,$out);
  7. my_parser_while($out[0]);
  8. }

Внутри функции my_parser, мы записываем в переменную контент с сайта «Работы», затем создаём шаблон для регулярного выражения, и подключаем функцию my_parser_while в которую передаём массив с блоками новых вакансий.

Функция preg_match_all запишет в массив все найденные совпадения, если они соответствуют шаблону

  1. #<section class=«list-vacancies__item premium «>(.*)</section>#isU

Внутри функции my_parser_while мы разбираем каждый блок с вакансией и вытаскиваем с помощью preg_match:

  • Наименование
  • Компанию
  • Цену
  • Описание

Эти поля мы избавляем от лишних пробелов, и HTML тегов, для этой задачи служат две php функции trim() и strip_tags(). В WordPress можно использовать esc_html()

  1. function my_parser_while($out){
  2. $array=array();
  3. foreach($out as $job){
  4. //А теперь вытаскиваем с помощью preg_match название вакансии
  5. preg_match(‘#<a?.*class=»js-vacancy-item-title list-vacancies__title»?.*>(.*)<sup>?.*</a>#isU’,$job,$title);
  6. //Название компании
  7. preg_match(‘#<a?.*class=»list-vacancies__company-title»?.*>(.*)</a>#isU’,$job,$company);
  8. //Цена
  9. preg_match(‘#<div class=»list-vacancies__salary?.*»?.*>(.*)</div>#isU’,$job,$price);
  10. //Описание
  11. preg_match(‘#<div class=»list-vacancies__desc indent-small»>(.*)<\/div>#isU’,$job,$opisanie);
  12. //Создаём переменные и делаем их обработку. Убираем HTML теги и лишние пробелы.
  13. $title=trim(strip_tags($title[1]));
  14. $company=trim(strip_tags($company[1]));
  15. $price=trim(strip_tags($price[1]));
  16. $opisanie=trim(strip_tags($opisanie[1]));
  17. //Создадим массив, чтобы показать его на странице
  18. $array[]=array(
  19. ‘title’=>$title,
  20. ‘company’=>$company,
  21. ‘price’=>$price,
  22. ‘opisanie’=>$opisanie
  23. );
  24. //Создаём условие, если одно из полей пустое, то импорта не будет
  25. if(!empty($title) and !empty($company) and !empty($price) and !empty($opisanie)){
  26. my_parser_insert($title,$company,$price,$opisanie);
  27. }
  28. }
  29. print_r($array);
  30. }

Внутри цикла я подключил функцию my_parser_insert, которая добавит в базу данных новые записи. Как выглядит эта функция.

  1. function my_parser_insert($title,$company,$price,$opisanie){
  2. $post = array(
  3. ‘post_author’ => 1,
  4. ‘post_content’ => $opisanie,
  5. ‘post_name’ => $title,
  6. ‘post_status’ => ‘publish’,
  7. ‘post_title’ => $title,
  8. ‘post_type’ => ‘post’,
  9. ‘post_category’ => array(),
  10. ‘meta_input’ => array(‘price’=>$price,‘company’=>$company),
  11. wp_insert_post($post);
  12. }

В 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 они не существуют.

Для запуска парсера в самом конце напишем:

  1. my_parser(«https://www.rabota.ru/vacancy»);

А теперь объединим весь функционал и запустим скрипт, а потом посмотрим, что именно у нас получилось на странице «Записи» в админ.панели WordPress.

  1. <?php
  2. //Подключаем функции wordpress
  3. require( dirname( __FILE__ ) . ‘/wp-blog-header.php’ );
  4. //print_r(file_get_contents(«https://www.rabota.ru/vacancy»));
  5. function my_parser($url){
  6. $content=file_get_contents($url);
  7. $match=‘#<section class=»list-vacancies__item?.*premium?.*»?.*>(.*)</section>#isU’;
  8. preg_match_all($match,$content,$out);
  9. my_parser_while($out[0]);
  10. }
  11. function my_parser_while($out){
  12. $array=array();
  13. foreach($out as $job){
  14. //А теперь вытаскиваем с помощью preg_match название вакансии
  15. preg_match(‘#<a?.*class=»js-vacancy-item-title list-vacancies__title»?.*>(.*)<sup>?.*</a>#isU’,$job,$title);
  16. //Название компании
  17. preg_match(‘#<a?.*class=»list-vacancies__company-title»?.*>(.*)</a>#isU’,$job,$company);
  18. //Цена
  19. preg_match(‘#<div class=»list-vacancies__salary?.*»?.*>(.*)</div>#isU’,$job,$price);
  20. //Описание
  21. preg_match(‘#<div class=»list-vacancies__desc indent-small»>(.*)<\/div>#isU’,$job,$opisanie);
  22. //Создаём переменные и делаем их обработку. Убираем HTML теги и лишние пробелы.
  23. $title=trim(strip_tags($title[1]));
  24. $company=trim(strip_tags($company[1]));
  25. $price=trim(strip_tags($price[1]));
  26. $opisanie=trim(strip_tags($opisanie[1]));
  27. //Создадим массив, чтобы показать его на странице
  28. $array[]=array(
  29. ‘title’=>$title,
  30. ‘company’=>$company,
  31. ‘price’=>$price,
  32. ‘opisanie’=>$opisanie
  33. );
  34. //Создаём условие, если одно из полей пустое, то импорта не будет
  35. if(!empty($title) and !empty($company) and !empty($price) and !empty($opisanie)){
  36. my_parser_insert($title,$company,$price,$opisanie);
  37. }
  38. }
  39. print_r($array);
  40. }
  41. function my_parser_insert($title,$company,$price,$opisanie){
  42. $post = array(
  43. ‘post_author’ => 1,
  44. ‘post_content’ => $opisanie,
  45. ‘post_name’ => $title,
  46. ‘post_status’ => ‘publish’,
  47. ‘post_title’ => $title,
  48. ‘post_type’ => ‘post’,
  49. ‘post_category’ => array( ),
  50. ‘meta_input’ => array( ‘price’=>$price,‘company’=>$company ),
  51. );
  52. wp_insert_post($post);
  53. }
  54. my_parser(«https://www.rabota.ru/vacancy»);

После запуска скрипта, в браузере должен отобразиться массив с вакансиями, для этого я специально добавил в него все данные

  1. $array[]=array(
  2. ‘title’=>$title,
  3. ‘company’=>$company,
  4. ‘price’=>$price,
  5. ‘opisanie’=>$opisanie
  6. );

Давайте посмотрим, что скрипт добавил в админку на страницу «Записи». А он добавил 10 вакансий (Без рубрики), на скриншоте всё не поместилось. На выполнение скрипта понадобилось около 3 секунд.

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

Если спарсить нужно небольшое кол-во товаров или блоков, то данного скрипта вполне достаточно.

Минусы

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

 

Взято с https://ivacms.ru чтоб не потерять. Уж больно хорошая статья. Спасибо автору.