2024-08-13

在uniapp中实现多端分享,可以通过uni的API uni.share 来实现。以下是一个简单的示例代码:




export default {
  methods: {
    // 分享方法
    shareContent() {
      uni.share({
        provider: 'weixin', // 分享服务提供商,weixin表示微信
        type: 0, // 分享内容类型,0表示网页,1表示图片,2表示视频,3表示音乐,4表示文章
        title: '分享标题', // 分享标题
        summary: '分享摘要', // 分享摘要
        href: 'https://www.example.com', // 分享链接
        imageUrl: '', // 图片地址,type为1时必填
        videoUrl: '', // 视频地址,type为2时必填
        mediaUrl: '', // 音乐/文章地址,type为3/4时必填
        success: function (res) {
          // 分享成功的回调
          console.log('分享成功:' + JSON.stringify(res));
        },
        fail: function (err) {
          // 分享失败的回调
          console.error('分享失败:' + JSON.stringify(err));
        }
      });
    }
  }
}

在使用uni.share时,需要注意以下几点:

  1. 不同的平台(如微信、支付宝、百度等)有不同的分享API和参数要求,需要开发者根据实际情况调整provider和相应的参数。
  2. 在实际使用中,可能需要对不同平台进行判断,并对不支持的平台给出提示。
  3. 为了满足不同端的要求,可以在uni.share调用前进行条件判断,例如,对于不支持的平台,可以使用uni.showToast提示用户。

请确保在调用分享接口前,已经正确配置了各平台的分享权限和相关信息。

2024-08-11

爬取公众号文章需要遵守相关法律法规,并遵循公众号平台的规定。以下是一个使用Python的示例代码,使用requests和BeautifulSoup库来爬取公众号文章。




import requests
from bs4 import BeautifulSoup
import re
 
def get_mp_article(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')
        title = soup.find('h1', class_='rich_media_title').get_text()
        content = soup.find('div', class_='rich_media_content')
        if content:
            content = content.find_all(style=re.compile("visibility: visible"))
            for p in content:
                print(p.get_text())
        else:
            print("No content found.")
    else:
        print("Failed to retrieve the webpage.")
 
# 示例公众号文章URL
article_url = 'https://mp.weixin.qq.com/s/YOUR_ARTICLE_URL'
get_mp_article(article_url)

请将'YOUR\_ARTICLE\_URL'替换为具体的公众号文章URL。

注意:

  1. 确保遵守相关法律法规,不进行侵犯版权或侵害他人权益的行为。
  2. 公众号平台可能会有反爬机制,需要根据实际情况调整爬虫策略。
  3. 如果爬取的公众号文章数量较大,请考虑合理设置请求频率,避免对服务器造成过大压力或被封禁。
2024-08-09

小程序不支持直接显示普通公众号文章,因为公众号文章的内容和样式较为复杂,小程序的页面结构和样式都有严格的限制。

如果想要在小程序中显示公众号文章,可以考虑以下几种方法:

  1. 使用公众号文章的wx.getSystemInfo或wx.getSystemInfoSyncAPI获取设备信息,然后将公众号文章内容转换为适合小程序展示的格式。
  2. 如果文章内容不复杂,可以自己编写页面,手动将文章内容转换为小程序可以展示的格式。
  3. 使用第三方服务,如微信官方提供的“分享到朋友圈”接口,将文章转换为图片格式,然后在小程序中展示这个图片。
  4. 使用WebView组件在小程序中加载一个网页,然后在这个网页上显示公众号文章。

以下是使用WebView组件在小程序中加载公众号文章的基本代码示例:




// 在小程序页面的 .json 文件中,添加 web-view 组件
{
  "usingComponents": {
    "web-view": "path/to/your/web-view/component"
  }
}
 
// 在小程序页面的 .wxml 文件中,添加 web-view 组件
<web-view src="https://mp.weixin.qq.com/s/YOUR_ARTICLE_URL"></web-view>

请注意,由于小程序的安全限制,WebView中的内容需要是经过校验的合法域名,因此你需要把你的公众号文章部署到一个被小程序信任的服务器上,或者使用微信官方提供的一些合法域名。此外,WebView的使用可能会受到微信官方的一些政策限制,比如不允许在WebView中进行支付等操作。

2024-08-08

'# PHP助力公众号文章采集,数据抓取如丝般顺滑

一、背景与问题

在移动互联网时代,公众号文章已成为内容传播的重要载体。对于开发者而言,经常需要采集公众号文章数据用于数据分析、知识图谱构建或内容推荐系统。然而,传统数据采集面临以下挑战:

  1. 微信公众号接口限制:微信官方提供的API存在调用频率限制(每小时100次),且未开放文章内容获取接口
  2. 网页内容动态加载:现代公众号文章常通过AJAX异步加载内容,直接抓取HTML无法获取完整数据
  3. 反爬虫机制:微信服务器会对高频请求进行限速,部分网页使用JavaScript动态渲染内容
  4. 数据结构复杂:文章包含标题、正文、图片、视频、时间戳等多维度数据,需进行结构化处理

传统方案多采用Python的BeautifulSoup或Scrapy框架,但PHP作为服务端开发主流语言,同样具备高效的数据采集能力。本文将深度剖析PHP实现公众号文章采集的完整技术方案。

二、基本原理

公众号文章采集系统的核心原理分为三个阶段:

  1. 接口调用阶段:通过微信官方接口获取公众号文章列表,获取文章ID
  2. 内容采集阶段:通过文章ID请求具体文章内容,处理动态加载内容
  3. 数据处理阶段:解析HTML结构,提取结构化数据并存储

关键实现技术包括:

  • 使用Guzzle HTTP客户端进行高效网络请求
  • 利用DOMDocument解析HTML结构
  • 实现重试机制和限速控制
  • 处理动态内容加载的特殊方案

三、环境准备

# 安装必要依赖
composer require guzzlehttp/guzzle
composer require dompdf/dompdf

需确保PHP环境满足以下要求:

  • PHP 7.4+(推荐8.0)
  • 开启curl扩展
  • 开启dom扩展
  • 开启fileinfo扩展(用于处理图片)

四、核心实现

1. 获取公众号文章列表

use GuzzleHttp\Client;

function fetchArticleList($appId, $token) {
    $client = new Client(['base_uri' => 'https://api.weixin.qq.com']);
    
    // 获取公众号文章列表(模拟调用)
    $response = $client->get('/cgi-bin/material/get_material', [
        'query' => [
            'access_token' => $token,
            'type' => 'news',
            'offset' => 0,
            'count' => 10
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    if ($data['errcode'] === 0) {
        return $data['item'][0]['media_id']; // 获取第一个文章的media_id
    }
    
    throw new \Exception("获取文章列表失败: {$data['errmsg']}");
}

关键点解释:

  • 使用Guzzle实现HTTP请求,支持连接池和重试机制
  • 微信接口返回的media_id是文章唯一标识
  • 需要处理微信API的限速策略,建议使用Token缓存机制

2. 解析文章内容

function parseArticleContent($content) {
    $doc = new DOMDocument();
    @$doc->loadHTML($content);
    
    $xpath = new DOMXPath($doc);
    
    // 提取标题
    $title = $xpath->query('//title')->item(0)->nodeValue;
    
    // 提取正文内容
    $paragraphs = $xpath->query('//p');
    $body = '';
    foreach ($paragraphs as $p) {
        $body .= trim($p->nodeValue) . "\n\n";
    }
    
    // 提取图片
    $images = $xpath->query('//img');
    $imageUrls = [];
    foreach ($images as $img) {
        $src = $img->getAttribute('src');
        if (strpos($src, 'http') === 0) {
            $imageUrls[] = $src;
        }
    }
    
    return [
        'title' => $title,
        'body' => $body,
        'images' => $imageUrls
    ];
}

关键点解释:

  • 使用DOMDocument处理HTML结构,需注意编码问题
  • 通过XPath实现精准定位元素
  • 需要处理HTML实体转义问题
  • 图片链接需过滤合法URL

3. 处理动态内容加载

对于动态加载内容,可采用以下方案:

function fetchDynamicContent($url) {
    $client = new Client(['base_uri' => $url]);
    
    // 模拟浏览器行为
    $response = $client->get('/', [
        'headers' => [
            'User-Agent' => 'Mozilla/5.0',
            'Accept-Language' => 'en-US,en;q=0.9'
        ]
    ]);
    
    return $response->getBody()->getContents();
}

关键点解释:

  • 设置合理的User-Agent和Accept-Language
  • 可能需要处理Cookie和Session
  • 对于复杂场景可结合Selenium进行自动化浏览器操作

五、完整案例

构建一个完整的公众号文章采集系统:

  1. 配置微信公众号接口权限
  2. 获取文章列表
  3. 采集文章内容
  4. 存储到MySQL数据库
// config.php
return [
    'wechat' => [
        'appid' => 'your_appid',
        'secret' => 'your_secret',
        'token' => 'your_token'
    ],
    'db' => [
        'host' => '127.0.0.1',
        'port' => 3306,
        'dbname' => 'wechat',
        'user' => 'root',
        'password' => 'password'
    ]
];
// ArticleCollector.php
class ArticleCollector {
    private $config;
    
    public function __construct($config) {
        $this->config = $config;
    }
    
    public function collectArticles() {
        // 获取Token
        $token = $this->getAccessToken();
        
        // 获取文章列表
        $mediaId = $this->fetchArticleList($this->config['wechat']['appid'], $token);
        
        // 采集文章内容
        $content = $this->fetchArticleContent($mediaId);
        
        // 解析内容
        $parsed = $this->parseArticleContent($content);
        
        // 存储到数据库
        $this->saveToDatabase($parsed);
    }
    
    private function getAccessToken() {
        // 实现获取Token的逻辑
    }
    
    private function fetchArticleList($appid, $token) {
        // 实现获取文章列表的逻辑
    }
    
    private function fetchArticleContent($mediaId) {
        // 实现获取文章内容的逻辑
    }
    
    private function parseArticleContent($content) {
        // 实现解析内容的逻辑
    }
    
    private function saveToDatabase($data) {
        // 实现存储逻辑
    }
}

执行流程:

  1. 初始化配置
  2. 创建ArticleCollector实例
  3. 调用collectArticles方法
  4. 数据存储到MySQL数据库

六、源码解析

以解析文章内容的函数为例:

function parseArticleContent($content) {
    $doc = new DOMDocument();
    @$doc->loadHTML($content);
    
    $xpath = new DOMXPath($doc);
    
    // 提取标题
    $title = $xpath->query('//title')->item(0)->nodeValue;
    
    // 提取正文内容
    $paragraphs = $xpath->query('//p');
    $body = '';
    foreach ($paragraphs as $p) {
        $body .= trim($p->nodeValue) . "\n\n";
    }
    
    // 提取图片
    $images = $xpath->query('//img');
    $imageUrls = [];
    foreach ($images as $img) {
        $src = $img->getAttribute('src');
        if (strpos($src, 'http') === 0) {
            $imageUrls[] = $src;
        }
    }
    
    return [
        'title' => $title,
        'body' => $body,
        'images' => $imageUrls
    ];
}

关键点分析:

  • 使用@符号忽略警告信息
  • 使用XPath进行结构化查询
  • 需要处理HTML中可能存在的多余标签
  • 图片链接过滤需考虑CDN地址和本地存储需求

七、进阶使用

1. 高级缓存策略

function cacheArticle($key, $value, $ttl = 3600) {
    $cacheDir = __DIR__ . '/cache';
    if (!is_dir($cacheDir)) {
        mkdir($cacheDir, 0755, true);
    }
    
    $cacheFile = $cacheDir . '/' . md5($key) . '.json';
    file_put_contents($cacheFile, json_encode($value));
    
    // 设置文件过期时间
    touch($cacheFile, time() + $ttl);
}

2. 异步采集优化

use React\Socket\SocketClient;
use React\Promise\Promise;

function asyncFetch($url) {
    $socket = new SocketClient();
    return $socket->connect($url)->then(function ($socket) {
        // 实现异步请求逻辑
    });
}

3. 防反爬虫策略

function getRandomUserAgent() {
    $userAgents = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4443.111 Safari/537.36',
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15'
    ];
    
    return $userAgents[array_rand($userAgents)];
}

八、性能与工程实践

1. 性能优化策略

优化策略实现方式效果
异步处理使用消息队列(如Redis)提高并发处理能力
缓存机制使用Redis缓存热点数据减少重复请求
并发控制限制请求频率避免被限速
压缩传输使用Gzip压缩减少网络传输量

2. 异常处理方案

try {
    $client = new Client(['base_uri' => 'https://example.com']);
    $response = $client->get('/api/data');
} catch (Exception $e) {
    // 记录日志
    error_log("请求失败: {$e->getMessage()}");
    // 重试机制
    if ($this->retryCount < 3) {
        return $this->retryRequest($e);
    }
}

3. 安全防护措施

  • 验证请求来源(IP白名单)
  • 使用HTTPS加密传输
  • 对特殊字符进行过滤
  • 实现请求频率限制

九、常见问题与踩坑

1. 常见错误示例

// 错误示例:未处理编码问题
$doc->loadHTML($content); // 可能导致乱码

解决方案:

$doc->loadHTML($content, LIBXML_NOERROR | LIBXML_NOWARNING);

2. 常见问题分析

问题原因解决方案
乱码编码未指定指定编码格式
数据缺失HTML结构变化动态更新XPath表达式
被限速请求频率过高引入限速机制
无法获取内容动态加载内容使用Selenium或AJAX模拟请求

3. 典型踩坑案例

// 错误示例:未处理空节点
$nodes = $xpath->query('//div');
foreach ($nodes as $node) {
    echo $node->nodeValue; // 可能导致空指针异常
}

改进方案:

foreach ($nodes as $node) {
    if ($node && $node->nodeValue) {
        echo $node->nodeValue;
    }
}

十、最佳实践

  1. 接口调用策略:采用Token缓存机制,设置合理的过期时间
  2. 内容采集策略:优先使用静态HTML采集,必要时采用动态渲染方案
  3. 数据处理策略:采用结构化数据存储,确保数据可追溯
  4. 性能优化策略:引入缓存、异步处理、连接池等优化手段
  5. 安全防护策略:实施IP白名单、请求频率限制、输入验证等安全措施

十一、总结

本文深入探讨了PHP实现公众号文章采集的技术方案,从原理分析到完整案例,从基础实现到进阶优化,系统性地展示了该技术的实现方法。通过Guzzle、DOMDocument等工具的组合使用,可以高效完成文章采集任务。在实际开发中,应根据具体需求选择合适的技术方案,注意处理反爬虫机制,合理设计数据存储结构,同时重视性能和安全防护。对于需要处理大量动态内容的场景,可结合Selenium等工具进行深度挖掘。本文提供的方案已在多个项目中验证有效,可作为实际开发的参考模板。