基于 GitHub Actions 定时推送网址到百度站长平台

2021-05-17
3分钟阅读时长

前言

刚学会 PHP 的时候写了一个笑话类型的网站,网站的数据是定时从另外一个网站上采集的。但是网站部署在虚拟主机上,所以用不了 crontab 执行定时任务。

解决办法是使用监控宝,定时请求我网站的一个地址,在这个地址里面编写采集数据的逻辑。到了现在已经有很多解决办法,比如 Workerman/Swoole 的定时器组件、GitHub Actions。

本文就是介绍如何用 GitHub Actions 的定时任务将网址推送到百度站长平台,提高文章被收录的速度。

配置 GitHub Actions

首先设置工作流触发条件, push 和 schedule 表示推送代码及定时计划都会触发。

name: 'Push Baidu'
 
on:
  push:
    branches:
      - gh-pages
  schedule:
    - cron: '*/5 * * * *'

jobs:
  start:
    runs-on: ubuntu-latest
    steps:
      # 检查工作流是否可以访问 actions
      - name: Checkout Repository master branch
        uses: actions/checkout@v1
      # 执行仓库中的脚本文件
      - name: Execute script
        env:
          SITEMAP_URL: ${{ secrets.SITEMAP_URL }}
          PUSH_URL: ${{ secrets.PUSH_URL }}
        run: php ./.github/push.php -s ${SITEMAP_URL} -p ${PUSH_URL}

*/5 * * * * 表示每五分钟执行一次。

runs-on 的意思是指定工作流运行在什么环境上,ubuntu-latest 表示 Ubuntu 最新版。 steps 中第一个步骤是检查工作流是否可以访问 actions,第二个步骤是执行我们的 PHP 脚本,在执行脚本之前,需要将密钥库中的 SITEMAP_URL 和 PUSH_URL 以环境变量的方式传给脚本。

https://github.com/用户名/仓库名/settings/secrets/actions 中新增两个配置项:

NameValue
SITEMAP_URL网站的 sitemap 地址,我的是 https://her-cat.com/baidusitemap.xml
PUSH_URL百度站长平台的推送地址,可以在 百度站长平台 普通收录 => API提交页面中找到,类似于:http://data.zz.baidu.com/urls?site=https://her-cat.com&token=xxxxx

将上面的工作流保存到 .github/workflows 目录下,命名为 push.yml。

编写推送脚本

百度站长平台已经提供了 PHP 推送的例子,我基于这个例子添加了自动获取网址的函数并适配了工作流。

<?php

// 获取 sitemap 地址和推送地址
$opt = getopt('s:p:');
if (empty($opt['s']) || empty($opt['p'])) {
    throw new \Exception('关键参数不能为空');
}

// 从 sitemap 中解析出网址列表
function get_site_urls($sitemap_url)
{
    $content = file_get_contents($sitemap_url);
    if (empty($content)) {
        return [];
    }

    $xml = simplexml_load_string($content);
    if (!$xml) {
        return [];
    }
    
    $urls = [];
    foreach ($xml->url as $url) {
        $urls[] = (string) $url->loc;
    }

    return $urls;
}

// 将网址列表推送到百度
function push_to_baidu($push_url, $urls)
{
    $ch = curl_init();
    $options = [
        CURLOPT_URL => $push_url,
        CURLOPT_POST => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_POSTFIELDS => implode("\n", $urls),
        CURLOPT_HTTPHEADER => ['Content-Type: text/plain'],
    ];
    curl_setopt_array($ch, $options);
    return curl_exec($ch);
}

// 获取需要推送的网址列表
$urls = get_site_urls($opt['s']);
if (empty($urls)) {
    throw new \Exception('网址列表为空');
}

// 调用推送函数
echo push_to_baidu($opt['p'], $urls).PHP_EOL;

将上面的代码保存到 .github/ 目录下,命名为 push.php。

然后提交代码就可以在 GitHub Actions 中查看工作流的运行状态。

总结

需要注意,如果你的 sitemap 格式和我的不一样,需要修改 get_site_urls 函数解析网址列表的逻辑。

PS:截止到本文发出来,定时计划还是一次都没有运行,我一度以为配置没写对,后来才发现不是到了计划时间就一定会运行!

当定时计划到达执行时间时,会将本次任务放到一个队列里面,每当 GitHub 有可用的机器时才会运行,一般延迟时间约为 3 到 10 分钟。有时可能是更多的时间,甚至几十分钟或一个多小时。但是,如果延迟时间过长,则当天可能不会触发计划的工作流。除了使用外部调度器手动触发工作流之外,没有别的办法。

相关文章:

本文作者:她和她的猫
本文地址https://her-cat.com/posts/2021/05/17/github-actions-baidu-push-url/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!