微信公众号脚本-获取热搜自动新建草稿并发布文章

2025-04-05 15:50

本文主要是介绍微信公众号脚本-获取热搜自动新建草稿并发布文章,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众...

介绍

本来想写一个自动化发布微信公众号的小绿书的脚本。但是微信公众号官网没有小绿书的接口。

想着算了吧,写都写了,那就写一个微信普通文章的脚本吧。

写完了 就想着把脚本分享出来,给大家一起交流下。

水平有限,大佬轻喷。

2025-0226:

1,解决gitee不能开源问题,我把之前的库删除了,新建了个同名的库

2,新增微信公众号小绿书,自动发布草稿

3,新增小绿书,利用ai编写国家5A级景区 小绿书种草文章

4,小绿书跟普通文章的大致步骤一样,欢迎大家交流

2025-0320:

1,优化一些逻辑

2,新增保持56篇热搜文章,删除老的热搜文章

思路

1,获取百度热搜列表

2,给热搜图片加上文字标题

3,上传图片到微信公众号素材库

4,新建微信公众号草稿

5,发布草稿

前期准备

1,注册微信公众号,获取AppID和AppSecret

微信公众号脚本-获取热搜自动新建草稿并发布文章

2,微信公众号接口文档( 文档链接),参照文档进行接口调用

3,微信公众号设置IP白名单

服务器上面获取出口外网ip

curl -s https://ipinfo.io/ip

环境要求

1,我使用的是python12

2,依赖就需要安装PIL库,其他库都是默认安装的

(py12-ai-django5) [root@gtp-test01-cyt wxmp]# python -V
Python 3.12.4
# 

import requests
import os
import time
import yaml
import json
import string

javascriptfrom PIL import Image, ImageDraw, ImageFont
 
# 安装PIL
pip install pillow==10.4.0
 
# 运行脚本wxmp.py 就行
python wxmp.py

# 输出

# 输出
图片已保存到 hotimg/orgimg/2.png
图片已保存到 hotimg/orgimg/3.png
图片已保存到 hotimg/orgimg/4.png
图片已保存到 hotimg/orgimg/5.png
图片已保存到 hotimg/orgimg/6.jpg
图片已保存到 hotimg/orgimg/7.jpg
图片已保存到 hotimg/orgimg/8.png
图片已保存到 hotimg/orgimg/9.png
图片已保存到 hotimg/orgimg/10.jpg
图片已保存到 hotimg/orgimg/11.png
图片已加文字 hotimg/nowimg/2.png
图片已加文字 hotimg/nowimg/3.png
图片已加文字 hotimg/nowimg/4.png
图片已加文字 hotimg/nowimg/5.png
图片已加文字 hotimg/nowimg/6.jpg
图片已加文字 hotimg/nowimg/7.jpg
图片已加文字 hotimg/nowimg/8.png
图片已加文字 hotimg/nowimg/9.png
图片已加文字 hotimg/nowimg/10.jpg
图片已加文字 hotimg/nowimg/11.png
新建草稿成功--{'media_id': 'V4QdIouS1e-m5FaD0_0keQQMcEMKo0-3YjLoF_JqJohqywWC3Byyr81SXUi1TheO', 'item': []}
{'errcode': 0, 'errmsg': 'ok', 'publish_id': 2247483801, 'msg_data_id': 2247483801}

获取接口token

1,由于Access_token的有效期只有2小时,故需要定时刷新。

2,这里使用app_token.yaml来保存获取到的token以及时间;token在时效内返回保存的token,超过时效会获取新的token

def get_token(
        app_id='',  # 微信公众号AppID
        app_secret=''  # 微信公众号AppSecret
):
    """
    获取token
    :return:
    """
    url = f'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={app_id}&secret={app_secret}'
    res = requests.get(url=url)
    result = res.json()
    if result.get('access_token'):
        token = result['access_token']
        print(f"获取token成功:{token[:14]}****")
        return token
    else:
        print(f"获取token失败--{result}")


def refresh_token():
    """
    token刷新机制
    :return:
    """
    app_token_path = os.path.dirname(os.path.abspath(__file__)) + os.sep + 'app_token.yaml'
    try:
        # 读取时间和token
        if not os.path.exists(app_token_path):
            with open(app_token_path, 'w+') as f:
                f.write('')
        cfg_token = yaml_read(app_token_path)
        t = cfg_token['time']
        record_token = cfg_token['token']
        cur_time = time.time()
        # token时间在7200s之内,返回token
        if 0 < cur_time - t < 7200:
            # print(f"token时效内")
            return record_token
        # token过期,刷新时间和token
        else:
            # print('token已过期')
            token = get_token()
            if token:
                data = {'time': time.time(), 'token': token}
                yaml_clear(app_token_path)
                yaml_write(data, app_token_path)
                return token
    except TypeError:
        # 获取初始时间和token
        print('获取初始token')
        token = get_token()
        data = {'time': time.time(), 'token': token}
        yaml_write(data, app_token_path)
        return token


def yaml_read(file):
    """
    yaml文件读取
    :param file:
    :return:
    """
    with open(file=file, mode="r", encoding="utf-8") as f:
        data = yaml.safe_load(f.read())
    return data


def yaml_write(data, file):
    """
    yaml文件写入
    :param data:
    :param file:
    :return:
    """
    with open(file, 'a', encoding='utf-8') as f:
        yaml.dump(
            data,
            stream=f,
            allow_unicode=True,  # 避免unicode编码问题
            sort_keys=False  # 不自动排序
        )


def yaml_clear(file):
    """
    yaml文件清空
    :param file:
    :return:
    """
    with open(file, 'w', encoding='utf-8') as f:
        f.truncate()

获取热搜

这里我是找的网上别人写好的接口。简单快速方便

https://dabenshi.cn/other/api/hot.php?type=douyinhot // 抖音热点
https://dabenshi.cn/other/api/hot.php?type=toutiaoHot // 头条热榜
https://dabenshi.cn/other/api/hot.php?type=baidu // 百度热搜

我这里使用的是百度热搜。

获取热搜数据

# 获取热搜数据
def get_hotdata():
    '''
    获取百度热搜的数据
    url网上找的: https://dabenshi.cn/other/api/hot.php?type=baidu
    '''
    url = f"https://dabenshi.cn/other/api/hot.php?type=baidu"
    hotdata = [] # 存储所有的热搜数据

    res = requests.get(url=url)
    result = res.json()
    hotdata = result['data'][1:11]    # 这里我只拿了10条数据


# 数据就是一个打列表,里面有字典
hotdata =[
        {
            www.chinasem.cn"index": 2,
            "title": "外交部回应是否邀请特朗普访华",
            "desc": "1月21日,外交部就“中方是否邀请特朗普访华”一事做出回应:愿同美国新政府保持沟通,加强合作。",
            "pic": "https:\/\/fyb-2.cdn.bcebos.com\/hotboard_image\/4d0700b48e6c791e29f1e231e24af061",
            "url": "https:\/\/www.baidu.com\/s?wd=%E5%A4%96%E4%BA%A4%E9%83%A8%E5%9B%9E%E5%BA%94%E6%98%AF%E5%90%A6%E9%82%80%E8%javascriptAF%B7%E7%89%B9%E6%9C%97%E6%99%AE%E8%AE%BF%E5%8D%8E&sa=fyb_news&rsv_dl=fyb_news",
            "hot": "797.6万",
            "mobilUrl": "https:\/\/www.baidu.com\/s?wd=%E5%A4%96%E4%BA%A4%E9%83%A8%E5%9B%9E%E5%BA%94%E6%98%AF%E5%90%A6%E9%82%80%E8%AF%B7%E7%89%B9%E6%9C%97%E6%99%AE%E8%AE%BF%E5%8D%8E&sa=fyb_news&rsv_dl=fyb_news"
        }
]

下载热搜图片

其实就是把热搜数据里面的pic图片保存到了本地

这样一会就好给图片加上标题文字了

def get_hotimg(hotdataall):
    """
    下载热搜图片
    hotdata: 所有数据
    """

    if hotdataall:
        for hotdata in hotdataall:
            try:
                # 发送HTTP GET请求获取图片数据
                response = requests.get(hotdata['pic'], timeout=10)
                # 检查请求是否成功
                if response.status_code == 200:
                    # 获取Content-Type头信息
                    content_type = response.headers.get('Content-Type')

                    # 根据Content-Type判断图片类型
                    image_extension = None
                    if content_type == 'image/jpeg':
                        image_extension = '.jpg'
                    elif content_type == 'image/png':
                        image_extension = '.png'
                    elif content_type == 'image/gif':
                        image_extension = '.gif'
                    else:
                        raise Exception(f"Unsupported image type: {content_type}")

                    # 以二进制写模式打开文件,并将图片数据写入文件
                    img_name = "hotimg/orgimg/" + str(hotdata['index']) + image_extension
                    img_name_new = "hotimg/nowimg/" + str(hotdata['index']) + image_extension
                    with open(img_name, 'wb') as file:
                        file.write(response.content)
                    print(f'图片已保存到 {img_name}')

                    hotdata['image_path'] = img_name
                    hotdata['image_path_new'] = img_name_new
                else:
                    print(f'下载图片失败,状态码: {response.status_code}')
            except requests.RequestException as e:
                print(f'请求出现异常: {e}')

给图片加上标题文字

# 给图片加上文字
    if hotdata:
        for hotdata_in in hotdata:
            image_path = hotdata_in['image_path']
            image_path_new = hotdata_in['image_path_new']
            text = hotdata_in['title']
            max_width = 500

            add_text_to_image(image_path, image_path_new, text=text, max_width=max_width)

def add_text_to_image(image_path, image_path_new, text='', max_width=500):
    '''
    给图片添加文字
    '''
    image = Image.open(image_path)
    draw = ImageDraw.Draw(image)
    width, height = image.size

    font_size = max(30, int(width * 0.03))

    font = ImageFont.truetype("ttf/feihuasongti.ttf", font_size)
    text_color = (255, 255, 255)  # 黑色字体
    shadow_color = (0, 0, 0)  # 黑色阴影
    # text_width, text_height = draw.textsize(text, font=font)
    # 获取文本尺寸
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]

    while text_width > width - 30:
        font_size -= 1
        font = ImageFont.truetype("ttf/feihuasongti.ttf", font_size)
        # text_width, text_height = draw.textsize(text, font=font)
        # 获取文本尺寸
        bbox = draw.textbbox((0, 0), text, font=font)
        text_width = bbox[2] - bbox[0]
        text_height = bbox[3] - bbox[1]

    # 计算文本位置
    x = width - text_width
    y = height - text_height - 30
    # 绘制文本阴影
    draw.text(((x/2) + 2, y + 2), text, font=font, fill=shadow_color)
    draw.text((x / 2, y), text, font=font, fill=NHdsayTdaatext_color)

    image.save(image_path_new)
    print(f'图片已加文字 {image_path_new}')

类似这样,在图片底部加上文字

微信公众号脚本-获取热搜自动新建草稿并发布文章

上传图片素材

这块会返回上传到素材url。这个url地址,可以在文章里面使用

def add_media(hotdataall):
    """
    新增临时素材: https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&amp;type=TYPE
    上传图文消息内www.chinasem.cn的图片获取URL, 新增永久素材: https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
    新增其他类型永久素材, 新增永久素材: https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&amp;type=TYPE
    """
    # url = f"https://api.weixin.qq.com/cgi-bin/media/upload?access_token={refresh_token()}&amp;type=image"
    url = f"https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={refresh_token()}"

    if hotdataall:
        for hotdata in hotdataall:
            with open(hotdata['image_path_new'], 'rb') as fp:
                files = {'media': fp}
                res = requests.post(url, files=files)
                res = json.loads(str(res.content, 'utf8'))
                hotdata["wx_img_url"] = res['url']

新建草稿

这里会返回草稿的ID

def add_draft(hotdataall):
    '''
    新建草稿
    '''
    url = f'https://api.weixin.qq.com/cgi-bin/draft/add?access_token={refresh_token()}'

    # content = "<img src='https://mmbiz.qpic.cn/sz_mmbiz_jpg/hY63os7Ee2Ro6WVkfj9nvfDdpONqLwr48J2eQEYXygs3cWibLvQTHAveYWNnXOOWHO3jZldO3fr7quVj6V0X5uA/0?wx_fmt=jpeg'/>"
    # 读取文件html
    # 打开HTML文件并读取内容
    with open('content.html', 'r', encoding='utf-8') as file:
        html_content_template = file.read()

    # 动态生成草稿content内容全部,先定义一个变量
    html_content = ""

    # 动态生成草稿content内容片段
    for hotdata in hotdataall:
        # 判断热搜第一
        if hotdata['index'] == 2:
            title_color = "red"
        else:
            title_color = "black"

        # 定义变量
        hot_context = {
            'num': hotdata['index'] - 1,
            'url_img': hotdata['wx_img_url'],
            'title_color': title_color,
            'title_title': hotdata['title'],
            'describe': hotdata['desc'],
        }

        # 替换变量
        substitute_data = string.Template(html_content_template)
        result = substitute_data.safe_substitute(hot_context)
        html_content += result

    data = {
        "articles": [
            {
                "title":"标题",
                "author":"作者",
                "digest":"描述",
                "content":html_content,
                "thumb_media_id":"封面素材ID",
                "need_open_comment":1,
                "only_fans_can_comment":1
            }
        ]
    }

    res = requests.post(url=url, data=json.dumps(data, ensure_ascii=False).encode('utf-8'))

    if res.status_code == 200:
        result = json.loads(res.content)
        if result.get('media_id'):
            print(f'新建草稿成功--{result}')
            return result['media_id']
        else:
            print(f'新建草稿失败--{result}')
    else:
        print(f'新建草稿失败--{res.text}')

发布草稿

def free_publish(media_id):
    '''
    发布草稿
    '''
    url = f'https://api.weixin.qq.com/cgi-bin/freepublish/submit?access_token={refresh_token()}'

    data = {
        "media_id": media_id
    }

    res = requests.post(url=url, json=data)
    res = json.loads(str(res.content, 'utf8'))
    print(res)

到此这篇关于微信公众号脚本-获取热搜自动新建草稿并发布文章的文章就介绍到这了,更多相关微信公众号热搜自动发文脚本内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于微信公众号脚本-获取热搜自动新建草稿并发布文章的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154103

相关文章

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

IDEA中新建/切换Git分支的实现步骤

《IDEA中新建/切换Git分支的实现步骤》本文主要介绍了IDEA中新建/切换Git分支的实现步骤,通过菜单创建新分支并选择是否切换,创建后在Git详情或右键Checkout中切换分支,感兴趣的可以了... 前提:项目已被Git托管1、点击上方栏Git->NewBrancjsh...2、输入新的分支的

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

利用Python脚本实现批量将图片转换为WebP格式

《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.