微信中展示的封面图很小又无法下载,如何获取封面原图,闲来无事探究一下,发现公众号文章封面是文章html中“msg_cdn_url”变量的值,因此,用PHP实现的思路就有了。
首先写一个简单的HTML界面:
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>通过公众号文章链接获取封面图</title></head><body>
<div class="box">
<h3>通过公众号文章链接获取封面图</h3>
<form id="mpform" action="" method="post">
<input type="text" name="url" placeholder="此处粘贴公众号文章链接" autocomplete="off" class="url">
<button type="button" class="btn">获取封面图</button>
</form>
<?php if(isset($mpThumb)){echo '<div class="result"><em>提示:请右键另存为下载图片</em><img src="'.$dir.'temp.jpg"></div>';}?>
<div class="tips">
<dl>
<dt></dt>
<dd>在微信中打开公众号文章,点击右上角菜单中的“<code>复制链接</code>”,粘贴到上方文本框内,点击按钮获取封面图。</dd>
</dl>
</div>
</div></body></html>
界面是否好看当然取决于CSS样式:
*,body { margin:0; padding:0; }.box { width:750px; padding:24px; margin:20px auto 0; border:1px solid #eee; border-top-width:5px; border-radius:4px; box-sizing:border-box; background:#f8f8f8; }.box h3 { font-size:18px; color:#333; font-weight:normal; text-align:center; }.url { width:100%; height:50px; margin-top:20px; font-family:verdana,'Microsoft Yahei'; line-height:50px; padding:0 14px; font-size:16px; color:#333; border:1px solid #eee; border-radius:4px; box-sizing:border-box; background:#fff; }.url.error, .url.error:focus { color:#f00; border-color:#f00; box-shadow:0 0 0 .2rem #ffdcdc; }.url:focus { color:#2aae67; border-color:#2aae67; outline:0; box-shadow:0 0 0 .2rem #daf1e5; background:#fff; }.btn { width:100%; height:50px; margin-top:20px; font-size:18px; color:#fff; border:0; border-radius:4px; cursor:pointer; background:#2aae67; }.result { position:relative; }.result em { padding:0 10px; font-size:12px; color:#fff; font-style:normal; line-height:24px; border-top-left-radius:4px; border-bottom-left-radius:4px; background:rgba(0,0,0,.5); position:absolute; top:6px; right:0; z-index:1; }.result img { width:100%; margin-top:20px; border-radius:4px; display:block; }.tips { margin-top:20px; font-size:14px; color:#999; }.tips dt { margin-bottom:6px; padding-bottom:6px; font-size:14px; color:#333; font-weight:bold; border-bottom:1px solid #eee; }.tips dd { font-size:12px; color:#666; line-height:1.8; }.tips dd code { margin:0 4px; padding:0 4px; font-size:12px; line-height:1.5; border:1px solid #b0efcd; border-radius:4px; background:#daf1e5; display:inline-block; }@media screen and (max-width:750px){
.box { width:auto; margin:20px 10px 0; }}
点击“获取封面图”按钮要判断文本框是否为空,以及粘贴公众号的链接格式是否正确,这些前端逻辑交由js来处理(提前引入jquery库):
$(function(){
function urlStartsWith(url, startsWith) {
return url.startsWith(startsWith);
}
$(".btn").click(function(){
if($(".url").val() == ''){
$(".url").focus();
$(".url").addClass("error").attr('placeholder','公众号文章链接不能为空!');
return false;
}else if(!urlStartsWith($(".url").val(), 'https://mp.weixin.qq.com/s/')){
$(".url").focus();
$(".url").addClass("error").val('').attr('placeholder','公众号文章链接格式不正确!');
return false;
}else{
$(".url").keydown(function(){
$(this).removeClass("error").attr('placeholder','此处粘贴公众号文章链接');
});
$("#mpform").submit();
}
});});
界面有了,接下来要用PHP实现接收表单传过来的公众号链接,进而使用正则表达式获取公众号html中变量msg_cdn_url的值,也就是封面图的地址,在html代码最上方插入:
<?phpif(isset($_POST['url'])){
$url = htmlspecialchars($_POST['url']);
$data = file_get_contents($url);
preg_match_all('/var msg_cdn_url = "(.*?)";/',$data,$matches);
$mpThumb = $matches[1][0];}?>
获取的封面图显示“此图片来自微信公众平台未经允许不可引用”,不支持外部调用,所以还需优化一下php代码将封面图片本地化:
<?php//当前文件创建同级目录,名字mpThumbs自定义,$dir = './mpThumbs/';if (!is_dir($dir)) {
mkdir($dir, 0777, true);}function downloadImage($remoteUrl, $localPath) {
$ch = curl_init($remoteUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
curl_close($ch);
throw new Exception("cURL Error: " . $error_msg);
}
curl_close($ch);
if (!file_put_contents($localPath, $response)) {
throw new Exception("Failed to save image to local file.");
}
return true;}if(isset($_POST['url'])){
$url = htmlspecialchars($_POST['url']);
$data = file_get_contents($url);
preg_match_all('/var msg_cdn_url = "(.*?)";/',$data,$matches);
$mpThumb = $matches[1][0];
downloadImage($mpThumb, $dir.'temp.jpg');}?>
这样就在php文件同级创建了mpThumbs目录,用于保存下载的封面图,至此,一个获取微信公众号封面的功能就实现了,但题外之言,下载的图片未经权利人许可不能侵权使用。