. */ namespace App\Sources; use \App\Models\Game; use \App\Models\Platform; use \App\Models\Language; use \App\Models\Author; use \App\Models\Tag; use \App\Source; use Log; /** * Парсер для Apero.ru * Проблема парсера в том, что на Аперо часто поломана кодировка UTF-8. */ class Apero extends Source { public $title = "Apero"; public $keyword = 'apero'; protected $urls = []; public function parse() { $text = $this->get_text('http://apero.ru/Текстовые-игры/Песочница', [ 'order_by' => 'by_public', ]); $text = mb_convert_encoding($text, 'UTF-8', 'auto'); $this->loadStr($text); $this->parseIndex(); $text = $this->get_text('http://apero.ru/Текстовые-игры', [ 'order_by' => 'by_public', ]); $text = mb_convert_encoding($text, 'UTF-8', 'auto'); $this->loadStr($text); $this->parseIndex(); foreach ($this->urls as $url) { $text = $this->get_text($url); $text = mb_convert_encoding($text, 'UTF-8', 'auto'); $this->loadStr($text); $this->page($url); } } public function parseIndex() { $this->dom->filter('.tabled-game-block')->each(function($gameBlock){ $url = trim($gameBlock->filter('h2 a')->first()->attr('href')); $this->urls[] = $url; }); } public function checkPage($url) { return (strpos($url,'http://apero.ru/') !== FALSE); } public function page($url) { $game = new Game; $game->url = $url; if ($this->dom->filter('#printer')->count() > 0) { $game->source_id = (int) $this->dom->filter('#printer')->first()->attr('data-game-id'); } else { $id = $this->dom->filter('dd')->reduce(function($block) { if ($block->attr('style') === 'color: #cccccc;') { return true; } return false; }); if ($id->count() > 0) { $game->source_id = (int) $id->text(); } } if (empty($game->source_id)) { throw new \Exception('no id'); } $game = $this->findGame($game); if ($game->isClean()) { return; } $title = $this->dom->filter('dd')->reduce(function($block) { if ($block->attr('itemprop') === 'name') { return true; } return false; }); if ($title->count() > 0) { $game->title = $title->text(); } $date = $this->dom->filter('meta')->reduce(function($block){ if ($block->attr('itemprop') === 'datePublished') { return true; } return false; })->first(); if ($date->count() > 0) { $date = $date->attr('content'); } else { $date = NULL; } if (!empty($date)) { $game->release_date = \DateTime::createFromFormat('Y-m-d', $date); } // TODO description $game->save(); $this->dom->filter('dd a')->reduce(function($block){ if ($block->attr('itemprop') === 'author') { return true; } return false; })->each(function($block) use($game){ $author_name = $block->text(); $author_url = $block->attr('href'); $author_model = Author::findByName($author_name); if (empty($author_model)) { $author_model = new Author(); $author_model->name = $author_name; $author_model->url = $author_url; $author_model->save(); } if (!$game->authors()->where('name', $author_name)->exists()) { $game->authors()->attach($author_model); } }); $language = Language::findByCode('ru'); if (!$game->languages()->where('code', 'ru')->exists()) { $game->languages()->attach($language); } $model = Platform::where('title', 'Аперо')->first(); if (!$model) { $model = new Platform(); $model->title = 'Аперо'; $model->save(); } $game->platforms()->attach($model); $this->dom->filter('dd')->reduce(function($block){ if ($block->attr('itemprop') === 'genre') { return true; } return false; })->each(function($block) use($game, $language){ $genre = trim($block->text()); $model = Tag::where('language_id', $language->id) ->where('title', $genre) ->first(); if (!$model) { $model = new Tag(); $model->language_id = $language->id; $model->title = $genre; $model->save(); } $game->tags()->attach($model); }); Log::info($game->title); } }