PHP实现通过公众号链接获取封面图
微信中展示的封面图很小又无法下载,如何获取封面原图,闲来无事探究一下,发现公众号文章封面是文章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代码最上方插入:
<?php 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]; } ?>
获取的封面图显示“此图片来自微信公众平台未经允许不可引用”,不支持外部调用,所以还需优化一下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目录,用于保存下载的封面图,至此,一个获取微信公众号封面的功能就实现了,但题外之言,下载的图片未经权利人许可不能侵权使用。
》》》演示地址