Contents

爬取微信公众号文章

步骤

  1. 使用 Fiddler 抓取公众号接口数据
  2. 使用 Python 脚本获取公众号所有历史文章数据
  3. 保存历史文章

Fiddler 抓包

  • 使用微信桌面客户端,打开某个公众号的历史文章,这里以我的公众号举例,如下图。

    https://gitee.com/chen-zq/bgimages/raw/master/img/20200904175325.png?imgslim

  • fiddler 配置没问题,能够看到如下图的数据

    https://gitee.com/chen-zq/bgimages/raw/master/img/20200904175541.png?imgslim

    https://gitee.com/chen-zq/bgimages/raw/master/img/20200904175926.png?imgslim

图中包含抓取的 url、一些重要的参数和我们想要的数据。

这些参数中,offset 控制着翻页,其他参数在每一页中都是固定不变的。

接口返回的数据结构如下图,其中 can_msg_continue 字段控制着能否翻页,1 表示还有下一页,0 表示没有已经是最后一页了。 next_offset 字段就是下一次请求的 offset 参数

构造请求,获取数据

使用 pdfkit 将 文章 url 保存为 pdf 文件;另一种是先保存 html 文件,然后将 html 制作成 chm 文件。保存为 pdf 文件,用到了 python 的第三方库 pdfkit 和 wkhtmltopdf

  1. 安装第三方工具包

    安装 pdfkit:

    pip install pdfkit

    安装 wkhtmltopdf

    下载地址

  2. 程序

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import time, json
    import pdfkit, requests
    
    index = 0
    can_msg_continue = 1
    file_name = '公众号PDF数据'
    
    __biz = ''
    uin = ''
    key = ''
    
    def parse():
        global index
    
        print('第 %s 页' % (index))
        # url前缀
        url = "https://mp.weixin.qq.com/mp/profile_ext"
    
        # 请求头
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 "
                        "Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 "
                        "QQBrowser/9.0.2524.400",
        }
        proxies = {
            'https': None,
            'http': None,
        }
    
        # 重要参数
        param = {
            'action': 'getmsg',
            '__biz': __biz,
            'f': 'json',
            'offset': index * 10,
            'count': '10',
            'is_ok': '1',
            'scene': '124',
            'uin': uin,
            'key': key,
            'wxtoken': '',
            'x5': '0',
        }
        # 发送请求,获取响应
        response = requests.get(url, headers=headers, params=param, proxies=proxies)
        response_dict = response.json()
    
        next_offset = response_dict['next_offset']
        can_msg_continue = response_dict['can_msg_continue']
    
        general_msg_list = response_dict['general_msg_list']
        data_list = json.loads(general_msg_list)['list']
    
        for data in data_list:
            # 文章发布时间
            datetime = data['comm_msg_info']['datetime']
            date = time.strftime('%Y-%m-%d', time.localtime(datetime))
    
            try:
                msg_info = data.get('app_msg_ext_info')
                msg_list = msg_info.get('multi_app_msg_item_list')
            except Exception as e:
                print("ERRMSG:::", e)
            else:
                # 文章标题
                title = msg_info['title']
                # 文章链接
                url = msg_info['content_url']
    
                options = {
                    'page-size': 'A4',
                    'margin-top': '0mm',
                    'margin-right': '0mm',
                    'margin-bottom': '0mm',
                    'margin-left': '0mm',
                    # 'orientation':'Landscape',#横向
                    'encoding': "UTF-8",
                    'no-outline': None,
                    # 'footer-right':'[page]' 设置页码
                }
                try:
                    # 设置wkhtmltopdf的路径
                    config = pdfkit.configuration(wkhtmltopdf='D:\\Program Files\wkhtmltopdf\\bin\\wkhtmltopdf.exe')
                    # 自己定义存储路径(绝对路径)
                    pdfkit.from_url(url, 'E:/service/数据文件/' + file_name + '/' + date + title + '.pdf', configuration=config)
                except Exception as e:
                    print('ERRMSG:::', e)
                    print("不是图文消息")
                else:
                    print(date + title + '成功')
    
                #
                if msg_list:
                    for data in msg_list:
                        title = data['title']
                        url = data['content_url']
                        try:
                            # 设置wkhtmltopdf的路径
                            config = pdfkit.configuration(wkhtmltopdf='D:\\Program Files\wkhtmltopdf\\bin\\wkhtmltopdf.exe')
                            # 自己定义存储路径(绝对路径)
                            pdfkit.from_url(url, 'E:/service/数据文件/' + file_name + '/' + date + title + '.pdf', configuration=config)
                        except Exception as e:
                            print('ERRMSG:::', e)
                            print("不是图文消息")
                        else:
                            print(date + title + '成功')
    
        if can_msg_continue == 1:
            index += 1
            parse()
            pass
    
        else:
            print('第 %s 页爬取完毕' % (index))
            return False
    
  3. 效果

    https://gitee.com/chen-zq/bgimages/raw/master/img/20200904181205.png?imgslim

    https://gitee.com/chen-zq/bgimages/raw/master/img/20200904181303.png?imgslim