python 获取微信公众号的文章(持续更新)

需求场景:关注很多的微信公众号,有时候看到很好的文章,过段时间再想查看下,发现找不到历史的文章记录了,也没有一个根据文章名称检索的地方。现在利用python爬虫爬取微信公众号的文章,数据存入到数据库中。可以定时读取微信公众号的最新文章,方便日后的读取和查询。

实现思路:通过微信公众号登录获取想要的微信公众好的fakeid,token和cookie(token和cookie是每天更新的,这个目前还没有实现自动获取,后续更新会继续)。现将步骤和代码奉上

步骤一:登录微信公众号获取token和cookie,fakeid

登录微信公众--创作管理--图文素材

步骤二:通过代码获取文章列表把数据存入mysql

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : articleCollection.py
# datetime:2020/11/5 10:58


import time
import random
import requests
import json
import pandas as pd
import mysql
from cookie import getCookie, getFakeId


# 毫秒数转日期
def getDate(times):
    # print(times)
    timearr = time.localtime(times)
    date = time.strftime("%Y-%m-%d %H:%M:%S", timearr)
    return date


def listAllArticle(fakeId):
    # with open('cookie.txt', 'r', encoding='utf-8') as f:
    #     cookie = f.read()
    # cookies = json.loads(cookie)
    # 目标url
    url = "https://mp.weixin.qq.com/cgi-bin/appmsg"
    # 使用Cookie,跳过登陆操作
    headers = {
        "Cookie": "appmsglist_action_3253322613=card; pgv_pvi=1927635968; RK=qb4RrLzDY3; ptcz=8e89a2e6f2a59b1a3f8a0f31ddac1c9377a330495aa98d6782318128d951fbde; pgv_pvid=3216855634; o_cookie=876860131; pac_uid=1_876860131; sd_userid=48741598419620498; sd_cookie_crttime=1598419620498; ua_id=HyCPg850LnH9CM3IAAAAAERZlptrn4Ugx5qlWDhDiUk=; mm_lang=zh_CN; openid2ticket_oFz_G00ma08fbv-hIlBEH6O6q6fE=; noticeLoginFlag=1; openid2ticket_oYj8c00Jx-5q4pqWDv11SI2X5ofc=; openid2ticket_oiYgP0Uqf2UZrNA391GmMDwJGcCE=; openid2ticket_ojB5L5CfumKlgHCgLAklgd5KEx4Y=; wxuin=03948109754498; remember_acct=463451476%40qq.com; ts_uid=611546807; openid2ticket_oVOWI5PW7Zm4a3wtuO1qNGNvoz-c=; luin=o0876860131; lskey=000100000766fb94649b295f405b49b4fccf586695f86fce7607f4d8ae57d26bbcb0301dbbf27c6270924611; openid2ticket_ooIDA4uHEZzqbrxbGu9AbKC12u-Q=; pgv_si=s1613571072; uuid=2e283eb009db08eaf4670f9242d7552f; rand_info=CAESIALz/RAVT8BuYAVfLpMNUKBAqgZZl6Edk1INJYS1j5AJ; slave_bizuin=3253322613; data_bizuin=3236413511; bizuin=3253322613; data_ticket=gU6uFdhksZuwfq6BMxYWp1PTkqrSZbknRl67RSBCVqcR65/ypmY41ldD5fsQ5/F0; slave_sid=Q3lsZHBsZ0JaQTdwV1gwMlpVSkU4dTBRRng2aVZJUXdPbDJrc0FNUWFXZ011VnRqVlZ1Z28xektlZzdfZGc2Wlo3VDV4R1h3NjY5dWJKZDRZTmNRV1NRQzdJNUR6UDBHQWVRVGRZcWIyTExCbkdDSURHYUdFT0FaVE9mazBPNDB0MUpGdkJFZHlUeUpNWFBs; slave_user=gh_142dc657372c; xid=6a58b8adab44b39b8aa19a7fb675f9c9; openid2ticket_oR8DnwJPMyNDbpsKFzdTxkqtKcmk=aXPZY0GRnsCCNvQJDcRjByPJv4/HgJg1agmjuL8MlQk=",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36",
    }
    data = {
        "token": "379017573",
        "lang": "zh_CN",
        "f": "json",
        "ajax": "1",
        "action": "list_ex",
        "begin": "0",
        "count": "5",
        "query": "",
        "fakeid": fakeId,
        "type": "9",
    }
    for i in range(2):
        data["begin"] = i * 5
        # 生成3-10的随机整数,方便下面程序间隔时间
        sleepTime = random.randint(3, 10)
        print(sleepTime)
        time.sleep(sleepTime)
        content_json = requests.get(url, headers=headers, params=data).json()
        for item in content_json["app_msg_list"]:
            # 提取每页文章的标题及对应的url
            items = [item["title"], item["link"], item["cover"], getDate(item["create_time"]), item["digest"],
                     item["item_show_type"], getDate(item["update_time"]), ''.join(fakeId)]
            print(items)
            mysql.saveWeChatArticle(items)


if __name__ == '__main__':
    listFakeId = mysql.listWeChatFilId()
    for i in listFakeId:
        print(''.join(i))
        listAllArticle(i)

从mysql中查询faikid和把文章列表存入mysql

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : mysql.py
# datetime:2020/11/5 10:44
import pymysql

from dbutils.pooled_db import PooledDB

POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
    maxshared=3,
    # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
    maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
    setsession=[],  # 开始会话前执行的命令列表。
    ping=0,
    # ping MySQL服务端,检查是否服务可用。
    host='10.63.4.53',
    port=20318,
    user='root',
    password='f608a3fd',
    database='sy_jzfp',
    charset='utf8'
)


def func():
    # 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常
    # 否则 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
    # 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
    # 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
    # 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
    conn = POOL.connection()

    # print(th, '链接被拿走了', conn1._con)
    # print(th, '池子里目前有', pool._idle_cache, '\r\n')

    cursor = conn.cursor()
    cursor.execute('select * from two_clour_two')
    result = cursor.fetchall()
    for i in result:
        print(i)
    conn.close()


# 数据库插入操作
def saveDouBan(dict):
    conn = POOL.connection()
    cursor = conn.cursor()
    sql = "insert into two_clour_two (`code`, `red_1`, `red_2`, `red_3`, `red_4`, `red_5`, `red_6`, `blue`,`sum`,`std`,`var`,`create_date`) values(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")" % (
        str(dict[0]), str(dict[1]), str(dict[2]), str(dict[3]), str(dict[4]), str(dict[5]), str(dict[6]),
        str(dict[7]), str(dict[8]), str(dict[9]), str(dict[10]), str(dict[11]))
    cursor.execute(sql)
    print('Successful')
    conn.commit()
    cursor.close()


# 数据库插入操作
def saveWeChatArticle(dict):
    # name = ['title', 'link', 'cover', 'create_time', 'digest', 'item_show_type', 'update_time', 'fakeid']
    conn = POOL.connection()
    cursor = conn.cursor()
    sql = "insert into we_chat_article (`title`, `link`,`cover`, `create_time`, `digest`, `item_show_type`, `update_time`, `fakeid`) values(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")" % (
        pymysql.escape_string(dict[0]), str(dict[1]), str(dict[2]),
        str(dict[3]), str(dict[4]), str(dict[5]),
        str(dict[6]), str(dict[7]))
    cursor.execute(sql)
    # print('Successful')
    conn.commit()
    cursor.close()


def listWeChatFilId():
    conn = POOL.connection()
    cursor = conn.cursor()
    cursor.execute("select fake_id from wechat_public where del_flag ='0' ")
    result = cursor.fetchall()
    # for i in result:
    #     print(i[0])
    conn.close()
    return result


if __name__ == '__main__':
    listWeChatFilId()

 

执行效果和结果如下

 

后记:改方法目前存在问题如如下:

1、不能实现自动的获取token和faikid;每天需要手动获取;

2、定时任务还没有加,获取的文章有一些重复的(目前的做法是取前两页列表的数据,重复的没有判断)

3、获取条数过多会被腾讯封IP;

4、后面会把数据接入微信小程序中。

这个是自己目前开发的一个app还不成熟

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值