为了提升网站的曝光和收录,我们一般都会生成Sitemap让搜索引擎。
而各大搜索引擎对sitemap也做了限制说明:
百度:
文件地址格式为txt或xml,每个地址文件最多包含50,000个网址且需小于10MB。
sitemap提交工具仅对已验证站点开放使用,开发者无法提交同一主域下其他未验证站点的数据。
请勿提交索引型sitemap,索引型不予处理,且若存在索引型sitemap,将不允许提交新文件;请删除索引型sitemap后再尝试提交数据。
360:
单个Sitemap文件:大小不超过10MB,且包含不超过50000个网址。如果网站所包含的网址超过50,000个,则可将列表分割成多个Sitemap文件,放在Sitemap索引中
单个Sitemap索引文件:大小不能超过500M,如果超过请提交多个Sitemap索引文件接口
您可以采用如下三种格式的文件向360搜索提交Sitemap,文件编码可以是UTF-8或GBK:
1)标准的XML格式文件
2)文本格式文件
3)Sitemap索引文件(可同时包含多个Sitemap文件)
搜狗:
不支持sitemap
神马:
神马搜索支持的Sitemap文件包括标准xml文件和索引型xml文件。标准xml文件最多包含10,000条url,如果url超过10,000条可采用索引型xml文件,索引型xml限定最多不超过三层。
一个站点地图可以包含一个网址列表或站点地图列表。
如果您的站点地图包含另一组站点地图,您应将自己的站点地图另存为站点地图索引文件,并使用该文件类型专用的 XML 格式。每个站点地图索引文件最多可以列出 50,000 个站点地图。
一个站点地图文件包含的网址不得超过 50,000 个,且未压缩时不得大于 10MB。如果您的站点地图超过了这些限值,请将其拆分为几个小的站点地图。这些限制条件有助于确保您的网络服务器不会因向 Google 提供大文件而超载。
php artisan make:migration create_artilces_table
Schema::create('article', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title')->comment('标题');
$table->string('thumb')->nullable()->comment('封面');
$table->longText('content')->nullable()->comment('内容');
$table->timestamps();
});<?phpnamespace App\Services;use App\Models\Article;use Illuminate\Support\Facades\Cache;use Illuminate\Support\Facades\App;class SitemapDemoService {// 初始条件选择protected function cachePartOptions($data) {$data = is_array($data) ? $data : [];if (!isset($data['start'])) $data['start'] = 0;$data['left'] = 50000;// if (!isset($data['left'])) $data['left'] = 5000;if (!isset($data['last'])) $data['last'] = 0;if (!isset($data['count'])) $data['count'] = 0;if (!isset($data['no'])) $data['no'] = 1;if (!isset($data['lastModTimes'])) $data['lastModTimes'] = [];return $data;}// 获取初始条件protected function getSitemapCache($name) {$data = Cache::store('redis')->get($name);return $this->cachePartOptions($data);}// 设置初始条件protected function setSitemapCache($name, $data) {$data = $this->cachePartOptions($data);Cache::store('redis')->forever($name, $data);}//...}
Article数据模型和访问路由这里就不多说了,根据laravel的教程来就可以了。
二、生成sitemap
在SitemapDemoService 类中添加下列方法,这里我们用到了50000的id增值来做条件,redis缓存和chunkById查询来优化处理速度,同时每次只生成50000条内的记录,无新增则不运行直接从缓存获取lastModTimes,超出0.8则开始下一阶段。当前你也可以想到其他更优解。
//按ID获取记录public function buildArticles(){$cacheKey = 'buildArticles';$data = $this->getSitemapCache($cacheKey);if ($data['last'] > 0) {$conditions = [['id', '>', $data['last']],];if (Article::where($conditions)->count() == 0) return $data['lastModTimes'];} else {$data['start'] = Article::min('id');}$conditions = [['id', '>', $data['start']],['id', '<', $data['start'] + $data['left']],];$data['count'] = 0;$sitemap = App::make("sitemap");Article::where($conditions)->select(['id', 'created_at', 'updated_at'])->chunkById(100, function ($items) use (&$data, &$sitemap) {foreach ($items as $item) {$data['count']++;$data['last'] = $item->id;// routes/web.php 需提前设置好别名$url = route('article.show', $item->id);$sitemap->add($url, date(DATE_RFC3339, strtotime($item->updated_at)), '0.8', 'daily');}});$sitemap->store('xml', 'articles-' . $data['no'], storage_path('app/public/sitemap'));$sitemap->model->resetItems();$data['lastModTimes'][$data['no']] = now()->timestamp;if ($data['count'] >= $data['left'] * 0.8) {$data['start'] = $data['last'];$data['no']++;}// logInfo('buildArticles-end',[$data]);$this->setSitemapCache($cacheKey, $data);return $data['lastModTimes'];}public function buildIndex() {// create sitemap$sitemap = App::make("sitemap");if ($lastModTimes = $this->buildArticles()) {foreach ($lastModTimes as $name => $time) {$sitemap->addSitemap(config('app.url') . '/storage/sitemap/articles-' . '-' . $name . '.xml', date(DATE_RFC3339, $time));}}// create file sitemap.xml in your public folder (format, filename)// laravelium/sitemap 提供的几种模版,你可以自行选择$sitemap->store('sitemapindex', 'sitemap');}
三、定时执行
完成上面的编写后,执行下列方法就可以生成sitemap,那手动执行肯定是不行的,数据量一大就会php-fpm超时。
new \App\Services\SitemapDemoService)->buildIndex();
<?phpnamespace App\Console\Commands;use Illuminate\Console\Command;class DemoSitemapCommand extends Command{/*** The name and signature of the console command.** @var string*/protected $signature = 'demo:sitemap';/*** The console command description.** @var string*/protected $description = 'Demo Sitemap Daily';/*** Create a new command instance.** @return void*/public function __construct(){parent::__construct();}/*** Execute the console command.** @return mixed*/public function handle(){$this->info('[' . date('Y-m-d H:i:s', time()) . ']开始执行sitemap生成脚本');try {(new \App\Services\SitemapDemoService)->buildIndex();} catch (\Exception $exception) {$this->error('生成sitemap失败:' . $exception->getMessage());return;}$this->info('[' . date('Y-m-d H:i:s', time()) . ']生成sitemap成功!');}}
将上面写好的类加入app\Console\Kernel.php中
protected $commands = [
DemoSitemapCommand::class,
];
protected function schedule(Schedule $schedule){
$schedule->command(DemoSitemapCommand::class)->twiceDaily(1, 13);
}这样你只要开启计划任务或是周期性执行下列命名就可以自动生成sitemap了。
php artisan demo:sitemap
注:
文中提到的Laravel8和 laravelium/sitemap未详尽处,请自行查看官方文档
下面提供几个站长地址:
1)百度 https://ziyuan.baidu.com/
2)360 https://zhanzhang.so.com/
3)搜狗 https://zhanzhang.sogou.com/
4)神马 https://zhanzhang.sm.cn/
5)google https://search.google.com/search-console
yufan个人站