需求描述

在SEO优化中,由于部分搜索引起(如神马、搜狗)没有自动推送功能,导致主动提交网站链接过于麻烦,而通过生成sitemap可以简洁高效的提交链接,让搜索引擎及时收录。

实践步骤

创建sitemap

1. 安装laravel-sitemap扩展包:

composer require spatie/laravel-sitemap

(在GitHub上查看laravel-sitemap)

2. 创建一个SitemapService编写生成逻辑

示例代码:

<?php

namespace App\Services;

use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\SitemapIndex;

class SitemapService
{
    //生成文章子文件,考虑文章数量可能很多,所以分周或者分月汇总
    public function buildArticles()
    {
        $sitemapName = '';
        $articlesData = [];

        Article::select(['id', 'created_at', 'updated_at'])->chunk(100, function ($articles) use (&$articlesData, &$sitemapName) {
            foreach ($articles as $article) {
                $created_at = $article->created_at;
                $sitemapName = $created_at->year . '-' . sprintf("%02d", $created_at->week());
                $articlesData[$sitemapName][] = [
                    'url' => route('article.show', ['id' => $article->id]),
                    'lastmod' => $article->updated_at,
                ];
            }
        });

        $lastModTimes = [];
        foreach ($articlesData as $name => $data) {
            $sitemap = Sitemap::create();
            $lastModTime = max(Arr::pluck($data, 'lastmod'));
            foreach ($data as $_data) {
                $sitemap->add(Url::create($_data['url'])
                        ->setLastModificationDate($_data['lastmod']));
            }
            if ($this->writeSiteMap($sitemap, '/sitemap/articles-' . $name . '.xml')) {
                $lastModTimes[$name] = $lastModTime;
            }
        }
        return $lastModTimes;
    }

    //生成标签地图文件,标签一般不会过多,放在一个文件中即可
    public function buildTags()
    {
        $sitemap = Sitemap::create();
        $lastModTime = Carbon::parse('2000-01-01 12:00');
        Tag::chunk(100, function ($tags) use ($sitemap, &$lastModTime) {
            $lastModTime = max($tags->pluck('updated_at')->toArray());
            foreach ($tags as $tag) {
                $sitemap->add(Url::create(route('tags.show', [ 'id' => $tag->id]))
                        ->setLastModificationDate($tag->updated_at)
                        ->setChangeFrequency(Url::CHANGE_FREQUENCY_WEEKLY)
                );
            }
        });
        if ($this->writeSiteMap($sitemap, '/sitemap/tags.xml')) {
            return $lastModTime;
        }
        return false;
    }

    //生成各栏目首页地图文件
    public function buildHome()
    {
        $sitemap = Sitemap::create();
        //官网首页
        $sitemap->add(Url::create('/')->setLastModificationDate(now()));
        //帮助首页
        $sitemap->add(Url::create(route('help.index'))->setLastModificationDate(now()));

        return $this->writeSiteMap($sitemap, '/sitemap/home.xml');
    }

    public function buildIndex()
    {
        // create sitemap index
        $sitemap = SitemapIndex::create();

        //各栏目首页
        if ($this->buildHome()) {
            $sitemap->add(\Spatie\Sitemap\Tags\Sitemap::create('/sitemap/home.xml')
                    ->setLastModificationDate(now()));
        }
        //标签
        if ($lastModTime = $this->buildTags()) {
            $sitemap->add(\Spatie\Sitemap\Tags\Sitemap::create('/sitemap/tags.xml')
                    ->setLastModificationDate($lastModTime));
        }

        //文章
        if ($lastModTimes = $this->buildArticles()) {
            foreach ($lastModTimes as $name => $time) {
                $sitemap->add(\Spatie\Sitemap\Tags\Sitemap::create('/sitemap/articles-' . $name . '.xml')
                        ->setLastModificationDate($time));
            }
        }
       
        $this->writeSiteMap($sitemap, 'sitemap.xml');
    }

    protected function writeSiteMap($sitemap, $path)
    {
        try {
            $sitemap->writeToFile(public_path($path));
        } catch (\Exception $exception) {
            Log::error('生成sitemap失败(' . $path . '):' . $exception->getMessage());
            return false;
        }
        return true;
    }
}

3. 生成sitemap文件

可食用任务调度每日更新:

php artisan make:command CreateSiteMap

示例代码:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Services\SitemapService;

class CreateSiteMap extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'Create:sitemap';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'create sitemap';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->info('[' . now() . ']开始执行sitemap生成脚本');
        try {
            $sitemapService = new SitemapService();
            $sitemapService->buildIndex();
        } catch (\Exception $exception) {
            $this->error('生成sitemap失败:' . $exception->getMessage());
            return;
        }
        $this->info('[' . now() . ']生成sitemap成功!');
    }
}

Kernel中添加任务:

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        …………
        \App\Console\Commands\CreateSiteMap::class,
        …………
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {

          …………
        //创建站点地图
        $schedule->command('Create:sitemap')
                ->dailyAt('05:00')
                ->runInBackground();
          …………
    }

    …………
}

4. 创建小结

通过以上方法,我们就在应用根目录下生成了sitemao.xml的索引文件,在文件中添加了各个板块或分时段的url明细。这样可以保证sitemap文件不会日积月累,超过限制大小和url数量。

提交sitemap

1. 国内支持sitemap提交的搜索引擎

至于搜狗搜索,站长平台没有显式sitemap提交方式,不过访问http://zhanzhang.sogou.com/index.php/sitemap/create/id/你的ID也是可以提交的。
获取搜狗站点ID可以在网站支持,右键查看源代码,如下图获取:
查看搜狗站点ID

2. 在网站robots.txt添加Sitemap字段,方便蜘蛛爬取

robots.txt结构如下:
robots.txt结构

建议在robots.txt文件最后添加以下信息:

Sitemap: the/url/to/your/stemap.xml

总结说明

昨天刚开始想要弄sitemap看了各种说明,因为对其不了解,觉得很复杂,单实际做了一遍后,会发现并不是很麻烦。
所以,当我们看到问题后,尝试一步步去解决,自然能优化到你想要的结果。
而畏惧前行,也只能故步自封。
另外提醒,sitemap提交并不会比主动推动或自动提交优秀,所以,针对可以主动推送或自动提交的搜索引擎,还是以主动推送为主,sitemap为辅。

Last modification:February 4th, 2020 at 01:01 pm