├── .DS_Store ├── README.md ├── assets ├── .DS_Store ├── image-20241129134229907.png ├── image-20241129134259965.png ├── image-20241129134540933.png ├── image-20241129134645936.png ├── image-20241129135101929.png ├── image-20241129135454164.png ├── image-20241129135535161.png └── image-20241129140633567.png ├── bzmonitor.py ├── dymonitor.py ├── image ├── 1.png └── 2.png ├── log ├── bilibili.txt ├── douyin.txt ├── wbIds.txt └── xiaohongshu.txt ├── requirements.txt ├── start.py ├── wbmonitor.py └── xhsmonitor.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 微博、B站、抖音、小红书实时监控脚本--WBDXmonitor 2 | =========================================== 3 | 4 | [![PyPI version](https://img.shields.io/badge/python-3-blue.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) 5 | 6 | 实时关注微博、B站、抖音、小红书某用户更新动态,并及时通过微信提醒 7 | 8 | 详见文章:https://www.blain.top/p/wbdxmonitor/ 9 | 10 | 有问题可通过博客内联系方式进行留言 11 | 12 | ![image-20241129134540933](assets/image-20241129134540933.png) 13 | 14 | ![image-20241129134645936](assets/image-20241129134645936.png) 15 | 16 | 17 | 18 | 此脚本的用途 19 | ==== 20 | 21 | 监控微博、B站、抖音、小红书关注之人的动态,并及时通过微信进行提醒 22 | 23 | 使用方法 24 | ==== 25 | 26 | 一、安装 27 | 28 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 29 | git clone https://github.com/Bla1n/WBDXmonitor.git 30 | cd WBDXmonitor 31 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 | 33 | 打开4个monitor,修改文件内容(有注释) 34 | 35 | ![image-20241129140633567](assets/image-20241129140633567.png) 36 | 37 | 二、免费注册使用WxPusher微信消息推送服务 38 | 39 | https://wxpusher.zjiecode.com/ 40 | 41 | 注册完成后在“应用管理--appToken”中生成一个自己的凭证,**并修改start.py中对应位置** 42 | 43 | ![image-20241129135535161](assets/image-20241129135535161.png) 44 | 45 | 三、使用方法 46 | 47 | 周期性执行以下命令,可使用宝塔或者crontab设置定时任务 48 | 49 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 50 | python3 start.py 51 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 | 53 | 54 | ![image-20241129134229907](assets/image-20241129134229907.png) 55 | 56 | ![image-20241129134259965](assets/image-20241129134259965.png) 57 | -------------------------------------------------------------------------------- /assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/.DS_Store -------------------------------------------------------------------------------- /assets/image-20241129134229907.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129134229907.png -------------------------------------------------------------------------------- /assets/image-20241129134259965.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129134259965.png -------------------------------------------------------------------------------- /assets/image-20241129134540933.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129134540933.png -------------------------------------------------------------------------------- /assets/image-20241129134645936.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129134645936.png -------------------------------------------------------------------------------- /assets/image-20241129135101929.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129135101929.png -------------------------------------------------------------------------------- /assets/image-20241129135454164.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129135454164.png -------------------------------------------------------------------------------- /assets/image-20241129135535161.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129135535161.png -------------------------------------------------------------------------------- /assets/image-20241129140633567.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/assets/image-20241129140633567.png -------------------------------------------------------------------------------- /bzmonitor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Author : B1ain 4 | # Action : B站 5 | # Desc : B站对接口进行了反爬处理,原先爬取数据json接口无法直接访问了,因此从搜索接口进行对应关注人视频数量的监控(可能不准,因为删除视频也会引起数量变化) 6 | 7 | import requests, re 8 | from urllib.parse import quote, unquote 9 | 10 | class bzMonitor(): 11 | def __init__(self, ): 12 | self.reqHeaders = { 13 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:132.0) Gecko/20100101 Firefox/132.0', 14 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 15 | 'Content-Type': 'application/x-www-form-urlencoded', 16 | 'Connection': 'close', 17 | 'Accept-Encoding': 'gzip, deflate, br', 18 | 'Upgrade-Insecure-Requests': '1', 19 | 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' 20 | } 21 | # 这里添加关注人的昵称 22 | self.uid = ['犬来八荒w'] 23 | self.dic = 'log/bilibili.txt' 24 | # 拼接各用户的访问连接 25 | def getBZUrl(self): 26 | self.bzurl = [] 27 | for i in self.uid: 28 | url = 'https://search.bilibili.com/all?keyword=' + quote(i) 29 | self.bzurl.append(url) 30 | # 日志为空时执行此函数,获取各用户当前视频数目 31 | def getBZQueue(self): 32 | for i in self.bzurl: 33 | res = requests.get(i, headers=self.reqHeaders) 34 | # 稿件:43(\d*)', res.text)[0] 29 | with open(self.dir, 'w') as f: 30 | f.write(str(num)+'\n') 31 | self.echoMsg('Info','抖音数目获取成功') 32 | # 监控函数 33 | def startdymonitor(self): 34 | returnDict = {} 35 | douyin = [] 36 | with open(self.dir,'r') as f: 37 | for line in f.readlines(): 38 | line = line.strip('\n') 39 | douyin.append(line) 40 | res = requests.get(self.url,headers=self.reqHeaders) 41 | num = re.findall('data-e2e="user-tab-count">(\d*)', res.text)[0] 42 | d_url = self.url+':'+str(num) 43 | if d_url not in douyin: 44 | with open(self.dir, 'a') as f: 45 | f.write(d_url+'\n') 46 | self.echoMsg('Info','狗子抖音更新啦!!!') 47 | returnDict['nickName'] = '狗子' 48 | return returnDict 49 | # 格式化输出 50 | def echoMsg(self, level, msg): 51 | if level == 'Info': 52 | print('[Info] %s'%msg) 53 | elif level == 'Error': 54 | print('[Error] %s'%msg) 55 | 56 | # def main(): 57 | # dy = dyMonitor() 58 | # dy.startdymonitor() 59 | # 60 | # if __name__ == '__main__': 61 | # main() 62 | -------------------------------------------------------------------------------- /image/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/image/1.png -------------------------------------------------------------------------------- /image/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bla1n/WBDXmonitor/3533ecf292af8df89df8629c77d31d6f7c25d528/image/2.png -------------------------------------------------------------------------------- /log/bilibili.txt: -------------------------------------------------------------------------------- 1 | https://search.bilibili.com/all?keyword=%E7%8A%AC%E6%9D%A5%E5%85%AB%E8%8D%92w:43 2 | -------------------------------------------------------------------------------- /log/douyin.txt: -------------------------------------------------------------------------------- 1 | https://www.douyin.com/user/MS4wLjABAAAAnCz_s5xyosgWTo5lTxKCmoYX1-uiytDsAKBye1LbfDE:146 2 | https://www.douyin.com/user/MS4wLjABAAAAnCz_s5xyosgWTo5lTxKCmoYX1-uiytDsAKBye1LbfDE:147 3 | -------------------------------------------------------------------------------- /log/wbIds.txt: -------------------------------------------------------------------------------- 1 | 4258583447216601 2 | 5105435503231169 3 | 5102066949166412 4 | 5101294681064298 5 | 5100333621841218 6 | 5099575716613092 7 | 5096416580471701 8 | 5095274036854863 9 | 5093821099280871 10 | 5092770609629385 11 | 5090977276760018 12 | 4538497644632699 13 | 5104625424534517 14 | 5104242915809310 15 | 5103882001449707 16 | 5103876975890070 17 | 5054291859738729 18 | 5042040127619366 19 | 5034439061277833 20 | 5027475970855049 21 | 5011254227501841 22 | 5004960578408913 23 | 5104219244463585 24 | 5100676500426405 25 | 5098088609878194 26 | 5096599745726584 27 | 5094120775223403 28 | 5091213900251643 29 | 5085077541228755 30 | 5084007842972298 31 | 5080625133914739 32 | 5078854840879438 33 | -------------------------------------------------------------------------------- /log/xiaohongshu.txt: -------------------------------------------------------------------------------- 1 | 夏🍃 2 | 🌧️ 3 | 是日常啊 4 | 🍹 5 | 小王子小野拿下了 6 | 翻看七年前的自己 7 | 冬日雀斑小烟熏我又来了 8 | 我十月没怀胎生下的孩子 9 | 。 10 | Zimomo |两代大首领都拥有了😋 11 | 给自己拍了几张照 12 | 一周内参加了两场婚礼 13 | 关于当年的“我”对要不要孩子的一些想法 14 | 想留高层次中长发的朋友注意了 15 | pts第一天去过了 16 | 倒霉到了极致反而觉得生活开始有劲了 17 | 搬家第一个开箱来了 18 | 上海没看成的柯南展,在首尔看到了 19 | 又到了能把手缩缩缩缩进外套袖子里的季节咯 20 | 淡妆,拿捏🫴 21 | 到了最爱的摆盘环节 22 | 23 | 细软塌发质适用的免打理高层次中短发 24 | 带着和夏天适配度max的透卡去看海了 25 | 喜欢这版的封面 26 | 厨力上升的同时 27 | 生生不息🌱 28 | 不懒了,以后还是多拿相机拍照吧 29 | 搞了半天学化妆的尽头还是淡妆…… 30 | 本意是想创业当老板的,最后成为了美工 31 | 关于我追的番20多年还没有完结 32 | 关于自己出门想全身自拍没带三脚架怎么办 33 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Requests==2.32.3 2 | urllib3==1.26.14 3 | -------------------------------------------------------------------------------- /start.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Author : B1ain 4 | # Action : 监控 5 | # Desc : 启动模块 6 | 7 | import wbmonitor, bzmonitor, dymonitor, xhsmonitor 8 | import requests 9 | import ssl 10 | 11 | ssl._create_default_https_context = ssl._create_unverified_context 12 | 13 | headers = { 14 | 'Connection': 'Keep-Alive', 15 | 'Accept': 'text/html, application/xhtml+xml, */*', 16 | 'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3', 17 | 'Accept-Encoding': 'gzip, deflate', 18 | 'User-Agent': 'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko', 19 | 'Content-Type': 'application/json' 20 | } 21 | 22 | #调用的wxpusher平台 23 | def notify_user(contents, summarys): 24 | url = 'http://wxpusher.zjiecode.com/api/send/message' 25 | datas = { 26 | "appToken":"AT_SvHqAVHGp78N79QLpa5sgtLC4pgcyp32", 27 | "content": contents, 28 | "summary": summarys, 29 | "contentType":1, 30 | "topicIds":[], 31 | "uids":[ 32 | "UID_2Lk68GKb5e2NYMYRnJ5A1LcDku3U" 33 | ], 34 | "url": "" 35 | } 36 | requests.post(url=url, headers=headers, json=datas).json() 37 | 38 | def wbweixin(dicts): 39 | flag = True 40 | try: 41 | summarys = dicts['nickName'] + "发布新微博!\n" 42 | contents = "标题: "+dicts['text']+"\n" 43 | notify_user(contents, summarys) 44 | except Exception as e: 45 | print(e) 46 | flag = False 47 | return flag 48 | 49 | def bzweixin(dicts): 50 | flag = True 51 | try: 52 | summarys = dicts['nickName'] + "B站更新了!\n" 53 | contents = "[B站]" 54 | notify_user(contents, summarys) 55 | except Exception as e: 56 | print(e) 57 | flag = False 58 | return flag 59 | 60 | def dyweixin(dicts): 61 | flag = True 62 | try: 63 | summarys = dicts['nickName'] + "抖音更新了!\n" 64 | contents = "[抖音]" 65 | notify_user(contents, summarys) 66 | except Exception as e: 67 | print(e) 68 | flag = False 69 | return flag 70 | 71 | def xhsweixin(dicts): 72 | flag = True 73 | try: 74 | summarys = dicts['nickName'] + "小红书更新了!\n" 75 | contents = "[小红书]" 76 | notify_user(contents, summarys) 77 | except Exception as e: 78 | print(e) 79 | flag = False 80 | return flag 81 | 82 | def main(): 83 | # 微博部分 84 | w = wbmonitor.WBMonitor() 85 | w.getWBInfo() 86 | with open('log/wbIds.txt', 'r') as f: 87 | text = f.read() 88 | if text == '': 89 | w.getWBQueue() 90 | try: 91 | newWB = w.startmonitor() 92 | if newWB is not None: 93 | print(wbweixin(newWB))#发送邮件成功则输出True 94 | print('微博部分运行成功') 95 | except: 96 | print('微博部分出现问题') 97 | 98 | # B站部分 99 | b = bzmonitor.bzMonitor() 100 | b.getBZUrl() 101 | with open('log/bilibili.txt', 'r') as f2: 102 | text = f2.read() 103 | if text == '': 104 | b.getBZQueue() 105 | try: 106 | newBZ = b.startbzmonitor() 107 | if newBZ is not None: 108 | print(bzweixin(newBZ)) 109 | print('B站部分运行成功') 110 | except: 111 | print('B站部分出现问题') 112 | 113 | # 抖音部分 114 | d = dymonitor.dyMonitor() 115 | with open('log/douyin.txt', 'r') as f3: 116 | text = f3.read() 117 | if text == '': 118 | d.getDYQueue() 119 | try: 120 | newDY = d.startdymonitor() 121 | if newDY is not None: 122 | print(dyweixin(newDY)) 123 | print('抖音部分运行成功') 124 | except: 125 | print('抖音部分出现问题') 126 | 127 | # 小红书部分 128 | x = xhsmonitor.xhsMonitor() 129 | with open('log/xiaohongshu.txt', 'r') as f4: 130 | text = f4.read() 131 | if text == '': 132 | x.getXHSQueue() 133 | try: 134 | newXHS = x.startxhsmonitor() 135 | if newXHS is not None: 136 | print(xhsweixin(newXHS)) 137 | print('小红书部分运行成功') 138 | except: 139 | print('小红书部分出现问题') 140 | 141 | if __name__ == '__main__': 142 | main() 143 | -------------------------------------------------------------------------------- /wbmonitor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Author : B1ain 4 | # Action : 微博 5 | # Desc : 微博主模块 6 | # 添加新uid时,自行清空上一层里的微博id列表 7 | 8 | import requests,json,sys 9 | 10 | class WBMonitor(): 11 | def __init__(self): 12 | self.reqHeaders = { 13 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0', 14 | 'Content-Type': 'application/x-www-form-urlencoded', 15 | 'Referer': 'https://passport.weibo.cn/signin/login', 16 | 'Connection': 'close', 17 | 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' 18 | } 19 | self.uid = ['1927305954', '7347878145', '6512991534']# 这里添加关注人的uid(成果, 犬来八荒, 王冰冰) 20 | self.dic = 'log/wbIds.txt' 21 | # 获取访问连接 22 | def getWBInfo(self): 23 | self.weiboInfo = [] 24 | for i in self.uid: 25 | userInfo = 'https://m.weibo.cn/api/container/getIndex?type=uid&value=%s'%(i) 26 | res = requests.get(userInfo,headers=self.reqHeaders) 27 | for j in res.json()['data']['tabsInfo']['tabs']: 28 | if j['tab_type'] == 'weibo': 29 | self.weiboInfo.append('https://m.weibo.cn/api/container/getIndex?type=uid&value=%s&containerid=%s'%(i,j['containerid'])) 30 | 31 | # 收集已经发布动态的id 32 | def getWBQueue(self): 33 | self.itemIds = [] 34 | for i in self.weiboInfo: 35 | res = requests.get(i,headers=self.reqHeaders) 36 | with open(self.dic, 'a') as f: 37 | for j in res.json()['data']['cards']: 38 | if j['card_type'] == 9: 39 | f.write(j['mblog']['id']+'\n') 40 | self.itemIds.append(j['mblog']['id']) 41 | self.echoMsg('Info', '微博数目获取成功') 42 | self.echoMsg('Info', '目前有 %s 条微博' %len(self.itemIds)) 43 | # 开始监控 44 | def startmonitor(self): 45 | # 获取微博相关内容,编辑邮件内容 46 | returnDict = {} 47 | itemIds = [] 48 | with open(self.dic,'r') as f: 49 | for line in f.readlines(): 50 | line = line.strip('\n') 51 | itemIds.append(line) 52 | for i in self.weiboInfo: 53 | res = requests.get(i,headers=self.reqHeaders) 54 | for j in res.json()['data']['cards']: 55 | if j['card_type'] == 9: 56 | if str(j['mblog']['id']) not in itemIds: 57 | with open(self.dic,'a') as f: 58 | f.write(j['mblog']['id']+'\n') 59 | self.echoMsg('Info','发微博啦!!!') 60 | self.echoMsg('Info','目前有 %s 条微博'%(len(itemIds)+1)) 61 | returnDict['created_at'] = j['mblog']['created_at'] 62 | returnDict['text'] = j['mblog']['text'] 63 | returnDict['source'] = j['mblog']['source'] 64 | returnDict['nickName'] = j['mblog']['user']['screen_name'] 65 | return returnDict 66 | # 格式化输出 67 | def echoMsg(self, level, msg): 68 | if level == 'Info': 69 | print('[Info] %s'%msg) 70 | elif level == 'Error': 71 | print('[Error] %s'%msg) 72 | 73 | # def main(): 74 | # wb = WBMonitor() 75 | # wb.getWBInfo() 76 | # wb.startmonitor() 77 | # 78 | # if __name__ == '__main__': 79 | # main() -------------------------------------------------------------------------------- /xhsmonitor.py: -------------------------------------------------------------------------------- 1 | # https://www.xiaohongshu.com/user/profile/5ad2ede14eacab146f865fe9 2 | 3 | #!/usr/bin/env python 4 | # -*- coding: utf-8 -*- 5 | # Author : B1ain 6 | # Action : 小红书 7 | # Desc : 未登录状态下小红书个人简介页会返回最新的32条笔记,因此只存储这32条内容,若有新笔记加入则会触发判断 8 | 9 | import requests, re 10 | 11 | class xhsMonitor(): 12 | def __init__(self, ): 13 | self.reqHeaders = { 14 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0', 15 | 'Content-Type': 'application/x-www-form-urlencoded', 16 | 'Referer': 'https://space.bilibili.com/3345720/video', 17 | 'Connection': 'close', 18 | 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' 19 | } 20 | self.xhsurl = 'https://www.xiaohongshu.com/user/profile/5ad2ede14eacab146f865fe9' 21 | self.dic = 'log/xiaohongshu.txt' 22 | # 日志为空时执行此函数,获取当前笔记标题 23 | def getXHSQueue(self): 24 | res = requests.get(self.xhsurl, headers=self.reqHeaders) 25 | content = re.findall('"displayTitle":"(.*?)"', res.text) 26 | with open(self.dic, 'a') as f: 27 | for i in content: 28 | f.write(i +'\n') 29 | self.echoMsg('Info','笔记题目获取成功') 30 | # 监控函数 31 | def startxhsmonitor(self): 32 | returnDict = {} #获取视频相关内容 33 | xhs = [] 34 | with open(self.dic, 'r') as f: 35 | for line in f.readlines(): 36 | line = line.strip('\n') 37 | xhs.append(line) 38 | res = requests.get(self.xhsurl, headers=self.reqHeaders) 39 | content = re.findall('"displayTitle":"(.*?)"', res.text) 40 | # 只比较两个数组的内容是否有变化,而不关心顺序 41 | if set(content) != set(xhs): 42 | # 清空原内容,重新写入,防止后期内容太多不好比较 43 | with open(self.dic, 'w') as f: 44 | for i in content: 45 | f.write(i + '\n') 46 | self.echoMsg('Info', '小红书更新啦!!!') 47 | returnDict['nickName'] = '狗子' 48 | return returnDict 49 | # 格式化输出 50 | def echoMsg(self, level, msg): 51 | if level == 'Info': 52 | print('[Info] %s'%msg) 53 | elif level == 'Error': 54 | print('[Error] %s'%msg) 55 | 56 | # def main(): 57 | # xhs = xhsMonitor() 58 | # xhs.startxhsmonitor() 59 | # 60 | # if __name__ == '__main__': 61 | # main() --------------------------------------------------------------------------------