Sitemap 生成,提升站点收录
2022-01-12 12:00 / 浏览量:1526

为了提升网站的曝光和收录,我们一般都会生成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限定最多不超过三层。


Google:
  • 一个站点地图可以包含一个网址列表或站点地图列表。

  • 如果您的站点地图包含另一组站点地图,您应将自己的站点地图另存为站点地图索引文件,并使用该文件类型专用的 XML 格式。每个站点地图索引文件最多可以列出 50,000 个站点地图。

  • 一个站点地图文件包含的网址不得超过 50,000 个,且未压缩时不得大于 10MB。如果您的站点地图超过了这些限值,请将其拆分为几个小的站点地图。这些限制条件有助于确保您的网络服务器不会因向 Google 提供大文件而超载。


笔者演示所使用的为Laravel8和 laravelium/sitemap: ^8.0。
一、准备工作
新增文章数据表


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();
});
新增 SitemapDemoService 类在App\Services下



<?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();
所以还需要在创建一个DemoSitemapCommand类在app\Console\Commands下面


<?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

注:

  1. 文中提到的Laravel8和 laravelium/sitemap未详尽处,请自行查看官方文档

  2. 下面提供几个站长地址:

    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