获取微博排行榜PHP

时间:2024-10-24 13:04:19

获取微博排行榜是获取微博html页面的数据,而非直接调用微博后端接口获取

PHP实现

class WeiBoHotSearchService extends BaseService
{
    /**
     * 微博热搜缓存过期时间
     * @var int
     */
    protected int $expireTime = 600;

    /**
     * 微博热搜URL
     * @var string
     */
    protected string $domainUrl = 'https://s.weibo.com';

    /**
     * URL内容
     * @var mixed|null
     */
    protected mixed $output = null;


    /**
     * 热搜列表
     * @var array
     */
    protected array $hotSearchList = [];

    /**
     * 缓存key
     * @var string
     */
    protected string $key = 'WEIBO_HOT_SEARCH_LIST_CACHE';

    /**
     * 微博热搜Cookie
     * @var string
     */
    protected string $cookie = 'SUB=1;_s_tentry=weibo.com;';


    /**
     * 微博热搜url
     * @var string
     */
    protected string $url = 'https://s.weibo.com/top/summary?cate=realtimehot';

    /**
     * 获取微博热搜列表缓存
     * @return array|array[]|mixed
     */
    public function getWeiBoHotSearchListCache()
    {
        $str = RedisUtil::getInstance()->get($this->key);
        if (!empty($str)) {
            return json_decode($str, true);
        } else {
            return $this->refreshWeiboHotSearch();
        }
    }

    /**
     * 刷新微博热搜列表缓存
     * @return array|array[]
     */
    public function refreshWeiboHotSearch()
    {
        try {
            $output = HttpUtil::getInstance()->getUrlContent($this->url, $this->cookie);
            // 获取html元素中table表格
            preg_match_all('/<table>[\s\S]*?<\/table>/i', $output, $match);
            // 获取table表格
            $table = $match[0][0];
            // 去除table标签
            $table = preg_replace("'<table[^>]*?>'si", "", $table);
            // 去除tr标签
            $table = preg_replace("'<tr[^>]*?>'si", "", $table);
            // 去除td标签
            $table = preg_replace("'<td[^>]*?>'si", "", $table);
            // 将tr标签替换为{tr}
            $table = str_replace("</tr>", "{tr}", $table);
            // 将td标签替换为{td}
            $table = str_replace("</td>", "{td}", $table);
            //去掉剩余HTML元素并将<a>标签保留是为了拿到跳转链接
            $table = preg_replace("/<(?!a\b|\/a\b)[^>]*>/i", "", $table);
            //去掉空白字符
            $table = preg_replace("'([rn])[s]+'", "", $table);
            // 去除空格
//        $table = str_replace(" ", "", $table);
            // 将table标签按照{tr}拆分
            $table = explode('{tr}', $table);
            foreach ($table as $key => $value) {
                // 自己可添加对应的替换
                $tr = str_replace("\n", "", $value);
                // 去除数组中的<!--{td}-->
                $tr = preg_replace("<!--{td}-->", "", $tr);
                $td = explode('{td}', $tr);
                $td_array[] = $td;
            }
            // 删除数组第一项,删除数组最后一项
            array_shift($td_array);
            array_pop($td_array);
            // 处理数组
            $this->hotSearchList = array_map(function ($item) {
                // 第二项
                $item[1] = get_href_content_dom($item[1],$this->domainUrl);
                $item[2] = trim($item[2]);
                // 将二三项合并
                $item[1]['tip'] = $item[2];
                return $item[1];
            }, $td_array);
            Log::record("微博热搜获取数据成功" . json_encode($this->hotSearchList), 'info');
        } catch (Exception $e) {
            Log::record("微博热搜获取数据异常" . $e->getMessage(), 'error');
        }
        RedisUtil::getInstance()->set($this->key, json_encode($this->hotSearchList), $this->expireTime);
        return $this->hotSearchList;
    }
}

上面的RedisUtil就是一个工具类,其中只用了String类型的set和get方法

下期使用Python实现