Знакомство с парсингом веб-страниц и его реализация с использованием PHP
Table Of Content
- Что такое парсинг веб-страниц?
- Зачем нужен парсинг веб-страниц?
- Как это реализовать?
- GitHub - ariakm25/simple-php-starter: Простой стартовый шаблон для разработки проектов на PHP.
- В настоящее время вы не можете выполнить это действие. Вы вошли в другую вкладку или окно. Вы вышли из системы в другой вкладке или окне или вошли в систему в другой вкладке или окне. Пожалуйста, повторите попытку.
- GitHub - ariakm25/anime_season_scraper
- В настоящее время вы не можете выполнить это действие. Вы вошли в другую вкладку или окно. Вы вышли из системы в другой вкладке или окне...
- Aria Krisna Murti - Medium
- Читайте тексты от Aria Krisna Murti на Medium. Студент программы Системная информатика.
Привет, друзья! Позвольте представиться, меня зовут Ария, и я студент, очень заинтересованный в программировании. В настоящее время я изучаю веб-программирование. В этой статье я расскажу о парсинге веб-страниц и покажу, как его реализовать с помощью языка программирования PHP.
Что такое парсинг веб-страниц?
Вкратце, парсинг веб-страниц - это процесс извлечения данных с веб-сайта.
Зачем нужен парсинг веб-страниц?
С помощью парсинга веб-страниц мы можем получать данные с сайтов, которые не предоставляют источник данных или API, к которым мы можем получить прямой доступ. Кроме того, мы также можем автоматизировать процесс получения данных с исходного веб-сайта.
Как это реализовать?
Хорошо, чтобы реализовать парсинг веб-страниц, на самом деле мы можем использовать различные языки программирования, такие как Nodejs, Python, PHP и другие. Но здесь я буду использовать язык программирования PHP, поэтому нам понадобятся некоторые предварительные условия:
После установки указанного выше программного обеспечения мы можем перейти к следующему шагу - кодированию. В этот раз я приведу пример парсинга веб-сайта MyAnimeList, где предоставляется полная информация о аниме. Мы возьмем данные о списке аниме, которые выходят в текущем сезоне. Вот внешний вид веб-сайта MyAnimeList:
Мы будем извлекать данные об аниме и отображать их на создаваемом нами веб-сайте с другим дизайном. Давайте начнем!
Чтобы упростить процесс разработки веб-сайта с использованием PHP, я создал простой стартовый проект. Вы можете скачать этот проект по следующей ссылке:
GitHub - ariakm25/simple-php-starter: Простой стартовый шаблон для разработки проектов на PHP.
В настоящее время вы не можете выполнить это действие. Вы вошли в другую вкладку или окно. Вы вышли из системы в другой вкладке или окне или вошли в систему в другой вкладке или окне. Пожалуйста, повторите попытку.
github.com
или клонируйте его с помощью git в командной строке:
git clone [https://github.com/ariakm25/simple-php-starter.git](https://github.com/ariakm25/simple-php-starter.git)
После загрузки проекта выполните следующую команду в папке проекта:
composer install
В этом проекте есть следующая структура папок:
- assets
- src
- Controllers
- Helpers
- Routes
- Services
- Views
- Папка assets используется для размещения файлов ресурсов, таких как иконки, изображения, CSS, JavaScript и т. д.
- Папка Controllers используется для размещения файлов контроллеров, которые содержат код для обработки данных и возврата запросов.
- Папка Helpers используется для размещения файлов, содержащих повторно используемый код функций.
- Папка Routes содержит файл Web.php, который содержит код для определения маршрута или URL страницы, к которой можно получить доступ.
- Папка Services содержит файлы, предоставляющие данные для обработки в контроллере.
- Папка Views содержит файлы для отображения пользовательского интерфейса.
Сначала создайте файл IndexController.php в папке Controllers и файл MALService.php в папке Services, которые затем заполним кодом для парсинга данных, которые мы хотим отобразить.
Затем в файле src/Routes/Web.php заполните следующим образом:
На строке 11 мы добавляем маршрут GET '/ ', что означает, что мы можем получить доступ к веб-сайту по URL / (например, domain.com**/**), и добавляем обработчик метода index в класс IndexController для этого маршрута.
Затем в файле IndexController.php заполните кодом ниже:
На строке 11 мы создаем ассоциативный массив с именем $args, который заполняется 'data' в качестве ключа и 'Hello World' в качестве значения. Затем на строке 12 метод index возвращает функцию render, которая включает файл index.php, находящийся в папке src/Views, и извлекает ассоциативный массив переменных $args, преобразуя ключи в переменные, чтобы мы могли получить значение 'Hello World' из ключа, преобразованного в переменную $data.
Затем в файле src/Views/index.php заполните кодом ниже:
Давайте попробуем запустить веб-сайт локально, выполнив следующую команду в интерфейсе командной строки:
php -S localhost:8080
После выполнения этой команды просто откройте URL http://localhost:8080/ в браузере. Если все прошло успешно, вы увидите следующее:
Далее мы создадим сервис для парсинга данных с MyAnimeList. Мы будем использовать пакет с названием voku/simple_html_dom, который упростит извлечение и манипулирование HTML DOM, полученным с целевого веб-сайта, чтобы получить данные или значения, которые мы хотим получить. Чтобы добавить этот пакет в проект, выполните следующую команду в интерфейсе командной строки:
composer require voku/simple_html_dom
После установки пакета продолжим, добавив код в файл src/Services/MALService.php
<?phpnamespace App\Services;use voku\helper\HtmlDomParser;class MALService{
// Базовый URL целевого веб-сайта
private $baseTarget = 'https://myanimelist.net'; private function init($path) { $curl = curl_init($this->baseTarget . $path); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt(
$curl,
CURLOPT_USERAGENT,
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13). Gecko/20080311 Firefox/2.0.0.13'
); $html = curl_exec($curl); curl_close($curl); return HtmlDomParser::str_get_html($html); }
}
В этом классе мы создаем метод init, который используется для получения всего HTML страницы целевого веб-сайта с использованием cURL на основе предоставленного пути в параметре функции. Метод возвращает абстрактный класс HtmlDomParser, чтобы мы могли манипулировать полученным HTML DOM с целевого веб-сайта.
Затем мы создаем новый публичный метод с именем getCurrentAnimeSeason()
public function getCurrentAnimeSeason() { // Получаем HTML с url [https://myanimelist.net/anime/season](https://myanimelist.net/anime/season)
$html = $this->init('/anime/season'); // Парсим HTML}
Для выполнения парсинга или извлечения HTML можно использовать следующий подход:
Сначала мы получим обертку div из данных, которые мы хотим получить, путем ввода селектора ID в функцию findOne() в HtmlDomParser.
public function getCurrentAnimeSeason() { // Получаем HTML с url [https://myanimelist.net/anime/season](https://myanimelist.net/anime/season)
$html = $this->init('/anime/season'); // Парсим HTML
$wrapper = $html->findOne('#contentWrapper');}
Затем, чтобы получить название сезона, мы должны получить элемент anchor, который является child элементом элемента h1. Для этого мы можем написать селектор класса .season_nav и символ > для указания, что мы выберем селектор child после него, и это будет выглядеть так:
public function getCurrentAnimeSeason() { // Получаем HTML с url [https://myanimelist.net/anime/season](https://myanimelist.net/anime/season)
$html = $this->init('/anime/season'); // Парсим HTML
$wrapper = $html->findOne('#contentWrapper');
$data['seasonName'] = $wrapper->findOne('.season_nav > a')->innerText();}
Чтобы получить несколько элементов, как показано выше, мы можем использовать функцию findMulti(), которую затем будем перебирать и парсить каждый элемент, чтобы добавить его в массив переменных 'list'.
public function getCurrentAnimeSeason() { // Получаем HTML с url [https://myanimelist.net/anime/season](https://myanimelist.net/anime/season)
$html = $this->init('/anime/season'); // Парсим HTML
$wrapper = $html->findOne('#contentWrapper');
$data['seasonName'] = $wrapper->findOne('.season_nav > a')->innerText();_ // Получаем список типов аниме текущего сезона_ foreach ($wrapper->findMulti('.js-categories-seasonal > .seasonal-anime-list.js-seasonal-anime-list') as $index => $animeType) { $typeName = $animeType->findOne('.anime-header')->innerText(); $data['list'][$index] = [ 'typeName' => $typeName, 'animes' => [] ]; }}
На данный момент мы получили массив данных, содержащий типы аниме. Затем мы снова выполним цикл, чтобы получить данные аниме по типу и добавить их в массив 'animes'.
Вот результат парсинга HTML для получения данных аниме:
public function getCurrentAnimeSeason(){ $html = $this->init('/anime/season'); $wrapper = $html->findOne('#contentWrapper'); $data['seasonName'] = $wrapper->findOne('.season_nav > a')->innerText();_ // Получаем список типов аниме текущего сезона _foreach ($wrapper->findMulti('.js-categories-seasonal > .seasonal-anime-list.js-seasonal-anime-list') as $index => $animeType) { $typeName = $animeType->findOne('.anime-header')->innerText(); $data['list'][$index] = [ 'typeName' => $typeName, 'animes' => [] ];_ // Получаем список аниме для каждого типа _foreach ($animeType->findMulti('.seasonal-anime.js-seasonal-anime') as $anime) {_ // Получаем жанры аниме. _$genres = [];
foreach ($anime->findMulti('.genres-inner > .genre') as $genre)
{
$genreName = $genre->findOne('a')->innerText();
_// Пропускаем 18+ аниме _if (strtolower($genreName) == 'hentai') continue 2;
$genres[] = $genreName;
}_ // Получаем изображение аниме _$image = $anime->findOne('.image > a > img')->getAttribute('data-src');
$image = $image != null ? $image : $anime->findOne('.image > a > img')->getAttribute('src');_ // Данные аниме _$data['list'][$index]['animes'][] = [ 'title' => $anime->findOne('.h2_anime_title > a')->innerText(), 'url' => $anime->findOne('.h2_anime_title > a')->getAttribute('href'), 'image' => $image, 'score' => strip_tags($anime->findOne('.score.score-label')->innerText()), 'member' => strip_tags($anime->findOne('.member.fl-r')->innerText()), 'producer' => $anime->findOne('.producer > a')->innerText(), 'eps' => $anime->findOne('.eps > a > span')->innerText(), 'source' => $anime->findOne('.source')->innerText(), 'genres' => $genres ]; } } return $data;}
Вот содержимое файла MALService.php
Затем давайте вызовем этот сервис в IndexController.php, а затем проверим данные, которые мы распарсили, в формате ответа JSON:
<?phpnamespace App\Controllers;use App\Helpers\View;use App\Services\MALService;class IndexController{ private $MALService; public function __construct() { $this->MALService = new MALService(); } public function index() { $args['data'] = $this->MALService->getCurrentAnimeSeason(); header('Content-Type: application/json'); echo json_encode($args['data'], JSON_PRETTY_PRINT); die();_ // return View::render('index', $args);_ }
public function notFound() { return View::render('404'); }}
Вот данные, которые мы распарсили и преобразовали в формат JSON:
Круто, не так ли? Веб-скрапинг можно использовать не только для таких случаев, как описано выше, но и для множества других задач, таких как сбор данных для исследований, текстового анализа, обнаружения фейкового контента и т. д.
Проект можно посмотреть в репозитории Github по следующей ссылке:
GitHub - ariakm25/anime_season_scraper
В настоящее время вы не можете выполнить это действие. Вы вошли в другую вкладку или окно. Вы вышли из системы в другой вкладке или окне...
github.com
Вы можете внести свой вклад в этот репозиторий GitHub, чтобы изучить реализацию других функций, таких как страница с подробной информацией об аниме.
Хорошо, это все, что я хотел рассказать в этой статье. Извините, если я сделал какие-либо ошибки, пожалуйста, исправьте меня в комментариях.
Спасибо, надеюсь, что это будет полезно!
10518122 — Ариа Крисна Мурти Программа Системной Информации Факультет Техники и Компьютерных Наук Университет Компьютерных Наук Индонезии
Aria Krisna Murti - Medium
Читайте тексты от Aria Krisna Murti на Medium. Студент программы Системная информатика.
medium.com