微信公众号文章跨域展示

帮朋友做了个整站,更新新闻的时候他用不惯我写的后台,老是发微信公众号,让我帮忙发到网站上,我觉得太麻烦了,就写了个调用的方法。

微信公众号自带保护,不让跨域访问。
只能用http://cors-anywhere.herokuapp.com/跨域访问接口。

http://cors-anywhere.herokuapp.com/+公众号文章地址就可以得到文章的源代码,加以正则匹配就可以得到文章的标题,正文。

匹配标题: /<h2 class=\"rich_media_title\" id=\"activity-name\">([\s\S]*)<\/h2>/ig
匹配正文: /js_content\">([\s\S]*?)<\/div>/ig

最后需要做的是把图片的路径用正则替换一下,因为公众号采取的是lazy-load,只有浏览到了才会加载,result.replace(/data-src="/g,'src="http://img01.store.sogou.com/net/a/04/link?appid=100520029&url=')

其中替换后sogou部分的网址是加载图片的API,不加这个的话,同样会提示禁止站外加载图片。

效果如下:
https://codepen.io/2bt/full/joBKJg

(2021年更新)
前端的方法API总是失效,现在改用本地PHP进行Curl访问图片,再封装内容给到前端。

源码如下,需要自己调整一下正则和输出的样式:

<?php
class WxCrawler
{
    //微信内容div正则
    private $wxContentDiv = '/<div class="rich_media_content " id="js_content" style="visibility: hidden;">(.*?)<\/div>/s';
    //微信图片样式
    private $imageStyle = 'style="width: 100% !important;height: auto !important;visibility: visible !important;"';
    /**
     * 爬取内容
     * @param  $url
     * @return false|string
     * @author bignerd
     * @since  2016-08-16T10:13:58+0800
     */
    private function _get($url)
    {

        $context = stream_context_create(array('http'=> array('header'=>'Connection:close')));
        return file_get_contents($url,false,$context);
    }

    public function crawByUrl($url)
    {
        $content = $this->_get($url);
 
        $basicInfo = $this->articleBasicInfo($content);
        list($content_html, $content_text) = $this->contentHandle($content);
        return array_merge($basicInfo,['content_html' => $content_html,'content_text' => $content_text]);
    }
    /**
     * 处理微信文章源码,提取文章主体,处理图片链接
     * @author bignerd
     * @since  2016-08-16T15:59:27+0800
     * @param  $content 抓取的微信文章源码
     * @return [带图html文本,无图html文本]
     */
    private function contentHandle($content)
    {
        $content_html_pattern = $this->wxContentDiv;
        preg_match_all($content_html_pattern, $content, $html_matchs);
        if(empty(array_filter($html_matchs))) {
            return http_response_code(404);
            exit();
        }
        $content_html = $html_matchs[0][0];
        //去除掉hidden隐藏
        $content_html = str_replace('style="visibility: hidden;"','',$content_html);
        //过滤掉iframe
        $content_html = preg_replace('/<iframe(.*?)<\/iframe>/','',$content_html);
        $path = 'article/';
        /** @var  带图片html文本 */
        $content_html = preg_replace_callback('/data-src="(.*?)"/', function($matches) use ($path){
            return 'src="https://img-blog.csdnimg.cn/2022010705000841016.png'.$this->getImg($matches[1]).'" '.$this->imageStyle;
        }, $content_html);
 
        //添加微信样式
        $content_html = '<div style="max-width: 50%;margin-left: auto;margin-right: auto;transform: scale(1.5);transform-origin: top;">'.$content_html. '</div>';
        /** @var  无图html文本 */
        $content_text = preg_replace('/<img.*?>/s','',$content_html);
 
        return [$content_html,$content_text];
    }
    /**
     * 获取文章的基本信息
     * @author bignerd
     * @since  2016-08-16T17:16:32+0800
     * @param  $content 文章详情源码
     * @return $basicInfo
     */
    private function articleBasicInfo($content)
    {
        //待获取item
        $item = [
            'ct' => 'date',//发布时间
            'msg_title' => 'title',//标题
            'msg_desc' => 'digest',//描述
            'msg_link' => 'content_url',//文章链接
            'msg_cdn_url' => 'cover',//封面图片链接
            'nickname' => 'wechatname',//公众号名称
        ];
        $basicInfo = [
            'author' => '',
            'copyright_stat' => '',
        ];
        foreach ($item as $k => $v) {
            if($k == 'msg_title')
                $pattern = '/ var '.$k.' = (.*?)\.html\(false\);/s';
            else
                $pattern = '/ var '.$k.' = "(.*?)";/s';
 
            preg_match_all($pattern,$content,$matches);
            if(array_key_exists(1, $matches) && !empty($matches[1][0])){
                $basicInfo[$v] = $this->htmlTransform($matches[1][0]);
            }else{
                $basicInfo[$v] = '';
            }
        }

        return $basicInfo;
    }
    /**
     * 特殊字符转换
     * @author bignerd
     * @since  2016-08-16T17:30:52+0800
     * @param  $string
     * @return $string
     */
    private function htmlTransform($string)
    {
        $string = str_replace('&quot;','"',$string);
        $string = str_replace('&amp;','&',$string);
        $string = str_replace('amp;','',$string);
        $string = str_replace('&lt;','<',$string);
        $string = str_replace('&gt;','>',$string);
        $string = str_replace('&nbsp;',' ',$string);
        $string = str_replace("\\", '',$string);
        return $string;
    }
 
    /**
     * @param $url
     * @return string
     */
    private function getImg($url){
        $refer = "http://www.qq.com/";
        $opt = [
            'http'=>[
                'header'=>"Referer: " . $refer,
                "Connection:" => "close"
            ]
        ];
        $context = stream_context_create($opt);
        //接受数据流
        $file_contents = file_get_contents($url,false, $context);
        $imageSteam =  Imagecreatefromstring($file_contents);
        $path = 'article/';
        //if(!file_exists($path))
        //mkdir($path,0777,true);
        //$fileName = time().rand(0,99999) . '.jpg';
        //生成新图片
        //imagejpeg($imageSteam, $path . $fileName);
        return base64_encode($file_contents);
    }
}


ini_set('default_socket_timeout', 1);

$url = $_GET['url'];
$crawler = new WxCrawler();
$content = $crawler->crawByUrl($url);

echo json_encode($content);
?>

使用JS调用 axios.get('crawler.php?url=<?=$rs['url']?>')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值