brutalhost / evocms-scraper
evocms 3.x 的抓取模块
Requires
- wa72/htmlpagedom: ^3.0
This package is auto-updated.
Last update: 2024-09-22 19:57:52 UTC
README
Evolution CMS 的静态网站解析器。该模块使用 Laravel 组件编写,仅与 Evo 3 兼容。DOM 树操作使用库 wasinger/htmlpagedom。
工作原理
- 在管理面板中创建任务。
- 将解析器 PHP 类列表写入配置文件。
- 通过管理面板或 artisan 命令处理任务。
安装
cd core
php -d="memory_limit=-1" artisan package:installrequire brutalhost/evocms-scraper "*"
php artisan vendor:publish --provider="EvolutionCMS\Scraper\ScraperServiceProvider"
php artisan migrate
开发自己的解析器
文件处理
- 创建 Laravel 包(适用于
EvolutionCMS\Main
)。 - 创建解析器文件夹(例如
EvolutionCMS\Main\Parsers
)。 - 创建一个继承自
EvolutionCMS\Scraper\Services\Parsers\AbstractParser
的类 - 将类添加到配置文件
yourproject\core\custom\config\scraper.php
AbstractParser
抽象类的核心逻辑在构造函数中描述。以下是你基于它创建自己的解析器类需要了解的内容
beforeProcess()
- 这里处理初始 DOM 树。例如,可以为 documentObject 设置 title 和 description。processHtml()
- 缩小 DOM,处理标签、类等。afterProcess()
- 处理处理后的内容,将其保存到 documentObject 的 content 字段。
函数将按此顺序执行。此外,AbstractParser 中还包含从任务中获取数据按 url 的逻辑。建议根据需要重写 AbstractParser。
解析器示例
<?php namespace EvolutionCMS\Scraper\Services\Parsers; use Wa72\HtmlPageDom\HtmlPage; use Wa72\HtmlPageDom\HtmlPageCrawler; class FourPdaParser extends AbstractParser { /* * $this->htmlPage - экземпляр Wa72\HtmlPageDom\HtmlPage; здесь хранится ответ, полученный при обращении к url из задания * $this->documentObject - стандартная страница Evolution CMS; сама создаётся либо перезаписывается уже существующая * $this->task - обрабатываемое задание (модель Task) * */ public function beforeProcess() { $title = str_replace(' - 4PDA', '', $this->htmlPage->getTitle()); $this->documentObject->pagetitle = $title; } public function processHtml() { // заносим в $c контентную часть, с которой будем работать $siteContent = $this->htmlPage->getCrawler()->filter('.content-box')->getInnerHtml(); $c = new HtmlPage($siteContent); // удаляем аттрибуты, которые сильно влияют на отображение $c->filter('*')->removeAttr('style')->removeAttr('width')->removeAttr('height'); // удаляем блок с источником информации $c->filter('.mb_source')->remove(); // удаляем пустые <p></p> $c->filter('p')->each(function (HtmlPageCrawler $node) { if ($node->innerText() == '') { // замещает текущую node дочерними node, если они существуют // если дочерних node нет - замещение пустотой $node->replaceWith($node->getInnerHtml()); } }); // картинки с описаниями $c->filter('.wp-caption')->each(function (HtmlPageCrawler $node) { $node->replaceWith('<figure class="figure">'.$node->getInnerHtml().'</figure>'); }); $c->filter('.wp-caption-dt')->addClass('figure-img'); $c->filter('.wp-caption-dd')->each(function (HtmlPageCrawler $node) { $node->replaceWith('<figcaption class="figure-caption">'.$node->getInnerHtml().'</figcaption>'); }); $c->filter('blockquote')->addClass('blockquote'); $c->filter("img")->removeAttr('class')->addClass("img-fluid"); // изображения в неупорядоченном списке, удаляем стандартные точки сбоку от <li> $c->filter('.galContainer')->addClass('list-unstyled'); $this->htmlPage = $c; } public function afterProcess() { $this->documentObject->content = $this->htmlPage->getBody()->html(); } }
任务处理
php artisan scraper:process {task?} {--with-completed} { --with-unfinished} {--ignore-timestamp}
处理状态为 Created 的任务。
php artisan scraper:process 13
强制处理 ID 为 13 的任务。
php artisan scraper:process --with-completed
处理状态为 Created 或 Completed 的任务。
php artisan scraper:process --with-unfinished --with-completed
处理状态为 Created、Unfinished 或 Completed 的任务。
php artisan scraper:process --ignore-timestamp
忽略时间戳字段(默认情况下,处理时间戳指示日期不在未来的任务)。
php artisan scraper:mark-tasks
将所有无文档的 Completed 任务状态更改为 Created。