国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
花 2 小時(shí)就能做出一個(gè) RSS 生成器
Wait no longer! Create RSS feeds for all websites you care about and read them from the comfort of your feed reader.
現(xiàn)在越來越多的網(wǎng)站都不支持 RSS 訂閱了,而作為 RSS 的忠實(shí)粉絲,還是希望有個(gè)工具可以將自己關(guān)注的網(wǎng)站內(nèi)容聚合在一起,然后實(shí)時(shí)推送到手機(jī)上,及時(shí)獲取最新消息和新聞動(dòng)態(tài)。
所以今天就讓我們用 2 個(gè)小時(shí),擼一個(gè) RSS 生成器。
本文的主角仍然是 Laravel。

1. 搭建 Laravel 骨架

由于需要有一個(gè)后臺(tái),添加我們關(guān)注的網(wǎng)站,所以我們還是沿用 laravel-damin 插件。
// 1. 創(chuàng)建 Laravel 5.5版本項(xiàng)目
composer create-project –prefer-dist laravel/laravel:5.5 lrss
cd lrss
cp .env.example .env
php 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
注:如出現(xiàn)問題:SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
解決方案:在 AppServiceProvider.php 加入默認(rèn)字符串長(zhǎng)度
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
剛巧,我們想借助 Symfonys 提供的 DomCrawler 插件,來解析網(wǎng)站的 xpath 信息,發(fā)現(xiàn) laravel-admin插件有引入:

2. 解析 XPath

之前有想借助 huginn 這個(gè)神器來生成我們的 RSS Feed,主要參看文章:讓所有網(wǎng)頁變成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
但在實(shí)際使用中,發(fā)現(xiàn)一直出現(xiàn) Huginn 無故宕機(jī),或者后臺(tái) jobs 動(dòng)不動(dòng)就失敗。這才有了自己擼個(gè)工具的想法。
但 Huginn 給了我靈感,可以利用解析 XPath 來生成 RSS Feed。

創(chuàng)建 Xpath 控制器

為了驗(yàn)證輸入的 XPath 信息的準(zhǔn)確性,我們可以參考 Huginn,
首先在 Huginn 測(cè)試 XPath 的效果,在創(chuàng)建 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”
}
}
}
然后點(diǎn) 「Dry Run」即可測(cè)試:
最后根據(jù) Huginn 填入的信息,我們來創(chuàng)建 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
// 創(chuàng)建 admin/Controller
php artisan admin:make XpathController –model=App\\Xpath
// 建立 route
$router->resource(‘xpaths’, XpathController::class);
// 加入到 admin 的 menu 中
// 略
注: 可以參考之前的文章:推薦一個(gè) Laravel admin 后臺(tái)管理插件

CURD XPath

有了 laravel-admin 插件,操作 XPath 信息就好簡(jiǎn)單了,直接看代碼:
<?php
namespace 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(‘請(qǐng)輸入解析的網(wǎng)址’)
->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(‘請(qǐng)輸入標(biāo)題 xpath’)
->rules(‘required|min:5|max:250’);
$form->text(‘titlevalue’, ‘title value 默認(rèn)可以不填’)
->default(”)
->rules(‘max:100’);
// desc
$form->divide();
$form->text(‘descxpath’, ‘desc xpath’)
->placeholder(‘請(qǐng)輸入詳情 xpath’)
->rules(‘required|min:5|max:250’);
$form->text(‘descvalue’, ‘desc value,默認(rèn)可以不填’)
->default(”)
->rules(‘max:100’);
// url
$form->divide();
$form->text(‘preurl’, ‘url 前綴’)
->placeholder(‘請(qǐng)輸入文章的url 前綴’)
->rules(‘max:50’);
$form->text(‘urlxpath’, ‘url xpath’)
->placeholder(‘請(qǐng)輸入文章的url xpath’)
->rules(‘required|min:5|max:250’);
$form->text(‘urlvalue’, ‘url value 默認(rèn)可以不填’)
->default(”)
->rules(‘max:100’);
$form->divide();
$form->display(‘created_at’, ‘Created At’);
$form->display(‘updated_at’, ‘Updated At’);
});
}
}
添加兩個(gè)網(wǎng)站信息試試:

XPath 轉(zhuǎn)為 RSS Feed

1. 根據(jù)填入的 Xpath 信息,解析內(nèi)容:
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);
}
// 通過規(guī)則獲取 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 數(shù)組裝入 Feed Item 中,構(gòu)建 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. 最終來看看效果吧,為每一個(gè)網(wǎng)站做成一個(gè) RSS:

RSS 實(shí)時(shí)訂閱

至此,當(dāng)前的 Laravel 代碼告一段落了,但為了達(dá)到及時(shí)推送內(nèi)容到手機(jī)的目標(biāo),我借助了兩個(gè)工具:
  1. Tiny Tiny RSS
  2. IFTTT + 釘釘
把制作好的 RSS 鏈接加入 Tiny Tiny RSS 上,每隔半個(gè)小時(shí),更新一次,獲取最新的內(nèi)容:
然后借助 IFTTT 綁定釘釘?shù)娜簷C(jī)器人 Webhook:
最后在手機(jī)釘釘或者在 PC 上就能及時(shí)收到最新資訊和信息了:

總結(jié)

今天花了 2 個(gè)小時(shí),主要是借助 laravel-amin 和 symfony/dom-crawler 插件來自己動(dòng)手搭建一個(gè) RSS Feed 生成工具Demo。
接下來還有待于繼續(xù)優(yōu)化,如向 https://feed43.com/ 那樣,輸入 Web URL 就能生成 RSS Feed,又能根據(jù)實(shí)際需要自己設(shè)定更新時(shí)間等。
最后,代碼以放在 github 上,可供參考: https://github.com/fanly/lrss
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用Huginn批量訂閱微信公眾號(hào)
RSS 2.0 Specification參考手冊(cè)
net/c#: 利用反射編寫通用的 rss 2.0 的 reader
Windows Presentation Foundation(WPF)中的數(shù)據(jù)綁定(使用XmlDataProvider作控件綁定之二:使用外部URL的XML文件)
可能是目前最全的 RSS 源,微信公眾號(hào)也有!
YYUC框架與YYUC手冊(cè)資料下載 | 無名
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服