php解析sitemap并提取有关信息
在昨天完善Magic主题的时候,突然想到一个需求,获取我另一个博客的文章和对应url。但是Halo博客没有提供api(可能是我不知道),但是它提供了sitemap。
那样我就可以用php去解析sitemap然后输出<a>
标签。
使用cURL发送get请求发现回传一个html。
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>荫茵小窝 网站地图</title>
<meta name="robots" content="index,follow" />
<style type="text/css">
..
</style>
</head>
<body>
<h2 style="text-align: center; margin-top: 20px">荫茵小窝 网站地图 </h2>
<div id="nav"><a href="https://blog.yiny.ml"><strong>荫茵小窝</strong></a> » <a href="https://blog.yiny.ml/sitemap.html">站点地图</a></div>
<div id="content">
<h3>最新文章</h3>
<ul id="myTable">
<li>
<div class="T1-h pull-left">URL</div>
<div class="T2-h pull-right">Last Change</div>
<div class="T3-h pull-right">Change Frequency</div>
<div class="T4-h pull-right">Priority</div>
</li>
<div class="myClear"></div>
<li>
<div class="T1 pull-left"><a href="https://blog.yiny.ml" title="荫茵小窝">荫茵小窝</a></div>
<div class="T2 pull-right">2019-02-27</div>
<div class="T3 pull-right">daily</div>
<div class="T4 pull-right">1</div>
</li>
<div class="myClear"></div>
<li>
<div class="T1 pull-left"><a href="https://blog.yiny.ml/archives/折腾失败的新主题" title="折腾失败的新主题">折腾失败的新主题 | 荫茵小窝</a></div>
<div class="T2 pull-right">2019-02-27</div>
<div class="T3 pull-right">daily</div>
<div class="T4 pull-right">0.6</div>
</li>
可以发现需要的标题都在 '/archives/.*?" title="(.*?)">
那么我们用这个正则表达式进行解析。
$url_map = $url . '/sitemap.html';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_map);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec($ch);
curl_close($ch);
preg_match_all('#<div class="T1 pull-left"><a href="'.$url.'/archives/.*?" title="(.*?)">#', $html, $title);
首先使用cURL获取html存入title 变量。这里要注意传入preg_match_all中第一个参数是匹配式,需要两端加#
原因未知,反正没加就报错。走了很多弯路。
$title['1'] = array_reverse($title['1']);
构造url列表。
foreach ($title['1'] as $item)
{
$url_list[] = $url.'/archives/'.$item;
}
然后构造<a>
标签。使用array_map()方法。
php
$all = array_map(function ($i1, $i2) {
return '<a href="' . $i1 . '" target="_blank">' . $i2 . '</a>';
}, $url_list, $title['1']);
最后附上完整的方法。
function parse_halo_sitemap($url)
{
$url_map = $url . '/sitemap.html';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_map);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec($ch);
curl_close($ch);
preg_match_all('#<div class="T1 pull-left"><a href="'.$url.'/archives/.*?" title="(.*?)">#', $html, $title);
$title['1'] = array_reverse($title['1']);
$url_list = array();
foreach ($title['1'] as $item)
{
$url_list[] = $url.'/archives/'.$item;
}
$all = array_map(function ($i1, $i2) {
return '<a href="' . $i1 . '" target="_blank">' . $i2 . '</a>';
}, $url_list, $title['1']);
return $all;
}
其他博客也是如此。