wechat_python/run.py
from sqlalchemy import Column, Integer, String, create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class ArticleInfo(Base): __tablename__ = 'article_info' id = Column(Integer, primary_key=True) type = Column(Integer) datetime = Column(Integer) fakeid = Column(String(255)) status = Column(Integer) content = Column(String(255)) title = Column(String(255)) digest = Column(String(255)) fileid = Column(Integer) content_url = Column(String(255)) source_url = Column(String(255)) cover = Column(String(255)) subtype = Column(Integer) is_multi = Column(Integer) author = Column(String(255)) copyright_stat = Column(Integer) duration = Column(Integer) del_flag = Column(Integer) item_show_type = Column(Integer) audio_fileid = Column(Integer) play_url = Column(String(255)) malicious_title_reason_id = Column(Integer) malicious_content_type = Column(Integer) # 初始化数据库连接 engine = create_engine('数据库连接字符串') # 创建 DBSession 类型 DBSession = sessionmaker(bind=engine) # 创建表 Base.metadata.create_all(engine) # 创建 session 对象 session = DBSession() # 创建新的 ArticleInfo 对象 new_article_info = ArticleInfo( id=1000001146, type=49, datetime=1685929036, fakeid="3553419583", status=2, content="", title="自由速度 | 第二十四期:為賤民寫詩,我們都愛的圖卡拉姆", digest="自由速度Tempo Rubato,唱出靈魂的旋律,以專屬於你的自由速度。\t聊正在翻譯的書、終於印好的書、聊詩", fileid=0, content_url="http://mp.weixin.qq.com/s?__biz=MzU1MzQxOTU4Mw==&mid=2247492333&idx=1&sn=798a9b4bccff988fa186e32f0c7f0100&chksm=adcd9671ea93b00c2c59f8edfd2c1e36656be92220de174f9233450ac3bdbcc5ad14fcb8bff3&scene=27#wechat_redirect", source_url="", cover="https://mmbiz.qpic.cn/mmbiz_jpg/vAKkjup1cHHoHGZ1YpyLMBbYWSTicRTYDgAvmT9Uxkxs5atymvIttUIf48iatUryefCvvyGRpcwSKIeLH33aDUMA/0?wx_fmt=jpeg", subtype=9, is_multi=0, author="灵智宝鬘", copyright_stat=201, duration=0, del_flag=1, item_show_type=0, audio_fileid=0, play_url="", malicious_title_reason_id=0, malicious_content_type=0 ) # 添加到 session session.add(new_article_info) # 提交即保存到数据库 session.commit() # 关闭 session session.close()
wechat_python/app.py
# -*- coding: UTF-8 -*- import json import requests url = 'https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=MzU1MzQxOTU4Mw==&f=json&offset=10&count=10&is_ok=1&scene=124&uin=NDA4Mzg1NTk1&key=05f982ebd31a295d7f06c6f8740e78fac336d2374b0fc6eaf55e88cb7117e9d1c1e643ecff8baa5939b4db06a5136bdfdd69124faf76468d46cb62656e70a7d1d10787b28d94409acfe0f1b54662a0f841d48774691df99c68114de0e8b72941af46d9d0410d07f3906021f4595b3be758bbb85914dbc9ba2ae03c3ea9249dba&pass_ticket=jyt6bvMlhDNP1DG0u0Pi4M5rLkPI8AmLNcKrzeckfLllmrFkmmXpIXcTz1tZjq3A&wxtoken=&appmsg_token=1224_n0SizMWgDDIEsfJ7kQmon6r8wC9xDLc8AhNb3g~~&x5=0&f=json' headers = { 'Host': 'mp.weixin.qq.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36 QBCore/4.0.1301.400 QQBrowser/9.0.2524.400 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2875.116 Safari/537.36 NetType/WIFI MicroMessenger/7.0.5 WindowsWechat', 'X-Requested-With': 'XMLHttpRequest', 'Accept': '*/*', 'Referer': 'https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzU1MzQxOTU4Mw==&scene=124&uin=NDA4Mzg1NTk1&key=05f982ebd31a295d7f06c6f8740e78fac336d2374b0fc6eaf55e88cb7117e9d1c1e643ecff8baa5939b4db06a5136bdfdd69124faf76468d46cb62656e70a7d1d10787b28d94409acfe0f1b54662a0f841d48774691df99c68114de0e8b72941af46d9d0410d07f3906021f4595b3be758bbb85914dbc9ba2ae03c3ea9249dba&devicetype=Windows+10+x64&version=62090538&lang=zh_CN&a8scene=7&acctmode=0&pass_ticket=jyt6bvMlhDNP1DG0u0Pi4M5rLkPI8AmLNcKrzeckfLllmrFkmmXpIXcTz1tZjq3A&winzoom=1', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.5;q=0.4'} cookies = { 'wxuin': '408385595', 'devicetype': 'android-33', 'version': '2800205d', 'lang': 'zh_CN', 'pass_ticket': 'jyt6bvMlhDNP1DG0u0Pi4M5rLkPI8AmLNcKrzeckfLllmrFkmmXpIXcTz1tZjq3A', 'wap_sid2': 'CLvw3cIBEooBeV9ISW8zQU9YN3BrRXo5dXA0WlVFOUdGd2RBRlBleFlmU3hUNHNnekREZXAzOGpDOGRNSktqOWF3TWt3RDNKckNXRm5QMk1SYnlGeGpfa1pFQy12dXhrWGJFX01rdzk2aFp4UV9ZS3dIa2YtNjRRbDRyNHRwMm9QWUxITW5NY1R5UEthWVNBQUF+MP/FhKUGOA1AlU4' } data = {} html = requests.get(url, headers=headers, verify=False, cookies=cookies) print(html.text) res_dict = json.loads(html.text) msg_list = res_dict.get("general_msg_list").get('list') for msg in msg_list: print(msg.get('comm_msg_info').get('id')) print(msg.get('comm_msg_info').get('datetime')) print(msg.get('app_msg_ext_info').get('title')) print(msg.get('app_msg_ext_info').get('digest')) print(msg.get('app_msg_ext_info').get('content_url')) print(msg.get('app_msg_ext_info').get('cover')) print(msg.get('app_msg_ext_info').get('multi_app_msg_item_list')) print('-----------------')
wechat_python/src/main.py
# -*- coding: UTF-8 -*- import asyncio import json from models.article import ArticleInfo from schemas.article import CreateArticle from services import article_service from db.sqlite import create_table async def async_function(): await create_table() with open('res.json','r',encoding='utf-8') as f: cont = f.read() cont_dict = json.loads(cont) app_msg_list = json.loads(cont_dict.get('general_msg_list')).get('list') for msg in app_msg_list: print(msg.get('app_msg_ext_info').get('title')) article = CreateArticle( msg_id=msg.get('comm_msg_info').get('id'), type=msg.get('comm_msg_info').get('type'), datetime=msg.get('comm_msg_info').get('datetime'), fakeid=msg.get('comm_msg_info').get('fakeid'), status=msg.get('comm_msg_info').get('status'), content=msg.get('comm_msg_info').get('content'), title =msg.get('app_msg_ext_info').get('title'), digest=msg.get('app_msg_ext_info').get('digest'), fileid=msg.get('app_msg_ext_info').get('fileid'), content_url=msg.get('app_msg_ext_info').get('content_url'), source_url=msg.get('app_msg_ext_info').get('source_url'), cover=msg.get('app_msg_ext_info').get('cover'), subtype=msg.get('app_msg_ext_info').get('subtype'), is_multi=msg.get('app_msg_ext_info').get('is_multi'), author=msg.get('app_msg_ext_info').get('author'), copyright_stat=msg.get('app_msg_ext_info').get('copyright_stat'), duration=msg.get('app_msg_ext_info').get('duration'), del_flag=msg.get('app_msg_ext_info').get('del_flag'), item_show_type=msg.get('app_msg_ext_info').get('item_show_type'), audio_fileid=msg.get('app_msg_ext_info').get('audio_fileid'), play_url=msg.get('app_msg_ext_info').get('play_url'), malicious_title_reason_id=msg.get('app_msg_ext_info').get('malicious_title_reason_id'), malicious_content_type=msg.get('app_msg_ext_info').get('malicious_content_type'), ) await article_service.create_wechat_article(article) if __name__ == '__main__': asyncio.run(async_function())
wechat_python/src/core/conf.py
import os import secrets from pathlib import Path class ST: # 获取项目根目录 # 或使用绝对路径,指到backend目录为止 BASE_PATH = Path(__file__).resolve().parent.parent.parent # 日志文件路径 LOG_PATH = os.path.join(BASE_PATH, 'log') # sqlite数据库文件路径 SQLITE_PATH = os.path.join(BASE_PATH, 'sqlite_db')
wechat_python/src/models/__init__.py
from db.sqlite import MappedBase from .article import ArticleInfo
wechat_python/src/models/article.py
from sqlalchemy import Column, Integer, String, create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from . import MappedBase class ArticleInfo(MappedBase): __tablename__ = 'article_info' id = Column(Integer,primary_key=True,autoincrement=True) datetime = Column(Integer) msg_id = Column(Integer) type = Column(Integer) fakeid = Column(String(255)) status = Column(Integer) content = Column(String(255)) title = Column(String(255)) digest = Column(String(255)) fileid = Column(Integer) content_url = Column(String(255)) source_url = Column(String(255)) cover = Column(String(255)) subtype = Column(Integer) is_multi = Column(Integer) author = Column(String(255)) copyright_stat = Column(Integer) duration = Column(Integer) del_flag = Column(Integer) item_show_type = Column(Integer) audio_fileid = Column(Integer) play_url = Column(String(255)) malicious_title_reason_id = Column(Integer) malicious_content_type = Column(Integer) # # 创建新的 ArticleInfo 对象 # new_article_info = ArticleInfo( # id=1000001146, # type=49, # datetime=1685929036, # fakeid="3553419583", # status=2, # content="", # title="自由速度 | 第二十四期:為賤民寫詩,我們都愛的圖卡拉姆", # digest="自由速度Tempo Rubato,唱出靈魂的旋律,以專屬於你的自由速度。\t聊正在翻譯的書、終於印好的書、聊詩", # fileid=0, # content_url="http://mp.weixin.qq.com/s?__biz=MzU1MzQxOTU4Mw==&mid=2247492333&idx=1&sn=798a9b4bccff988fa186e32f0c7f0100&chksm=adcd9671ea93b00c2c59f8edfd2c1e36656be92220de174f9233450ac3bdbcc5ad14fcb8bff3&scene=27#wechat_redirect", # source_url="", # cover="https://mmbiz.qpic.cn/mmbiz_jpg/vAKkjup1cHHoHGZ1YpyLMBbYWSTicRTYDgAvmT9Uxkxs5atymvIttUIf48iatUryefCvvyGRpcwSKIeLH33aDUMA/0?wx_fmt=jpeg", # subtype=9, # is_multi=0, # author="灵智宝鬘", # copyright_stat=201, # duration=0, # del_flag=1, # item_show_type=0, # audio_fileid=0, # play_url="", # malicious_title_reason_id=0, # malicious_content_type=0 # )
wechat_python/src/schemas/article.py
# -*- coding: utf-8 -*- from typing import Optional, List from pydantic import BaseModel, Field, EmailStr from datetime import datetime,timedelta,timezone class CreateArticle(BaseModel): msg_id:int type:int datetime:int fakeid:str status:int content:str title:str digest:str fileid:int content_url:str source_url:str cover:str subtype:int is_multi:int author:str copyright_stat:int duration:int del_flag:int item_show_type:int audio_fileid:int play_url:str malicious_title_reason_id:int malicious_content_type:int class Config: json_schema_extra = { "example": { "dev_id": 1, "station_id":1 , "created_at":1676886307 , "name":'str(1676886307).jpg' } }
wechat_python/src/common/logger.py
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os from pathlib import Path from loguru import logger from core.conf import ST class Logger: @staticmethod def log() -> logger: if not os.path.exists(ST.LOG_PATH): os.mkdir(ST.LOG_PATH) # 日志文件 log_file = os.path.join(ST.LOG_PATH, "FastBlog.log") # loguru日志 # more: https://github.com/Delgan/loguru#ready-to-use-out-of-the-box-without-boilerplate logger.add( log_file, encoding='utf-8', level="DEBUG", rotation='00:00', # 每天 0 点创建一个新日志文件 retention="7 days", # 定时自动清理文件 enqueue=True, # 异步安全 backtrace=True, # 错误跟踪 diagnose=True, ) return logger logger = Logger().log()
wechat_python/src/crud/article_crud.py
# -*- coding: utf-8 -*- import time from typing import List, NoReturn from sqlalchemy import select, update,insert from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload, noload from sqlalchemy.sql import Select,text from sqlalchemy import func from datetime import date, datetime, timedelta from models.article import ArticleInfo from schemas.article import CreateArticle async def create_article(db: AsyncSession, obj_in: CreateArticle) -> NoReturn: db_obj = ArticleInfo(**obj_in.model_dump()) db.add(db_obj) await db.commit() async def get_article_by_datetime(db: AsyncSession, datetime: int) -> ArticleInfo: user = await db.execute( select(ArticleInfo) .where(ArticleInfo.datetime == datetime) ) return user.scalars().first() # async def get_user_by_id(self, db: AsyncSession, user_id: int) -> User: # return await self.get(db, user_id) # async def get_user_roles(self, db: AsyncSession, user_id: int) -> list: # se = await db.execute( # select(self.model) # .where(self.model.id == user_id) # .options(selectinload(self.model.roles)) # ) # role_ids = [r.id for r in se.scalars().first().roles] # return role_ids # async def get_userinfo_by_id(self, db: AsyncSession, user_id: int) -> User: # user = await db.execute( # select(self.model) # .options(selectinload(self.model.department)) # .options(noload(self.model.roles)) # .where(self.model.id == user_id) # ) # return user.scalars().first() # res = await db.execute(insert(self.model).values(obj_in.dict())) # async def get_img_by_timestamp(self, db: AsyncSession, timestamp: int) -> Img: # img = await db.execute(select(self.model).where(self.model.created_at ==datetime.fromtimestamp(timestamp) )) # return img.scalars().first() # async def get_imgs_by_dev_id(self, db: AsyncSession, id: int) -> List[Img]: # img = await db.execute(select(self.model).where(self.model.dev_id == id )) # return img.scalars().all() # async def get_imgs_group_by_station_id(self, db: AsyncSession,content_type:str) -> List[Img]: # if content_type == 'temp': # textual_sql = text("""SELECT station.dev_id,station_id,content_temperature,max(datetime(created_at)),x,y FROM img INNER JOIN station WHERE img.station_id = station.id GROUP BY station_id;""") # # textual_sql = textual_sql.columns(Station.dev_id,self.model.station_id,self.model.content_temperature,self.model.created_at,Station.x,Station.y) # else: # textual_sql = text("""SELECT station.dev_id,station_id,content_humidity,max(datetime(created_at)),x,y FROM img INNER JOIN station WHERE img.station_id = station.id GROUP BY station_id;""") # res = await db.execute(textual_sql) # # 将查询的结果转换成字典形式 # keys =list(res.keys()) # keys[3] = 'created_at' # data = [dict(zip(keys, re)) for re in res] # return data # img = await db.execute(select(self.model.id,self.model.station_id,self.model.created_at).group_by(self.model.station_id,self.model.created_at)) # first_date = datetime.now() - timedelta(days=1) # first_date = datetime.now() - timedelta(days=10) # last_date = datetime.now() # img = await db.execute((select(self.model.dev_id).where(self.model.created_at.between(first_date,last_date)).order_by(self.model.created_at)).group_by(self.model.station_id)) # res = await db.execute(select(self.model.station_id).group_by(self.model.station_id)) # res = await db.execute(text("select * from img")) # 获取一段时间的图片,返回一个list # first_date = datetime(2023, 2, 21,11,8,0) # last_date = datetime(2023, 2, 21,11,9,0) # img = await db.execute(select(self.model).where(self.model.created_at.between(first_date,last_date) )) # return img.scalars().all() # async def get_station_by_id(self, db: AsyncSession, id: int) ->Station: # db_obj = await db.execute(select(self.model).where(self.model.id == id)) # return db_obj.scalars().first() # async def get_user_by_username_with_roles(self, db: AsyncSession, username: str) -> User: # user = await db.execute( # select(self.model) # .options(selectinload(self.model.roles)) # .where(self.model.username == username) # ) # return user.scalars().first() # async def update_user_login_time(self, db: AsyncSession, username: str) -> int: # user = await db.execute( # update(self.model) # .where(self.model.username == username) # .values(last_login=func.now()) # ) # return user.rowcount # async def get_email_by_username(self, db: AsyncSession, username: str) -> str: # user = await self.get_user_by_username(db, username) # return user.email # async def get_username_by_email(self, db: AsyncSession, email: str) -> str: # user = await db.execute(select(self.model).where(self.model.email == email)) # return user.scalars().first().username # async def get_avatar_by_username(self, db: AsyncSession, username: str) -> str: # user = await self.get_user_by_username(db, username) # return user.avatar # async def create_user(self, db: AsyncSession, user: CreateUser) -> NoReturn: # user.password = jwt.get_hash_password(user.password) # new_user = self.model(**user.dict(exclude={'role_id'})) # roles_list = [] # for i in user.role_id: # roles_list.append(await db.get(Role, i)) # new_user.roles = roles_list # db.add(new_user) # async def update_userinfo(self, db: AsyncSession, current_user: User, obj: UpdateUser) -> int: # dept = await db.get(Department, obj.department_id) # obj.department_id = dept.id # u = await db.execute( # update(self.model) # .where(self.model.id == current_user.id) # .values(**obj.dict(exclude={'role_id'})) # ) # # step1 删除所有角色 # for i in list(current_user.roles): # current_user.roles.remove(i) # # step2 添加新的角色 # role_list = [] # for i in obj.role_id: # role_list.append(await db.get(Role, i)) # current_user.roles = role_list # return u.rowcount # async def update_avatar(self, db: AsyncSession, current_user: User, avatar: str) -> int: # return await self.update(db, current_user.id, {'avatar': avatar}) # async def delete_user(self, db: AsyncSession, user_id: int) -> int: # return await self.delete(db, user_id) # async def check_email(self, db: AsyncSession, email: str) -> User: # mail = await db.execute(select(self.model).where(self.model.email == email)) # return mail.scalars().first() # async def delete_avatar(self, db: AsyncSession, user_id: int) -> int: # return await self.update(db, user_id, {'avatar': None}) # async def reset_password(self, db: AsyncSession, username: str, password: str) -> int: # user = await db.execute( # update(self.model) # .where(self.model.username == username) # .values(password=jwt.get_hash_password(password)) # ) # return user.rowcount # def get_users(self) -> Select: # return select(self.model)\ # .order_by(self.model.time_joined.desc())\ # .options(selectinload(self.model.department))\ # .options(noload(self.model.roles)) # async def get_user_is_super(self, db: AsyncSession, user_id: int) -> bool: # user = await self.get_user_by_id(db, user_id) # return user.is_superuser # async def get_user_is_active(self, db: AsyncSession, user_id: int) -> bool: # user = await self.get_user_by_id(db, user_id) # return user.is_active # async def super_set(self, db: AsyncSession, user_id: int) -> int: # super_status = await self.get_user_is_super(db, user_id) # user = await db.execute( # update(User) # .where(User.id == user_id) # .values(is_superuser=False if super_status else True) # ) # return user.rowcount # async def active_set(self, db: AsyncSession, user_id: int) -> int: # active_status = await self.get_user_is_active(db, user_id) # user = await db.execute( # update(User) # .where(User.id == user_id) # .values(is_active=False if active_status else True) # ) # return user.rowcount
wechat_python/src/db/sqlite.py
#!/usr/bin/env python3 # -*- coding:utf-8 -*- from contextlib import asynccontextmanager import sys from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker from sqlalchemy.ext.declarative import declarative_base from common.logger import logger # from model import MappedBase from core.conf import ST from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import DeclarativeBase,declared_attr """ 说明:SqlAlchemy """ SQLALCHEMY_DATABASE_URL = f'sqlite+aiosqlite:///{ST.SQLITE_PATH}/wechat.sqlite' try: # 数据库引擎 async_engine = create_async_engine(SQLALCHEMY_DATABASE_URL, future=True) # log.success('数据库连接成功') except Exception as e: logger.error('❌ 数据库链接失败 {}', e) sys.exit() else: async_db_session = async_sessionmaker(bind=async_engine, autoflush=False, expire_on_commit=False) MappedBase = declarative_base() @asynccontextmanager async def get_async_session() -> AsyncSession: """ session 生成器 :return: """ session = async_db_session() try: yield session except Exception as se: await session.rollback() raise se finally: await session.close() def async_session(func): async def wrapper(*args, **kwargs): async with get_async_session() as session: return await func(session, *args, **kwargs) return wrapper async def create_table(): """ 创建数据库表 """ async with async_engine.begin() as coon: await coon.run_sync(MappedBase.metadata.create_all)
wechat_python/src/services/article_service.py
from db.sqlite import async_session from sqlalchemy.ext.asyncio import AsyncSession from schemas.article import CreateArticle from crud import article_crud @async_session async def create_wechat_article(db:AsyncSession,article:CreateArticle): res = await article_crud.get_article_by_datetime(db,article.datetime) if res: return await article_crud.create_article(db,article)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2021-07-02 静态内部类实现单例模式
2021-07-02 单例模式的饿汉式的思想原理
2021-07-02 线程安全的懒汉式单例模式
2021-07-02 单例模式的懒汉式的思想原理
2021-07-02 懒汉模式的单例模式的代码逻辑
2021-07-02 # 单例模式总结和使用场景