├── unknown_gift ├── 0111b93f5b78887399444398ef29da62.png ├── 18ebc87e25795cb334a5ec732991fad9.png ├── 2ae339db0f66d0ef0f9360fabde65c26.png ├── 448ba5dd8ad07ce62a5daa8e6f9d7a0d.png ├── 523b7d52453d88f311b45eb6003ab913.png ├── 580c253e0bd3cc4212f7087d110691ed.png ├── 742c5fb2297a9be4e6d1679252561ea5.png ├── 9770db00a20d8a402778f1adc4093c1d.png ├── 9cebd3a40ddc9e75c53615aa1ca1356e.png ├── cc689489c88d0556f27907eccac3613e.png ├── d09618abdb47007ffa88f6f56aee6cae.png ├── dcab513f09ffa0cbdfc5017deabb6afe.png ├── e123c9a946d17be2f8176a95493f5983.png └── f7ab08a25a2bb546862d9c2d2f72b360.png ├── running.py ├── init.py ├── handle.py ├── requirements.txt ├── config.py ├── import_gift.py ├── gift.txt ├── utils.py ├── readme.md └── main.py /unknown_gift/0111b93f5b78887399444398ef29da62.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/0111b93f5b78887399444398ef29da62.png -------------------------------------------------------------------------------- /unknown_gift/18ebc87e25795cb334a5ec732991fad9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/18ebc87e25795cb334a5ec732991fad9.png -------------------------------------------------------------------------------- /unknown_gift/2ae339db0f66d0ef0f9360fabde65c26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/2ae339db0f66d0ef0f9360fabde65c26.png -------------------------------------------------------------------------------- /unknown_gift/448ba5dd8ad07ce62a5daa8e6f9d7a0d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/448ba5dd8ad07ce62a5daa8e6f9d7a0d.png -------------------------------------------------------------------------------- /unknown_gift/523b7d52453d88f311b45eb6003ab913.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/523b7d52453d88f311b45eb6003ab913.png -------------------------------------------------------------------------------- /unknown_gift/580c253e0bd3cc4212f7087d110691ed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/580c253e0bd3cc4212f7087d110691ed.png -------------------------------------------------------------------------------- /unknown_gift/742c5fb2297a9be4e6d1679252561ea5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/742c5fb2297a9be4e6d1679252561ea5.png -------------------------------------------------------------------------------- /unknown_gift/9770db00a20d8a402778f1adc4093c1d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/9770db00a20d8a402778f1adc4093c1d.png -------------------------------------------------------------------------------- /unknown_gift/9cebd3a40ddc9e75c53615aa1ca1356e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/9cebd3a40ddc9e75c53615aa1ca1356e.png -------------------------------------------------------------------------------- /unknown_gift/cc689489c88d0556f27907eccac3613e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/cc689489c88d0556f27907eccac3613e.png -------------------------------------------------------------------------------- /unknown_gift/d09618abdb47007ffa88f6f56aee6cae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/d09618abdb47007ffa88f6f56aee6cae.png -------------------------------------------------------------------------------- /unknown_gift/dcab513f09ffa0cbdfc5017deabb6afe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/dcab513f09ffa0cbdfc5017deabb6afe.png -------------------------------------------------------------------------------- /unknown_gift/e123c9a946d17be2f8176a95493f5983.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/e123c9a946d17be2f8176a95493f5983.png -------------------------------------------------------------------------------- /unknown_gift/f7ab08a25a2bb546862d9c2d2f72b360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wlkjyh/kuaishou_gift_v2/HEAD/unknown_gift/f7ab08a25a2bb546862d9c2d2f72b360.png -------------------------------------------------------------------------------- /running.py: -------------------------------------------------------------------------------- 1 | """ 2 | 程序运行时动态保存的数据 3 | 4 | 注意:请不要在这个文件中修改或者添加任何代码,否则可能会导致程序无法正常运行 5 | """ 6 | 7 | DRIVER = None 8 | 9 | IS_QRCODE_START = True 10 | 11 | GIFT_LIST = {} -------------------------------------------------------------------------------- /init.py: -------------------------------------------------------------------------------- 1 | from DrissionPage import ChromiumPage 2 | from DrissionPage.easy_set import set_paths 3 | import config 4 | import running 5 | 6 | 7 | """ 初始化出浏览器 """ 8 | set_paths(browser_path=config.BROWSER_PATH) 9 | running.DRIVER = ChromiumPage() 10 | running.DRIVER.get(config.LIVE_URL) -------------------------------------------------------------------------------- /handle.py: -------------------------------------------------------------------------------- 1 | """ 2 | 处理一些消息,你可以在这里实现你的业务逻辑 3 | """ 4 | 5 | 6 | """ 7 | 收到弹幕消息会调用这个函数 8 | """ 9 | def message(username,text): 10 | pass 11 | 12 | 13 | """ 14 | 收到点赞消息会调用这个函数 15 | """ 16 | def like(username): 17 | pass 18 | 19 | """ 20 | 收到礼物消息会调用这个函数,如果未知礼物,gift_name 为 None 21 | """ 22 | def gift(username,gift_name): 23 | pass -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | charset-normalizer==3.1.0 2 | click==8.1.3 3 | colorama==0.4.6 4 | cssselect==1.2.0 5 | DataRecorder==3.3.1 6 | DownloadKit==0.5.3 7 | DrissionPage==3.2.26 8 | et-xmlfile==1.1.0 9 | filelock==3.11.0 10 | FlowViewer==0.3.0 11 | idna==3.4 12 | lxml==4.9.2 13 | openpyxl==3.1.2 14 | pychrome==0.2.3 15 | requests==2.28.2 16 | requests-file==1.5.1 17 | six==1.16.0 18 | tldextract==3.4.0 19 | urllib3==1.26.15 20 | websocket-client==1.5.1 21 | wincertstore==0.2 22 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | 2 | # 直播间地址 3 | LIVE_URL = r"https://live.kuaishou.com/u/KPL704668133" 4 | 5 | # 浏览器可执行文件路径,支持chrome、edge等chromium内核浏览器 6 | BROWSER_PATH = r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe' 7 | 8 | # 是否忽略官方弹幕 9 | IS_IGNORE_OFFICIAL = True 10 | 11 | 12 | # 礼物列表路径 13 | """ 14 | 如果有未知类型的礼物,你需要在这个文件里面添加这个例如,格式为 图片md5值:礼物名称 15 | """ 16 | GIFT_LIST_PATH = r'./gift.txt' 17 | 18 | 19 | # 未知礼物存储路径,你需要将里面的文件名改为礼物名称,然后运行python import_gift.py即可导入新礼物 20 | UNKNOWN_GIFT_PATH = r'./unknown_gift/' 21 | 22 | # 处理多少条弹幕后刷新页面(防止弹幕过多导致程序卡死) 23 | REFRESH_MESSAGE_NUMBER = 1000 24 | 25 | 26 | -------------------------------------------------------------------------------- /import_gift.py: -------------------------------------------------------------------------------- 1 | """ 2 | 导入未知礼物数据 3 | """ 4 | 5 | import os 6 | import config 7 | import hashlib 8 | 9 | 10 | list_file = os.listdir(config.UNKNOWN_GIFT_PATH) 11 | 12 | 13 | for i in list_file: 14 | name = i.split('.')[0] 15 | if len(name) == 32: 16 | print('>>> 跳过文件:', i, ' 因为没有配置礼物名称') 17 | else: 18 | md5 = hashlib.md5(open(config.UNKNOWN_GIFT_PATH + i, 'rb').read()).hexdigest() 19 | print('>>> 导入礼物:', name, 'md5:', md5) 20 | with open(config.GIFT_LIST_PATH, 'a',encoding='utf-8') as f: 21 | f.write('\n' + md5 + ':' + name) 22 | 23 | os.remove(config.UNKNOWN_GIFT_PATH + i) 24 | print('>>> 删除文件:', i) 25 | 26 | print('>>> 原始数量:', len(list_file)) 27 | print('>>> 导入数量:', len(list_file) - len(os.listdir(config.UNKNOWN_GIFT_PATH))) 28 | print('>>> 剩余数量:', len(os.listdir(config.UNKNOWN_GIFT_PATH))) 29 | print('>>> 导入完成') 30 | 31 | 32 | -------------------------------------------------------------------------------- /gift.txt: -------------------------------------------------------------------------------- 1 | 7fd509a7498656ec1700dad93ceefefa:啤酒 2 | ddb4a36f7a5eeed3d1e925c6cf7abc8d:恋爱宇宙 3 | df1d0fa4178112256737086486cb7107:玫瑰 4 | f4f91a671c3bf28070d071b11bfd2c7a:棒棒糖 5 | c13ae0b339530a1162e255a905a65560:游乐园 6 | a282c13ed8fc2f333f641e5400e1e0d2:浪漫邮轮 7 | bae1d0b704f9f836834543e0abf54c3e:玫瑰花园 8 | 9f338535b17d226b6ccdbac78faeedaa:真爱大炮 9 | c9db5568a11ca659678f16e3e94f7252:奥里给 10 | 08f8e7ecb69ac594a3c14e0c1a2b3e1b:钻戒 11 | 4136ba80ca7ee05c75962f6f3b6392ba:皇冠 12 | 0de35cd26ca193e0e94c4cc0b35d9342:私人飞机 13 | 0fdcc3c10c2985f618aa03459acaf0f6:凤冠 14 | a229d7e13cd7d3c877c05c19e6c17324:火箭 15 | c712eb9191d443a85ba32a22e8918b36:烟花 16 | 64e1cc3144b3b0f813a07bd81913b0c9:告白气球 17 | fbd9ad104bdfcc61becfe107c4a8e97d:超跑车队 18 | 254b701829983507204490ef94455589:金龙 19 | 263efe1882621dc60560572500098d05:豪车幻影 20 | 8ebcf0721505f61055854d269eb786bd:超级6 21 | d95eb49c7aa6ba251c43e6e725090b8f:水晶 22 | bb383b18e10822b7ac40c69a947f4154:吻你 23 | 54f5bd6b5f6f78a40bc40401ae3bb3b9:浪漫城堡 24 | 745a421675521e2fbf7198b57cabee3e:金莲 25 | bd44250b2f98b7ef2efd1ba9da96d75e:福袋 26 | 4c643784ef78eeafc1feaea4bf4af589:入场券 27 | e1b78151efb0097e496602cc92a58147:猫粮 28 | 1995e9fc3daf5d17d394fa7b3905e234:吱吱鼠 29 | 527b38c98f4874ba695984b9b6bdb84a:YYDS 30 | 1902140e6a2f9f7724c035439876c1aa:幸运魔盒 31 | 269605dea039956458f40d51487fa35f:草履虫 32 | 4516d493fbe8153bf2d2076894f12812:小白菜 33 | 1c43d23f2579827091256ccbc075b5d6:棒棒糖 34 | 02b9001e8c4cee2dbc05c4f52670face:人气票 35 | caad8394f583fb26b55e7e9058c198d0:人气票 -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | from DrissionPage import ChromiumPage 2 | import running 3 | import config 4 | import re 5 | import base64 6 | import os 7 | import requests 8 | import hashlib 9 | import handle 10 | 11 | def has_login(): 12 | html = running.DRIVER.html 13 | if '登录发弹幕,参与主播互动' in html: 14 | return False 15 | else: 16 | return True 17 | 18 | 19 | def start_qrcode_login(): 20 | try: 21 | running.DRIVER.ele('.login').click() 22 | qrcode_tag = running.DRIVER.ele('xpath:html/body/div[2]/div/div[2]/div/div[1]/div[2]/div[1]/div/div/div/img/@src') 23 | qrcode_tag = str(qrcode_tag) 24 | qrcode_url = re.findall(r'src=\'(.*?)\'', qrcode_tag)[0].replace('data:image/png;base64,', '') 25 | 26 | with open('qrcode.png', 'wb') as f: 27 | f.write(base64.b64decode(qrcode_url)) 28 | os.system('start qrcode.png') 29 | print('>>> 二维码获取成功,请扫描二维码后继续') 30 | except: 31 | print('>>> 二维码获取失败,请手动在浏览器窗口扫码') 32 | 33 | 34 | """ 35 | 异步获取礼物名称,因为获取礼物名称需要发送请求,所以需要异步获取 36 | """ 37 | def queue_get_gift_name(url,username): 38 | r = requests.get(url).content 39 | md5 = hashlib.md5(r).hexdigest() 40 | if md5 in running.GIFT_LIST: 41 | gift_name = running.GIFT_LIST[md5] 42 | print(f'>>>>> 用户名: {username} 送出了 {gift_name} 。') 43 | handle.gift(username, gift_name) 44 | 45 | else: 46 | 47 | storage_file = config.UNKNOWN_GIFT_PATH + md5 + '.png' 48 | if os.path.exists(storage_file) == False: 49 | with open(storage_file, 'wb') as f: 50 | f.write(r) 51 | 52 | 53 | print(f'>>>>> 用户名: {username} 送出了 未知礼物 。') 54 | handle.gift(username, None) 55 | 56 | 57 | pass -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 基于DrissionPage实现的获取快手直播间实时礼物、聊天、点赞信息 2 | 3 | 4 | ## 环境要求 5 | 建议使用conda虚拟环境部署,python版本要求大于或等于``3.6`` 6 | 7 | ## 环境安装 8 | 首先你需要将本项目克隆到你本地。 9 | 10 | 11 | 然后您只需要使用下面命令即可一键安装所需的环境 12 | ```bash 13 | pip3 install -r requirements.txt 14 | ``` 15 | 如果pip下载速度较慢,请使用下面这个命令 16 | ``` 17 | pip3 install -r requirements.txt -i http://pypi.douban.com/simple/ 18 | ``` 19 | 20 | 21 | ## 配置 22 | 在使用前,你需要完成一些基本配置 23 | 24 | 所有配置你只需要在``config.py``文件中完成,如果你不懂任何技术,请不要修改除``config.py``文件外的任何文件。 25 | 26 | 27 | 你主要是需要去配置``LIVE_URL``选项,去指定直播间的地址,配置实例 28 | ```py 29 | LIVE_URL = r"https://live.kuaishou.com/u/KPL704668133" 30 | ``` 31 | 上面这个代码我指定了KPL直播间地址。 32 | 33 | 34 | 其次,你需要配置``BROWSER_PATH``选项,该选项需要你指定浏览器可执行文件的路径,在默认的配置中,我使用了``edge``浏览器作为驱动。 35 | 36 | 你可以配置任何使用``chromium``内核构建的浏览器,例如``Microsoft Edge``或者是``Google Chrome``等。 37 | ```py 38 | BROWSER_PATH = r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe' 39 | ``` 40 | 41 | 其他选项对于本项目的运行影响不大,你可以看选项上面的注释进行配置 42 | 43 | ## 运行 44 | 如果你完成了上述的配置,使用以下命令进行启动本项目 45 | ```bash 46 | python main.py 47 | ``` 48 | 49 | ## 未知礼物 50 | 由于时效性问题,可能导致一些礼物无法识别,此时,你需要额外配置一些未知的礼物。 51 | 52 | 程序会将获取到的未知的例如默认存放到``unknow_gift``目录(你可以在``config.py``中修改这个路径),名称为:礼物图片md5.png,你需要将``礼物图片md5``改为礼物真实的名称,例如,原始文件名``580c253e0bd3cc4212f7087d110691ed.png``,你需要改为``粉丝团.png`` 53 | 54 | 最后你需要执行以下命令完成礼物的导入 55 | 56 | ```shell 57 | python import_git.py 58 | ``` 59 | 60 | 61 | ## 事件开发 62 | 如果你在获取到礼物、收到聊天信息、收到点赞后想实现一些业务流程处理,你需要在``handle.py``中实现。 63 | 64 | 该文件中共实现了三个方法,分别为``message``、``like``、``gift``分别代表了``消息``、``点赞``、``礼物`` 65 | 66 | 代码如下 67 | ```py 68 | 69 | """ 70 | 收到弹幕消息会调用这个函数 71 | """ 72 | def message(username,text): 73 | pass 74 | 75 | 76 | """ 77 | 收到点赞消息会调用这个函数 78 | """ 79 | def like(username): 80 | pass 81 | 82 | """ 83 | 收到礼物消息会调用这个函数,如果未知礼物,gift_name 为 None 84 | """ 85 | def gift(username,gift_name): 86 | pass 87 | 88 | ``` 89 | 90 | ``message``函数会传入两个参数,分别为``username``和``text``,顾名思义``username``就是谁发的消息,``text``就是发的什么消息。 91 | 92 | ``like``函数会传入一个参数,为``username``,就是谁点了赞。 93 | 94 | ``gift``函数会传入两个参数,为`username`和``gift_name``,``username``是送礼物的人,``gift_name``就是礼物名称,如果遇到了未知礼物,则传入的为None 95 | 96 | 97 | 98 | 99 | ## 郑重提示 100 | 请勿将 本项目 应用到任何可能会违反法律规定和道德约束的工作中,请友善使用 本项目,遵守蜘蛛协议,不要将 本项目 用于任何非法用途。如您选择使用 本项目 即代表您遵守此协议,作者不承担任何由于您违反此协议带来任何的法律风险和损失,一切后果由您承担。 101 | 102 | 103 | ## 作者信息 104 | QQ:3139505131 105 | 106 | WECHAT:laravel_debug 107 | 108 | E-Mail:wlkjyy@vip.qq.com 109 | 110 | 111 | ## 后言 112 | 113 | 参考文献: 114 | 115 | - http://g1879.gitee.io/drissionpagedocs/ 116 | - https://github.com/wlkjyh/kuaishouLiwu 117 | 118 | 119 | 120 | 开发不易,如果本项目对你有用,让我喝杯咖啡吧。 121 | 122 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import init 2 | from utils import * 3 | import time 4 | import threading 5 | import handle 6 | 7 | 8 | while True: 9 | if has_login(): 10 | break 11 | 12 | 13 | if running.IS_QRCODE_START == False: 14 | start_qrcode_login() 15 | running.IS_QRCODE_START = True 16 | print('>>> 未检测到登录状态,将在10秒后重试') 17 | time.sleep(10) 18 | 19 | while True: 20 | if '请求过快,请稍后重试' in running.DRIVER.html: 21 | print('>>> [ERROR:1] 正在尝试刷新页面') 22 | running.DRIVER.get(config.LIVE_URL) 23 | else: 24 | print('>>> 已完成。') 25 | break 26 | 27 | """ 28 | 加载礼物列表 29 | """ 30 | print('>>> 开始加载礼物信息') 31 | try: 32 | with open(config.GIFT_LIST_PATH, 'r', encoding='utf-8') as f: 33 | gift_list = f.readlines() 34 | gift_list = [i.replace('\n', '') for i in gift_list] 35 | gift_list = [i.split(':') for i in gift_list] 36 | gift_list = {i[0]:i[1] for i in gift_list} 37 | except: 38 | print('>>> 无法加载礼物信息,请检查相关配置是否正确') 39 | exit(0) 40 | running.GIFT_LIST = gift_list 41 | print('>>> 礼物信息加载成功') 42 | 43 | 44 | frist_length = 0 45 | print('>>> 开始监听弹幕') 46 | while True: 47 | try: 48 | chat_history_container = running.DRIVER.ele('.chat-history').ele('.history') 49 | 50 | chat_info = chat_history_container.eles('.chat-info') 51 | chat_info_length = len(chat_info) 52 | if chat_info_length == frist_length: 53 | continue 54 | else: 55 | frist_length = chat_info_length 56 | 57 | last_chat_info = chat_info[-1] 58 | type_text = last_chat_info.text 59 | # 先判断类型 60 | if '点亮了' in type_text: 61 | username = type_text.split('点亮了')[0] 62 | print(f'>>>>> 用户名: {username} 点赞了。') 63 | handle.like(username) 64 | elif '送' in type_text: 65 | try: 66 | username = type_text.split('送')[0] 67 | 68 | liwu_name = last_chat_info.ele('.gift-img').attrs['src'] 69 | thread = threading.Thread(target=queue_get_gift_name, args=(liwu_name,username)) 70 | thread.setDaemon(True) 71 | thread.start() 72 | 73 | except Exception as e: 74 | print(e) 75 | continue 76 | elif ':' in type_text: 77 | split = type_text.split(':') 78 | username = split[0] 79 | if username == '快手平台账号' and config.IS_IGNORE_OFFICIAL == False: 80 | continue 81 | send_text = split[1] 82 | if send_text == '请求过快,请稍后重试': 83 | print('>>> 被系统风控了,现在需要等待10秒后继续') 84 | time.sleep(10) 85 | 86 | print(f'>>>>> 用户名:{username} 发送了弹幕 {send_text}') 87 | handle.message(username, send_text) 88 | 89 | 90 | if frist_length > config.REFRESH_MESSAGE_NUMBER: 91 | print('>>> 弹幕数量过多,正在尝试刷新页面。') 92 | frist_length = 0 93 | running.DRIVER.get(config.LIVE_URL) 94 | 95 | 96 | except Exception as e: 97 | print('>>> [ERROR:2] 程序出现错误,尝试刷新页面后重试') 98 | print(e) 99 | running.DRIVER.get(config.LIVE_URL) 100 | continue 101 | --------------------------------------------------------------------------------