pursue wind pursue wind
首页
Java
Python
数据库
框架
Linux
中间件
前端
计算机基础
DevOps
项目
面试
书
关于
归档
MacOS🤣 (opens new window)
GitHub (opens new window)
首页
Java
Python
数据库
框架
Linux
中间件
前端
计算机基础
DevOps
项目
面试
书
关于
归档
MacOS🤣 (opens new window)
GitHub (opens new window)
  • 基于Python轻松自建App服务器

  • 基于Python实现微信公众号爬虫

    • 0微信公众号爬虫的基本原理
    • 1使用 Requests 实现一个简单网页爬虫
    • 2使用 Fiddler 抓包分析公众号请求过程
    • 3抓取微信公众号第一篇文章
    • 4抓取微信公众号所有历史文章
    • 5将爬取的文章存储到MongoDB
      • 6获取文章阅读数、点赞数、评论数、赞赏数
      • 7搭建数据分析环境:Anaconda、Jupyter Notebook(1)
      • 8利用 Pandas 对爬取数据进行分析
      • 9基于 Matplotlib 实现数据可视化展示
      • 10小结
    • Xpath
    • python3 翻译
    • python3循环创建数据库表
    • python实用30个小技巧
    • pywin32
    • Python
    • 基于Python实现微信公众号爬虫
    pursuewind
    2020-11-23
    目录

    5将爬取的文章存储到MongoDB

    # 将爬取的文章存储到MongoDB

    关于数据的存储有很多选择,最简单的方式就是直接保存到 CSV 文件中,这种方式操作简单,适合数据量少的情况,Python的标准库 csv 模块就可以直接支持。如果遇到数据量非常大的情况,就必须要用到专业的数据库系统,你既可以使用 MySQL 这样的关系型数据库,也可以使用 MongoDB 一类的文档型数据库。用Python 操作 MongoDB 非常方便,无需定义表结构就可以直接将数据插入,所以我们在这一节采用 MongoDB 来存储数据。

    # MongoDB 安装

    MongoDB 目前最新版本是3.6,在官网地址https://www.mongodb.com/download-center#community (opens new window)选择相应平台下载安装。

    Windows 默认安装在 C:\Program Files\MongoDB\Server\3.6\,macOS 也可以直接通过 brew 命令安装,Linux平台直接下载压缩包解压即可。

    brew install mongodb --with-openssl
    
    1

    # 启动 MongoDB

    mongod --dbpath <path to data directory> 
    
    1

    默认端口是 27017,为了更好的查看数据,我们可以装一个 MongoDB 客户端, 官方自带有 compass,也可以下载第三方工具 Robo 3T https://robomongo.org/ (opens new window),这里推荐大家使用免费的 Robo 3T。

    # MongoEngine

    MongoEngine 是 MongoDB 的 DOM(Document-Object Mapper)框架,一种类似于关系型数据库中的ORM框架 ,使用它可以更方便并写出简洁的代码

    安装

    $ pip install mongoengine
    
    1

    连接

    from mongoengine import connect
    # 连接 mongodb,无需事先创建数据库
    connect('weixin', host='localhost', port=27017)
    
    1
    2
    3

    定义数据模型

    # -*- coding: utf-8 -*-
    from datetime import datetime
    
    from mongoengine import DateTimeField
    from mongoengine import Document
    from mongoengine import IntField
    from mongoengine import StringField
    from mongoengine import URLField
    from mongoengine import connect
    
    __author__ = "liuzhijun"
    
    # 连接 mongodb
    connect('weixin2', host='localhost', port=27017)
    
    
    class Post(Document):
        """
        文章信息
        """
        title = StringField()  # 文章标题
        content_url = StringField()  # 文章链接
        content = StringField()  # 文章内容
        source_url = StringField()  # 原文链接
        digest = StringField()  # 文章摘要
        cover = URLField(validation=None)  # 封面图
        p_date = DateTimeField()  # 推送时间
    
        read_num = IntField(default=0)  # 阅读数
        like_num = IntField(default=0)  # 点赞数
        comment_num = IntField(default=0)  # 评论数
        reward_num = IntField(default=0)  # 赞赏数
        author = StringField()  # 作者
    
        c_date = DateTimeField(default=datetime.now)  # 数据生成时间
        u_date = DateTimeField(default=datetime.now)  # 最后更新时间
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    # 数据保存

    在第五小节中,我们只是把抓取的数据简单的打印出来,现在我们就把它存数据库,因为抓取的数据中有很多无用的字段,所以,这里我们写一个工具函数叫 sub_dict 用于获取指定字段信息。

    import html
    def sub_dict(d, keys):
        return {k: html.unescape(d[k]) for k in d if k in keys}
    
    d = {"a": "1", "b": 2, "c": 3}
    sub_dict(d, ["a", "b"]) # {"a":"1", "b": "2"}
    
    1
    2
    3
    4
    5
    6

    获取字典的子字典可以用字典推导式实现,我这里还导入了html.unescape方法是希望保存到数据库的数据都是经过反转义处理的。

        @staticmethod
        def save(msg_list):
    
            msg_list = msg_list.replace("\/", "/")
            data = json.loads(msg_list)
            msg_list = data.get("list")
            for msg in msg_list:
                p_date = msg.get("comm_msg_info").get("datetime")
                msg_info = msg.get("app_msg_ext_info")  # 非图文消息没有此字段
                if msg_info:
                    WeiXinCrawler._insert(msg_info, p_date)
                    multi_msg_info = msg_info.get("multi_app_msg_item_list") # 多图文推送,把第二条第三条也保存
                    for msg_item in multi_msg_info:
                        WeiXinCrawler._insert(msg_item, p_date)
                else:
                    logger.warning(u"此消息不是图文推送,data=%s" % json.dumps(msg.get("comm_msg_info")))
    
        @staticmethod
        def _insert(item, p_date):
            keys = ('title', 'author', 'content_url', 'digest', 'cover', 'source_url')
            sub_data = utils.sub_dict(item, keys)
            post = Post(**sub_data)
            p_date = datetime.fromtimestamp(p_date)
            post["p_date"] = p_date
            logger.info('save data %s ' % post.title)
            try:
                post.save()
            except Exception as e:
                logger.error("保存失败 data=%s" % post.to_json(), exc_info=True)
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    如果是文字推送就没有app_msg_ext_info字段,无需保存,multi_app_msg_item_list是多图文推送字段,而且和外层的app_msg_ext_info字段是一致的,有标题、封面图、摘要、链接等信息,所以我们把插入数据库的代码_insert作为私有方法抽离出来共用。

    最后我们看一下保存的数据。

    # 小结

    本节完成代码在GitHub v0.3 (opens new window),这小节我们主要熟悉 Mongodb 的安装以及如何用Python连接 Mongodb 进行数据存储,推荐两个资源,第一个是:《MongoDB 入门指南》 (opens new window),第二个是 MongoEngine 教程 (opens new window),如果你想进行系统的学习 MongoDB,推荐两本书籍《MongoDB权威指南》和《MongoDB实战》。

    Last Updated: 2023/02/14, 18:02:00
    4抓取微信公众号所有历史文章
    6获取文章阅读数、点赞数、评论数、赞赏数

    ← 4抓取微信公众号所有历史文章 6获取文章阅读数、点赞数、评论数、赞赏数→

    Theme by Vdoing | Copyright © 2019-2023 pursue-wind | 粤ICP备2022093130号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    • 飙升榜
    • 新歌榜
    • 云音乐民谣榜
    • 美国Billboard榜
    • UK排行榜周榜
    • 网络DJ