aldamr01/laravel-sitemap

轻松创建和生成网站地图

7.10 2023-10-13 06:56 UTC

This package is auto-updated.

Last update: 2024-09-13 08:57:18 UTC


README

此包可以在不手动添加URL的情况下生成网站地图。这是通过爬取整个网站来实现的。

use Aldamr01\Sitemap\SitemapGenerator;

SitemapGenerator::create('https://example.com')->writeToFile($path);

您也可以手动创建您的网站地图

use Carbon\Carbon;
use Aldamr01\Sitemap\Sitemap;
use Aldamr01\Sitemap\Tags\Url;

Sitemap::create()

    ->add(Url::create('/home')
        ->setLastModificationDate(Carbon::yesterday())
        ->setChangeFrequency(Url::CHANGE_FREQUENCY_YEARLY)
        ->setPriority(0.1))

   ->add(...)

   ->writeToFile($path);

或者,您可以通过生成网站地图并添加更多链接来同时获得两者的好处

SitemapGenerator::create('https://example.com')
   ->getSitemap()
   ->add(Url::create('/extra-page')
        ->setLastModificationDate(Carbon::yesterday())
        ->setChangeFrequency(Url::CHANGE_FREQUENCY_YEARLY)
        ->setPriority(0.1))

    ->add(...)

    ->writeToFile($path);

您还可以控制网站地图的最大深度

SitemapGenerator::create('https://example.com')
    ->configureCrawler(function (Crawler $crawler) {
        $crawler->setMaximumDepth(3);
    })
    ->writeToFile($path);

生成器具有在每个页面上执行JavaScript的能力(请参阅此处),因此通过JavaScript注入DOM的链接也将被爬取。

您还可以使用您可用的文件系统磁盘之一将网站地图写入。

SitemapGenerator::create('https://example.com')->getSitemap()->writeToDisk('public', 'sitemap.xml');

您还可以通过实现\Spatie\Sitemap\Contracts\Sitemapable接口直接添加您的模型。

use Aldamr01\Sitemap\Contracts\Sitemapable;
use Aldamr01\Sitemap\Tags\Url;

class Post extends Model implements Sitemapable
{
    public function toSitemapTag(): Url | string | array
    {
        return route('blog.post.show', $this);
        return Url::create(route('blog.post.show', $this))
            ->setLastModificationDate(Carbon::create($this->updated_at))
            ->setChangeFrequency(Url::CHANGE_FREQUENCY_YEARLY)
            ->setPriority(0.1);
    }
}

现在您可以向网站地图添加单个帖子模型,甚至整个集合。

use Aldamr01\Sitemap\Sitemap;

Sitemap::create()
    ->add($post)
    ->add(Post::all());

这样,您可以非常快速地添加所有页面,而无需爬取它们。

支持我们

我们投入了大量资源来创建一流的开源软件包。您可以通过购买我们的付费产品之一来支持我们。

我们非常感谢您从您的家乡寄来明信片,并说明您正在使用我们哪些包。您可以在我们的联系页面上找到我们的地址。我们将在我们的虚拟明信片墙上发布所有收到的明信片。

安装

首先,通过composer安装包

composer require spatie/laravel-sitemap

该包将自动注册自己。

如果您想自动和频繁地更新您的网站地图,您需要执行一些额外步骤

配置

您可以覆盖爬虫的默认选项。首先发布配置

php artisan vendor:publish --provider="Aldamr01\Sitemap\SitemapServiceProvider" --tag=sitemap-config

这将把默认配置复制到config/sitemap.php,您可以在那里编辑它。

use GuzzleHttp\RequestOptions;
use Aldamr01\Sitemap\Crawler\Profile;

return [

    /*
     * These options will be passed to GuzzleHttp\Client when it is created.
     * For in-depth information on all options see the Guzzle docs:
     *
     * http://docs.guzzlephp.org/en/stable/request-options.html
     */
    'guzzle_options' => [

        /*
         * Whether or not cookies are used in a request.
         */
        RequestOptions::COOKIES => true,

        /*
         * The number of seconds to wait while trying to connect to a server.
         * Use 0 to wait indefinitely.
         */
        RequestOptions::CONNECT_TIMEOUT => 10,

        /*
         * The timeout of the request in seconds. Use 0 to wait indefinitely.
         */
        RequestOptions::TIMEOUT => 10,

        /*
         * Describes the redirect behavior of a request.
         */
        RequestOptions::ALLOW_REDIRECTS => false,
    ],
    
    /*
     * The sitemap generator can execute JavaScript on each page so it will
     * discover links that are generated by your JS scripts. This feature
     * is powered by headless Chrome.
     */
    'execute_javascript' => false,
    
    /*
     * The package will make an educated guess as to where Google Chrome is installed. 
     * You can also manually pass it's location here.
     */
    'chrome_binary_path' => '',

    /*
     * The sitemap generator uses a CrawlProfile implementation to determine
     * which urls should be crawled for the sitemap.
     */
    'crawl_profile' => Profile::class,
    
];

用法

生成网站地图

最简单的方法是爬取给定的域名并生成包含所有找到的链接的网站地图。网站地图的目标应由$path指定。

SitemapGenerator::create('https://example.com')->writeToFile($path);

生成的网站地图看起来可能如下所示

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://example.com</loc>
        <lastmod>2016-01-01T00:00:00+00:00</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>
    <url>
        <loc>https://example.com/page</loc>
        <lastmod>2016-01-01T00:00:00+00:00</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>

    ...
</urlset>

自定义网站地图生成器

定义自定义爬取配置文件

您可以通过实现Spatie\Crawler\CrawlProfiles\CrawlProfile接口并自定义shouldCrawl()方法来创建自定义爬取配置文件,以完全控制应爬取哪些URL/域名/子域名。

use Aldamr01\Crawler\CrawlProfiles\CrawlProfile;
use Psr\Http\Message\UriInterface;

class CustomCrawlProfile extends CrawlProfile
{
    public function shouldCrawl(UriInterface $url): bool
    {
        if ($url->getHost() !== 'localhost') {
            return false;
        }
        
        return $url->getPath() === '/';
    }
}

并将您的CustomCrawlProfile::class注册到config/sitemap.php中。

return [
    ...
    /*
     * The sitemap generator uses a CrawlProfile implementation to determine
     * which urls should be crawled for the sitemap.
     */
    'crawl_profile' => CustomCrawlProfile::class,
    
];

更改属性

要更改联系页面的lastmodchangefreqpriority属性

use Carbon\Carbon;
use Aldamr01\Sitemap\SitemapGenerator;
use Aldamr01\Sitemap\Tags\Url;

SitemapGenerator::create('https://example.com')
   ->hasCrawled(function (Url $url) {
       if ($url->segment(1) === 'contact') {
           $url->setPriority(0.9)
               ->setLastModificationDate(Carbon::create('2016', '1', '1'));
       }

       return $url;
   })
   ->writeToFile($sitemapPath);

省略某些链接

如果您不希望爬取的链接出现在网站地图中,只需不要在传递给hasCrawled的可调用函数中返回它即可。

use Aldamr01\Sitemap\SitemapGenerator;
use Aldamr01\Sitemap\Tags\Url;

SitemapGenerator::create('https://example.com')
   ->hasCrawled(function (Url $url) {
       if ($url->segment(1) === 'contact') {
           return;
       }

       return $url;
   })
   ->writeToFile($sitemapPath);

防止爬虫爬取某些页面

您还可以通过传递一个callableshouldCrawl来指示基础爬虫不要爬取某些页面。

注意: shouldCrawl仅与默认爬取Profile或实现shouldCrawlCallback方法的自定义爬取配置文件一起工作。

use Aldamr01\Sitemap\SitemapGenerator;
use Psr\Http\Message\UriInterface;

SitemapGenerator::create('https://example.com')
   ->shouldCrawl(function (UriInterface $url) {
       // All pages will be crawled, except the contact page.
       // Links present on the contact page won't be added to the
       // sitemap unless they are present on a crawlable page.
       
       return strpos($url->getPath(), '/contact') === false;
   })
   ->writeToFile($sitemapPath);

配置爬虫

爬虫本身可以配置来完成一些不同的事情。

您可以为生成网站地图的爬虫进行配置,例如:忽略机器人检查;如下所示。

SitemapGenerator::create('https://:4020')
    ->configureCrawler(function (Crawler $crawler) {
        $crawler->ignoreRobots();
    })
    ->writeToFile($file);

限制爬取页面数量

您可以通过调用setMaximumCrawlCount来限制爬取页面的数量

use Aldamr01\Sitemap\SitemapGenerator;

SitemapGenerator::create('https://example.com')
    ->setMaximumCrawlCount(500) // only the 500 first pages will be crawled
    ...

执行JavaScript

网站地图生成器可以在每个页面上执行JavaScript,以便发现由您的JS脚本生成的链接。您可以通过在配置文件中将execute_javascript设置为true来启用此功能。

在内部,使用无头Chrome来执行JavaScript。以下是如何在您的系统上安装它的提示

该包将根据您的系统猜测Chrome的安装位置。您也可以手动将Chrome二进制文件的路径传递给executeJavaScript()

手动添加链接

您可以为网站地图手动添加链接

use Aldamr01\Sitemap\SitemapGenerator;
use Aldamr01\Sitemap\Tags\Url;

SitemapGenerator::create('https://example.com')
    ->getSitemap()
    // here we add one extra link, but you can add as many as you'd like
    ->add(Url::create('/extra-page')->setPriority(0.5))
    ->writeToFile($sitemapPath);

在XML标签中添加CData属性

默认情况下,CData属性是禁用的,您可以通过在URL::class中添加setCdata()来启用它,如下所示

use Aldamr01\Sitemap\SitemapGenerator;
use Aldamr01\Sitemap\Tags\Url;

SitemapGenerator::create('https://example.com')
    ->getSitemap()
    ->add(Url::create('/extra-page')->setCdata())
    ->writeToFile($sitemapPath);

为链接添加备选链接

多语言网站可能有相同页面的几个备选版本(每个语言一个)。基于前面的示例,添加备选链接可以这样做

use Aldamr01\Sitemap\SitemapGenerator;
use Aldamr01\Sitemap\Tags\Url;

SitemapGenerator::create('https://example.com')
    ->getSitemap()
    // here we add one extra link, but you can add as many as you'd like
    ->add(Url::create('/extra-page')->setPriority(0.5)->addAlternate('/extra-pagina', 'nl'))
    ->writeToFile($sitemapPath);

注意addAlternate函数,它接受一个备选URL和它所属的区域设置。

为链接添加图像

URL也可以有图像。另请参阅https://developers.google.com/search/docs/advanced/sitemaps/image-sitemaps

use Aldamr01\Sitemap\Sitemap;
use Aldamr01\Sitemap\Tags\Url;

Sitemap::create()
    // here we add an image to a URL
    ->add(Url::create('https://example.com')->addImage('https://example.com/images/home.jpg', 'Home page image'))
    ->writeToFile($sitemapPath);

为链接添加多个图像

URL也可以有多个图像。另请参阅https://developers.google.com/search/docs/advanced/sitemaps/image-sitemaps

use Aldamr01\Sitemap\Sitemap;
use Aldamr01\Sitemap\Tags\Url;

Sitemap::create()
    // here we add an image to a URL
    ->add(Url::create('https://example.com')
        ->addImage('https://example.com/images/home.jpg', 'Home page image')
        ->addImage('https://example.com/images/home2.jpg', 'Home page image')
        ->addImage('https://example.com/images/home3.jpg', 'Home page image')
    )
    ->writeToFile($sitemapPath);

为链接添加新闻

URL也可以有新闻。另请参阅https://developers.google.com/search/docs/advanced/sitemaps/news-sitemaps

use Aldamr01\Sitemap\Sitemap;
use Aldamr01\Sitemap\Tags\Url;

Sitemap::create()
    // here we add an image to a URL
    ->add(Url::create('https://example.com')
        ->addNews('https://example.com/images/home.jpg', '27-10-2023 11:11:11')        
    )
    ->writeToFile($sitemapPath);

为链接添加视频

除了图像之外,视频也可以被URL标签包围。请参阅https://developers.google.com/search/docs/crawling-indexing/sitemaps/video-sitemaps

您可以通过这种方式设置所需的属性

use Aldamr01\Sitemap\Sitemap;
use Aldamr01\Sitemap\Tags\Url;

Sitemap::create()
    ->add(
        Url::create('https://example.com')
            ->addVideo('https://example.com/images/thumbnail.jpg', 'Video title', 'Video Description', 'https://example.com/videos/source.mp4', 'https://example.com/video/123')
    )
    ->writeToFile($sitemapPath);

如果您想传递可选参数,如family_friendlyliveplatform

use Aldamr01\Sitemap\Sitemap;
use Aldamr01\Sitemap\Tags\Url;
use Aldamr01\Sitemap\Tags\Video;


$options = ['family_friendly' => Video::OPTION_YES, 'live' => Video::OPTION_NO];
$allowOptions = ['platform' => Video::OPTION_PLATFORM_MOBILE];
$denyOptions = ['restriction' => 'CA'];

Sitemap::create()
    ->add(
        Url::create('https://example.com')
            ->addVideo('https://example.com/images/thumbnail.jpg', 'Video title', 'Video Description', 'https://example.com/videos/source.mp4', 'https://example.com/video/123', $options, $allowOptions, $denyOptions)
    )
    ->writeToFile($sitemapPath);

手动创建网站地图

您还可以完全手动创建网站地图

use Carbon\Carbon;

Sitemap::create()
   ->add('/page1')
   ->add('/page2')
   ->add(Url::create('/page3')->setLastModificationDate(Carbon::create('2016', '1', '1')))
   ->writeToFile($sitemapPath);

创建网站地图索引

您可以创建网站地图索引

use Aldamr01\Sitemap\SitemapIndex;

SitemapIndex::create()
    ->add('/pages_sitemap.xml')
    ->add('/posts_sitemap.xml')
    ->writeToFile($sitemapIndexPath);

您可以将Spatie\Sitemap\Tags\Sitemap对象传递以手动设置lastModificationDate属性。

use Aldamr01\Sitemap\SitemapIndex;
use Aldamr01\Sitemap\Tags\Sitemap;

SitemapIndex::create()
    ->add('/pages_sitemap.xml')
    ->add(Sitemap::create('/posts_sitemap.xml')
        ->setLastModificationDate(Carbon::yesterday()))
    ->writeToFile($sitemapIndexPath);

生成的网站地图索引将类似于以下内容

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <sitemap>
      <loc>http://www.example.com/pages_sitemap.xml</loc>
      <lastmod>2016-01-01T00:00:00+00:00</lastmod>
   </sitemap>
   <sitemap>
      <loc>http://www.example.com/posts_sitemap.xml</loc>
      <lastmod>2015-12-31T00:00:00+00:00</lastmod>
   </sitemap>
</sitemapindex>

创建包含后续网站地图的网站地图索引

您可以通过调用maxTagsPerSitemap方法来生成只包含给定数量标签的网站地图

use Aldamr01\Sitemap\SitemapGenerator;

SitemapGenerator::create('https://example.com')
    ->maxTagsPerSitemap(20000)
    ->writeToFile(public_path('sitemap.xml'));

频繁生成网站地图

您的网站可能需要不时更新。为了使您的网站地图反映这些更改,您可以定期运行生成器。这样做最简单的方法是利用Laravel的默认调度功能。

您可以将 artisan 命令设置得像这样

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Aldamr01\Sitemap\SitemapGenerator;

class GenerateSitemap extends Command
{
    /**
     * The console command name.
     *
     * @var string
     */
    protected $signature = 'sitemap:generate';

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // modify this to your own needs
        SitemapGenerator::create(config('app.url'))
            ->writeToFile(public_path('sitemap.xml'));
    }
}

该命令应在控制台内核中调度。

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    ...
    $schedule->command('sitemap:generate')->daily();
    ...
}

变更日志

请参阅CHANGELOG了解最近更改的信息。

测试

首先在单独的终端会话中启动测试服务器

cd tests/server
./start_server.sh

服务器运行时,您可以执行测试

$ composer test

贡献

请参阅CONTRIBUTING以获取详细信息。

安全性

如果您发现了关于安全性的错误,请通过电子邮件发送至security@spatie.be,而不是使用问题跟踪器。

致谢

支持我们

Spatie是一家位于比利时安特卫普的网络设计公司。您可以在我们的网站上找到所有开源项目的概述在这里

您的业务依赖于我们的贡献吗?在Patreon上与我们联系并支持我们。所有的承诺都将专门用于分配人员以维护和开发新功能。

许可

MIT许可证(MIT)。有关更多信息,请参阅许可证文件