日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用 Laravel 花 2 小时撸一个 RSS 生成器

發布時間:2025/3/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用 Laravel 花 2 小时撸一个 RSS 生成器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Wait no longer! Create RSS feeds for all websites you care about and read them from the comfort of your feed reader.

現在越來越多的網站都不支持 RSS 訂閱了,而作為 RSS 的忠實粉絲,還是希望有個工具可以將自己關注的網站內容聚合在一起,然后實時推送到手機上,及時獲取最新消息和新聞動態。

所以今天就讓我們用 2 個小時,擼一個 RSS 生成器。

本文的主角仍然是 Laravel。

1. 搭建 Laravel 骨架

由于需要有一個后臺,添加我們關注的網站,所以我們還是沿用 laravel-damin 插件。

// 1. 創建 Laravel 5.5版本項目composer create-project --prefer-dist laravel/laravel:5.5 lrsscd lrsscp .env.example .envphp artisan key:generate// 2. 使用 laravel-admin 插件 composer require encore/laravel-admin "1.5.*"php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"php artisan admin:install

注:如出現問題:SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

解決方案:在 AppServiceProvider.php 加入默認字符串長度

use Illuminate\Support\Facades\Schema;public function boot() {Schema::defaultStringLength(191); }

剛巧,我們想借助 Symfonys 提供的 DomCrawler 插件,來解析網站的 xpath 信息,發現 laravel-admin插件有引入:

2. 解析 XPath

之前有想借助 huginn 這個神器來生成我們的 RSS Feed,主要參看文章:讓所有網頁變成RSS —— Huginn http://git.huginn.cn/docs/%E8%AE%A9%E6%89%80%E6%9C%89%E7%BD%91%E9%A1%B5%E5%8F%98%E6%88%90RSS%E2%80%94%E2%80%94Huginn.html

但在實際使用中,發現一直出現 Huginn 無故宕機,或者后臺 jobs 動不動就失敗。這才有了自己擼個工具的想法。

但 Huginn 給了我靈感,可以利用解析 XPath 來生成 RSS Feed。

創建 Xpath 控制器

為了驗證輸入的 XPath 信息的準確性,我們可以參考 Huginn,

首先在 Huginn 測試 XPath 的效果,在創建 WebsiteAgent 界面,輸入如下信息:

{"expected_update_period_in_days": "2","url": "http://www.woshipm.com/","type": "html","mode": "on_change","extract": {"title": {"xpath": "//div[@class=\"postlist-item u-clearfix\"]/div[2]/h2/a/text()","value": "normalize-space(.)"},"desc": {"xpath": "//div[@class=\"postlist-item u-clearfix\"]/div[2]/p/text()","value": "normalize-space(.)"},"url": {"xpath": "//div[@class=\"postlist-item u-clearfix\"]/div[2]/h2/a","value": "@href"}} }

然后點 「Dry Run」即可測試:

最后根據 Huginn 填入的信息,我們來創建 Xpath Controller

// bash php artisan make:model Xpath -m// migration public function up() {Schema::create('xpaths', function (Blueprint $table) {$table->increments('id');// url$table->string('url', 250);$table->string("urldesc", 250);// title$table->string('titlexpath', 250);$table->string('titlevalue', 100)->nullable();// desc$table->string('descxpath', 250);$table->string('descvalue', 100)->nullable();// url$table->string("preurl", 50)->nullable();$table->string('urlxpath', 250);$table->string('urlvalue', 100)->nullable();$table->timestamps();}); }// migrate php artisan migrate// 創建 admin/Controller php artisan admin:make XpathController --model=App\\Xpath// 建立 route $router->resource('xpaths', XpathController::class);// 加入到 admin 的 menu 中 // 略

注: 可以參考之前的文章:推薦一個 Laravel admin 后臺管理插件

CURD XPath

有了 laravel-admin 插件,操作 XPath 信息就好簡單了,直接看代碼:

<?phpnamespace App\Admin\Controllers;use App\Xpath;use Encore\Admin\Form; use Encore\Admin\Grid; use Encore\Admin\Facades\Admin; use Encore\Admin\Layout\Content; use App\Http\Controllers\Controller; use Encore\Admin\Controllers\ModelForm;class XpathController extends Controller {use ModelForm;/*** Index interface.** @return Content*/public function index(){return Admin::content(function (Content $content) {$content->header('header');$content->description('description');$content->body($this->grid());});}/*** Edit interface.** @param $id* @return Content*/public function edit($id){return Admin::content(function (Content $content) use ($id) {$content->header('header');$content->description('description');$content->body($this->form()->edit($id));});}/*** Create interface.** @return Content*/public function create(){return Admin::content(function (Content $content) {$content->header('header');$content->description('description');$content->body($this->form());});}/*** Make a grid builder.** @return Grid*/protected function grid(){return Admin::grid(Xpath::class, function (Grid $grid) {$grid->id('ID')->sortable();$grid->column('url');$grid->column('urldesc', "描述");$grid->column('titlexpath');$grid->column('titlevalue');$grid->column('descxpath');$grid->column('descvalue');$grid->column('preurl');$grid->column('urlxpath');$grid->column('urlvalue');$grid->created_at();$grid->updated_at();});}/*** Make a form builder.** @return Form*/protected function form(){return Admin::form(Xpath::class, function (Form $form) {$form->display('id', 'ID');// url$form->text('url', '鏈接')->placeholder('請輸入解析的網址')->rules('required|min:5|max:250');$form->text('urldesc', '一句話描述')->placeholder('一句話描述')->rules('required|min:5|max:250');// title$form->divide();$form->text('titlexpath', 'title xpath')->placeholder('請輸入標題 xpath')->rules('required|min:5|max:250');$form->text('titlevalue', 'title value 默認可以不填')->default('')->rules('max:100');// desc$form->divide();$form->text('descxpath', 'desc xpath')->placeholder('請輸入詳情 xpath')->rules('required|min:5|max:250');$form->text('descvalue', 'desc value,默認可以不填')->default('')->rules('max:100');// url$form->divide();$form->text('preurl', 'url 前綴')->placeholder('請輸入文章的url 前綴')->rules('max:50');$form->text('urlxpath', 'url xpath')->placeholder('請輸入文章的url xpath')->rules('required|min:5|max:250');$form->text('urlvalue', 'url value 默認可以不填')->default('')->rules('max:100');$form->divide();$form->display('created_at', 'Created At');$form->display('updated_at', 'Updated At');});} }

添加兩個網站信息試試:

XPath 轉為 RSS Feed

1. 根據填入的 Xpath 信息,解析內容:

public static function analysis(XpathModel $model) {$html = file_get_contents($model->url);$crawler = new Crawler($html);$titlenodes = $crawler->filterXPath($model->titlexpath);$titles = self::getValueByNodes($titlenodes, $model->titlevalue);$descnodes = $crawler->filterXPath($model->descxpath);$desces = self::getValueByNodes($descnodes, $model->descvalue);$urlnodes = $crawler->filterXPath($model->urlxpath);$urls = self::getValueByNodes($urlnodes, $model->urlvalue);return RssFeeds::feeds($model, $titles, $desces, $urls); }// 通過規則獲取 nodes 的值 public static function getValueByNodes(Crawler $crawler, $key = null) {return $crawler->each(function (Crawler $node) use ($key) {if (empty($key)) {return trim($node->text());} else {return $node->attr($key);}}); }

2. 將獲得 title、desc 和 url 數組裝入 Feed Item 中,構建 RSS。

public static function feeds(Xpath $xpath, $titles = [], $desces = [], $urls = []) {if (!empty($xpath->preurl)) {$preurl = $xpath->preurl;$urlss = collect($urls)->map(function ($url, $key) use ($preurl) {return $preurl.trim($url);});} else {$urlss = collect($urls);}return response()->view('rss',['xpath' => $xpath,'titles' => $titles,'desces' => $desces,'urls' => $urlss->toArray(),'pubDate' => Carbon::now()])->header('Content-Type', 'text/xml'); }

3. 編寫 blade 模板

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>{{ $xpath->url or ' title' }}</title><description>{{ $xpath->urldesc or '描述' }}</description><link>{{ $xpath->url }}</link><atom:link href="{{ url("/feed/$xpath->id") }}" rel="self" type="application/rss+xml"/><pubDate>{{ $pubDate }}</pubDate><lastBuildDate>{{ $pubDate }}</lastBuildDate><generator>coding01</generator>@foreach ($titles as $key => $title)<item><title>{{ $title }}</title><link>{{ $urls[$key] }}</link><description>{{ $desces[$key] }}</description><pubDate>{{ $pubDate }}</pubDate><author>coding01</author><guid>{{ $urls[$key] }}</guid><category>{{ $title }}</category></item>@endforeach</channel> </rss>

4. 最終來看看效果吧,為每一個網站做成一個 RSS:

RSS 實時訂閱

至此,當前的 Laravel 代碼告一段落了,但為了達到及時推送內容到手機的目標,我借助了兩個工具:

  • Tiny Tiny RSS
  • IFTTT + 釘釘
  • 把制作好的 RSS 鏈接加入 Tiny Tiny RSS 上,每隔半個小時,更新一次,獲取最新的內容:

    然后借助 IFTTT 綁定釘釘的群機器人 Webhook:

    最后在手機釘釘或者在 PC 上就能及時收到最新資訊和信息了:

    總結

    今天花了 2 個小時,主要是借助 laravel-amin 和 symfony/dom-crawler 插件來自己動手搭建一個 RSS Feed 生成工具Demo。

    接下來還有待于繼續優化,如向 https://feed43.com/ 那樣,輸入 Web URL 就能生成 RSS Feed,又能根據實際需要自己設定更新時間等。

    最后,代碼已放在 github 上,可供參考: https://github.com/fanly/lrss

    「未完待續」

    總結

    以上是生活随笔為你收集整理的利用 Laravel 花 2 小时撸一个 RSS 生成器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。