使用 PHP 把 Sitemap 中的 URL 推送给百度
建站快两年了,感觉国内的搜索引擎是真的谜!我的网站同时提交给了 Google 、必应、百度、搜狗、360 ,目前 Google 和 必应 基本已经收录了所有网页,新网页也能在 24 小时内收录,很容易就能搜到我的网站。但国内的搜索引擎就很难搜到我的网站,百度的 sitemap
基本上也是半个月前的,点击 手动更新文件 也是一直显示等待:
吐槽的差不多了,下面是用 PHP 主动给百度推送 sitemap.xml 也就是网站地图。
推送方式
目前百度的推送方式包括 主动推送、自动推送、sitemap、手动提交 URL。主动推送就是通过 POST 方式把 URL 提交给百度。自动推送就是在网站 HTML 中添加百度的 JS 推送代码,通过访问者的浏览器推送。sitemap 就是把网站地图的访问地址提交给百度,百度定期访问网站地图来获取 URL。
sitemap 基本上是长时间不会抓取,我的最近一次抓取还是在半个月前。JS 需要手动访问网页,而且可能还会被浏览器阻止,网络不好的情况下可能会影响速度。目前只剩下了主动推送方式提交 URL,百度对提交格式的要求是每行一个 URL,也就是用换行符分隔,百度也给出了一段 PHP 示例,如下:
$urls = array(
'http://www.example.com/1.html',
'http://www.example.com/2.html',
);
$api = 'http://data.zz.baidu.com/urls?site=xxx&token=xxx';
$ch = curl_init();
$options = array(
CURLOPT_URL => $api,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => implode("\n", $urls),
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
echo $result;
这里用到了 Client URL 库 ,我之前写的 PHP 发送 GET 和 POST 请求 也用到了 Client URL 库。百度的示例是把 URL 放在数组里,然后在把数组转为字符串 用 \n 分隔。提交地址后面的 site
参数就是网站域名,token
就是 推送秘钥。
处理 XML
我的网页数量虽然不多 但也不可能手动写 URL,所以只能把 sitemap.xml
中的 URL 转换为 1行 1个 提交给百度。生成 sitemap 的工具和网站有很多,这里推荐一个我正在用的在线生成 sitemap.xml 的网站:https://www.xml-sitemaps.com/ ,只需要输入网站域名就能生成 sitemap.xml
。
下面是 sitemap.xml
的格式:
<url>
<loc>https://www.misterma.com/</loc>
<lastmod>2019-07-08T06:55:06+00:00</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://www.misterma.com/cross.html</loc>
<lastmod>2019-07-08T06:55:06+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://www.misterma.com/category/php/</loc>
<lastmod>2019-07-08T06:55:06+00:00</lastmod>
<priority>0.80</priority>
</url>
提交的时候只需要 loc
,下面是 PHP 代码:
<?php
// 读取 sitemap.xml 文件 并 转换为 PHP 对象
$xml = simplexml_load_file('sitemap.xml');
$urls = array(); // 稍后用来存储 URL
foreach ($xml->url as $val) {
// 把 loc 中的 URL 添加到 $urls 数组
array_push($urls, $val->loc);
}
这里得到了一个包含 URL 的数组,只需要把数组转换为 1 行 1个的字符串就可以提交给百度了,转换函数为: implode("\n", $urls)
。提交后会返回一个 JSON 格式的字符串,需要把 JSON 字符串转换为 PHP 对象才能方便的判断,转换函数为: json_decode()
传入需要转换的 JSON 字符串,返回转换后的 PHP 对象,如果要更详细的了解 PHP 操作 JSON 可以看: PHP 操作 JSON 格式数据 。
因为上面的代码很多都有注释且比较简单,就不逐句介绍了。
返回结果
如果成功会返回:
{
"remain": 4999998,
"success": 2
}
或者:
{
"remain": 4999998,
"success": 2,
"not_same_site": [],
"not_valid": []
}
下面是返回结果说明:
字段 | 是否必选 | 参数类型 | 说明 |
---|---|---|---|
success | 是 | int | 成功推送的url条数 |
remain | 是 | int | 当天剩余的可推送url条数 |
not_same_site | 否 | array | 由于不是本站url而未处理的url列表 |
not_valid | 否 | array | 不合法的url列表 |
如果发生错误会返回:
{
"error": 401,
"message": "token is not valid"
}
其中 error
是错误码,message
是错误信息。
完整示例
下面是完整示例:
<?php
// 读取网站地图并转换为 PHP 对象
$xml = simplexml_load_file('sitemap.xml');
$urls = array(); // 用来存储 URL
foreach ($xml->url as $val) {
// 把 URL 添加到 $urls
array_push($urls, $val->loc);
}
$api = 'http://data.zz.baidu.com/urls?site=xxx&token=xxx'; // 提交地址
$ch = curl_init();
$options = array(
CURLOPT_URL => $api,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => implode("\n", $urls),
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
$result = json_decode($result); // 把返回的json字符串转换为php对象
// 是否推送成功
if (isset($result->success)) {
// 输出已推送的 URL 数量和网站地图中的 URL 数量
echo '推送完成,已推送的 URL 数量:' . $result->success . '网站地图中的 URL 数量:' . count($xml->url);
}else {
echo '推送失败,错误代码:' . $result->error;
}
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/798/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。
很少写评论,这个必须评一下,就想找一个利用sitemap.xml自动推送的代码。这个简直为我量身定制。然后在宝塔添加一个自动任务,简直舒服的不要不要的。
很少写评论,这个必须评一下,就想找一个得胜sitemap.xml自动推送的代码。这个简直为我量身定制。
不错不错!~
似乎和这个配合就能做到发布一次文章,推送一次?
这个完整代码放哪里呢,太难了
在 $api 中填写你的接口调用地址,每个人的接口调用地址都不一样。代码需要和 Sitemap.xml 在同一个目录,也就是说你需要先生成 Sitemap.xml。