├── .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 | [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE)
5 |
6 | 实时关注微博、B站、抖音、小红书某用户更新动态,并及时通过微信提醒
7 |
8 | 详见文章:https://www.blain.top/p/wbdxmonitor/
9 |
10 | 有问题可通过博客内联系方式进行留言
11 |
12 | 
13 |
14 | 
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 | 
36 |
37 | 二、免费注册使用WxPusher微信消息推送服务
38 |
39 | https://wxpusher.zjiecode.com/
40 |
41 | 注册完成后在“应用管理--appToken”中生成一个自己的凭证,**并修改start.py中对应位置**
42 |
43 | 
44 |
45 | 三、使用方法
46 |
47 | 周期性执行以下命令,可使用宝塔或者crontab设置定时任务
48 |
49 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 | python3 start.py
51 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52 |
53 |
54 | 
55 |
56 | 
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()
--------------------------------------------------------------------------------