部分主题里在文章的标题栏下方会显示一些文章的相关信息,比如目录啊,作者啊,文章的发布日期等等。其中也有包含文章是否被百度收录的,本身“小鸟数据”这个站点配置了“sitemap.xml”,也提交了百度,是否收录就我为鱼肉了。但是偶尔还是想了解一下,到底哪几篇文章已被百度所收录,收录的周期大约又是多久,就想着也在文章下加上这么一行。
比较普遍的实现方式
这段代码网上的流传很广,首先将该代码加入“functions.php”文件:
/**
* 提示文章百度是否收录
*
*/
function baidu_record() {
$url='http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
if(checkBaidu($url)==1){
echo "百度已收录";
}else{
echo "<a style=\"color:red;\" rel=\"external nofollow\" title=\"点击提交收录!\" target=\"_blank\"
href=\"http://zhanzhang.baidu.com/sitesubmit/index?sitename=$url\">百度未收录</a>";}
}
function checkBaidu($url) {
$url = 'http://www.baidu.com/s?wd=' . urlencode($url);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$rs = curl_exec($curl);
curl_close($curl);
if (!strpos($rs, '没有找到')) { //没有找到说明已被百度收录
return 1;
} else {
return -1;
}
}
然后在前台需要的地方调用:
<?php echo baidu_record() ?>
但实际使用中发现,即便是刚发布的文章,也是显示已收录,与实际情况不符,可能是由于提交的参数不足,被安全策略导向了验证页面,从而导致了判断条件的失效。
jquery的尝试
尝试用jquery的ajax组织代码,去获取这个结果,但是遇到了同源策略的限制,无法获取到正确的结果,虽然是短短一句话,背后其实花了博主一个晚上的时间,所以提一嘴以资纪念。虽然没有收获什么成果,但也收获了一个冷知识:
https://www.baidu.com/s
上述语句的s代表了一个接口,不同的接口可以返回不同的功能,虽然s接口遭遇了同源测试,但是如果改成
su,还是可以获取到返回信息的:
https://www.baidu.com/su
比如意图获取百度的下拉词,可以选取使用如下的接口:
https://www.baidu.com/sugrec
joe主题的实现
joe主题是一个很完善的typecho主题,界面精美,功能完善,甚至有很多衍生的魔改版本,下方是joe主题的github地址,寻觅主题的亲可以尝试一下。
印象中joe主题就有这个功能,虽然一知半解都做不到,还是硬着头皮翻看了joe的代码,joe是在页面加载完成之后,利用ajax调用后台命令,实现的这个查询。说一下涉及到的几个文件:
/* 主题开放API 路由规则 */
/core/core.php
/* 查询函数 */
/core/route.php
/* ajax */
/assets/js/joe.post_page.js
因为博主只想看看文章是否被收录,所以就省略了推送的步骤,将程序精简成了如下这样的形式,代码基本纯搬运自joe主题,首先在functions.php文件中添加如下语句:
/* 查询是否收录 已测试 √ */
function _getRecord($self)
{
$self->response->setStatus(200);
$site = $self->request->site;
$encryption = md5(mt_rand(1655, 100860065) . time());
$baiduSite = "https://www.baidu.com/s?ie=utf-8&newi=1&mod=1&isid={$encryption}&wd={$site}&rsv_spt=1&rsv_iqid={$encryption}&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_dl=ib&rsv_sug3=2&rsv_sug1=1&rsv_sug7=001&rsv_n=2&rsv_btype=i&inputT=3083&rsv_sug4=3220&rsv_sug=9&rsv_sid=32818_1460_33042_33060_31660_33099_33101_32961_26350_22159&_ss=1&clist=&hsug=&f4s=1&csor=38&_cr1=32951";
$ip = mt_rand(0, 255) . '.' . mt_rand(0, 255) . '.' . mt_rand(0, 255) . '.' . mt_rand(0, 255);
$header[] = "accept-encoding: gzip, deflate";
$header[] = "accept-language: en-US,en;q=0.8";
$header[] = "CLIENT-IP:" . $ip;
$header[] = "X-FORWARDED-FOR:" . $ip;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baiduSite);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_REFERER, "https://www.baidu.com/s?ie=UTF-8&wd={$site}");
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$output = curl_exec($ch);
curl_close($ch);
$res = str_replace([' ', "\n", "\r"], '', $output);
if (strpos($res, "抱歉,没有找到与") || strpos($res, "找到相关结果约0个") || strpos($res, "没有找到该URL") || strpos($res, "抱歉没有找到")) {
$self->response->throwJson(array("data" => "未收录"));
} else {
$self->response->throwJson(array("data" => "已收录"));
}
}
function themeInit($self){
/* 主题开放API 路由规则 */
if ($self->request->getPathInfo() == "/api") {
if($self->request->routeType == "baidu_record"){
_getRecord($self);
}
}
}
然后在主题的js文件中增加这些内容,因为展现内容的元素命名不同,需要做对应的修改,这里博主为post添加了一个类,仅在文章页让该段代码生效,负责输出的是一个id为“baidu-record”的span元素:
document.addEventListener('DOMContentLoaded', () => {
if(!$('body').hasClass('post'))return;
$.ajax({
url: 'https://www.abddb.com/api',
type: 'POST',
dataType: 'json',
data: { routeType: 'baidu_record', site: window.location.href },
success(res) {
if (res.data && res.data === '已收录') {
$('#baidu-record').text('已收录');
} else {
$('#baidu-record').text('未收录');
}
}
});
});
以上代码需要jquery支持,所以使用前也需要先确认主题是否引入了jquery,效果就是您在本页标题下方看到的效果了,很遗憾,截至目前,本文尚未被百度所收录:)。