前言
刚学会 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 中新增两个配置项:
Name | Value |
---|---|
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 分钟。有时可能是更多的时间,甚至几十分钟或一个多小时。但是,如果延迟时间过长,则当天可能不会触发计划的工作流。除了使用外部调度器手动触发工作流之外,没有别的办法。
相关文章: