#1 快手机器人批量登录v1.0

Open
lyq wants to merge 6 commits from lyq/feature/mtilogin into lyq/master
25 changed files with 1012 additions and 0 deletions
  1. 13 0
      .dockerignore
  2. 1 0
      .gitignore
  3. 18 0
      Dockerfile
  4. 35 0
      README.md
  5. 109 0
      comment/comment.py
  6. 13 0
      comment/save_comment.py
  7. 4 0
      conf/account.ini
  8. 8 0
      conf/user.sql
  9. 10 0
      docker-compose.debug.yml
  10. 8 0
      docker-compose.yml
  11. 28 0
      get_proxy.py
  12. 11 0
      login.py
  13. 2 0
      requirements.txt
  14. 52 0
      test/kuaishou_socket.py
  15. 22 0
      test/que.py
  16. 38 0
      test/sssocket.py
  17. 37 0
      test/t2.py
  18. 30 0
      update_dict.py
  19. 86 0
      user_agent.py
  20. 0 0
      utils/__init__.py
  21. 344 0
      utils/alive.py
  22. 55 0
      utils/collect.py
  23. 49 0
      utils/get_cookie.py
  24. 26 0
      utils/kuaishou.py
  25. 13 0
      video/download.py

+ 13 - 0
.dockerignore

@@ -0,0 +1,13 @@
+node_modules
+npm-debug.log
+Dockerfile*
+docker-compose*
+.dockerignore
+.git
+.gitignore
+.env
+*/bin
+*/obj
+README.md
+LICENSE
+.vscode

+ 1 - 0
.gitignore

@@ -1 +1,2 @@
 /.idea
+*.pyc

+ 18 - 0
Dockerfile

@@ -0,0 +1,18 @@
+FROM python:alpine
+LABEL Name=crawl-kuaishou Version=0.0.1
+EXPOSE 3000
+
+WORKDIR /app
+ADD . /app
+
+RUN python3 -m pip install -r requirements.txt
+CMD ["python3", "-m", "crawl-kuaishou"]
+
+# Using pipenv:
+#RUN python3 -m pip install pipenv
+#RUN pipenv install --ignore-pipfile
+#CMD ["pipenv", "run", "python3", "-m", "crawl-kuaishou"]
+
+# Using miniconda (make sure to replace 'myenv' w/ your environment name):
+#RUN conda env create -f environment.yml
+#CMD /bin/bash -c "source activate myenv && python3 -m crawl-kuaishou"

+ 35 - 0
README.md

@@ -0,0 +1,35 @@
+## crawl-kuaishou
+
+快手爬虫,实现快手主播增粉,在线人数维持。
+
+### docker 环境搭建:
+
+```
+docker pull hub.tencentyun.com/google/crawl-kuaishou:[v1.0.0]
+docker tag [ImageId] hub.tencentyun.com/google/crawl-kuaishou:[v1.0]
+docker push hub.tencentyun.com/google/crawl-kuaishou:[v1.0.0]
+```
+
+```
+docker volume create --name datadir
+docker run --name my-mysql -v datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d daocloud.io/mysql:5.7.4
+```
+
+
+```
+cd crawl_bilibili
+python user/get_user.py
+python user/get_face.py
+```
+
+### 快手签名算法
+
+https://blog.csdn.net/wangmxe/article/details/89142436
+
+
+### 错误码表
+
+```
+400       
+{"result":120}
+```

+ 109 - 0
comment/comment.py

@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   login.py
+@Time    :   2019/05/25 21:37:21
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   自动评论
+解决方案:
+'''
+
+import requests
+import json
+import os
+import sys
+import re
+# import pymysql
+import random
+
+
+import user_agent
+
+# src = "C:/Users/liuyuqi/Desktop/crawl_bilibili"
+# os.chdir(src)
+# sys.path.append(src)
+
+# baseUrl = "https://live.kuaishou.com"
+baseUrl = "http://nginx.ok.yoqi.me:88"
+
+proxies = {"http": "http://120.26.110.59:8080"}
+sessionClient = requests.session()
+
+baseHeader = {
+    "Accept": "application/json",
+    "Content-Type": "application/json;charset=UTF-8",
+    "Origin": baseUrl,
+    "kpf": "PC_WEB",
+    "kpn": "GAME_ZONE",
+}
+
+def login():
+    """
+    登录快手,执行一次即可。
+    param :
+    return:
+    """
+    url = baseUrl + "/rest/wd/live/liveStream/myfollow"
+    res=sessionClient.get(url=url)
+    print(res)
+
+def myfollow(parameter_list):
+
+    url = baseUrl + "/rest/wd/live/liveStream/myfollow"
+    headers = ""
+
+    # cookies = requests.utils.dict_from_cookiejar(session.cookies)
+    # print(session)
+
+    res = requests.get(
+        url=url, headers=user_agent.getheaders()).content.decode("utf8")
+    mSessions = requests.session()
+
+    print(res)
+
+def collect(parameter_list):
+    """
+    param :
+    return:
+    """
+    url = baseHeader + "/rest/wd/live/web/collect"
+
+def comment():
+    """
+    给主播评论
+    param :
+    return:
+    """
+    url = baseUrl+"/comment"
+    mPartHeader = {
+        "Referer": "https://live.kuaishou.com/u/3x7zqyj9au3wzaw",
+    }
+    mHeader = baseHeader.copy()
+    mHeader.update(mPartHeader)
+    data = u'{"liveStreamId": "uZrj-hcnNk0","content": "主播好呀,有人吗,呜呜。","color": null}'.encode(
+        "utf8")
+    cookies = {
+        "clientid": "3",
+        "did": "web_4095924dbbb4d12df7a87725a16104b6",
+        "client_key": "65890b29",
+        "userId": "1365365171",
+        "kuaishou.live.web_st": "ChRrdWFpc2hvdS5saXZlLndlYi5zdBKgAUuoAahJmqz3gcRCt5L_K5-otg-5bj5Rg_WChLSt2KDdpifZzHPHXqoxiOeswJoSyGLTrKAnS3VP-lnD9ryAWhPUnEWXfEBL80S9HDu3DUwCv10QFoFmpaRtV7RQs1oCEk8yr0vJH_UaKbG9OOToVcg8cPMpSuVkweBvf14jZJsjL7Ak0dHZukgrBfQ_uglsbdl2xIRYVYNitxg3yZtq-HkaEhq2DZZ7DUHSmXUzdRyAf3O3USIgQt6RuXtFQd4lTRGIeHeD4-JehbLHLMHVo6PoztW7wuUoBTAB",
+        "kuaishou.live.bfb1s": "477cb0011daca84b36b3a4676857e5a1",
+        "kuaishou.live.web_ph": "19c53e5f66220620785d73d07a347e8e76b3"
+    }
+
+    # 下面值是变动的cookie
+    # "kuaishou.live.web_ph": "35642148eaef81c55d0c31082222fa91c2c7"
+
+    res = sessionClient.post(
+        url=url, headers=mHeader, data=data, cookies=cookies,
+        # proxies=proxies
+    )
+    print("finish")
+    print(res.text)
+
+if __name__ == "__main__":
+    comment()

+ 13 - 0
comment/save_comment.py

@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   save_comment.py
+@Time    :   2019/05/26 00:12:06
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   保存评论
+'''
+
+

+ 4 - 0
conf/account.ini

@@ -0,0 +1,4 @@
+[Accounts]
+xiaozhou@qq.com = 16456asf
+liuxiaoq@qq.com = 223girl
+

+ 8 - 0
conf/user.sql

@@ -0,0 +1,8 @@
+DROP TABLE IF EXISTS `user`;
+CREATE TABLE `user` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `mid` int(20) unsigned NOT NULL,
+  `name` varchar(45) NOT NULL,
+  `sex` varchar(45) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;

+ 10 - 0
docker-compose.debug.yml

@@ -0,0 +1,10 @@
+version: '2.1'
+
+services:
+  crawl-kuaishou:
+    image: crawl-kuaishou
+    build:
+      context: .
+      dockerfile: Dockerfile
+    ports:
+      - 3000:3000

+ 8 - 0
docker-compose.yml

@@ -0,0 +1,8 @@
+version: '2.1'
+
+services:
+  crawl-kuaishou:
+    image: crawl-kuaishou
+    build: .
+    ports:
+      - 3000:3000

+ 28 - 0
get_proxy.py

@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   get_proxy.py
+@Time    :   2019/05/26 01:03:22
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   通过给定的 API 文档,获取付费的 ip 代理
+
+这里代理举例如下:
+
+http://www.data5u.com/api/create-dynamic.html
+
+'''
+import requests
+
+sessionClient=requests.session()
+url=""
+
+def saveProxy():
+    # 保存proxy到文件
+    pass
+
+res=sessionClient.get(url=url)
+saveProxy()
+print(res)

+ 11 - 0
login.py

@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   login.py
+@Time    :   2019/05/26 00:52:15
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   快手 web 登录
+'''

+ 2 - 0
requirements.txt

@@ -0,0 +1,2 @@
+aiowebsocket==1.0.0.dev2
+asyncio

+ 52 - 0
test/kuaishou_socket.py

@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   kuaishou_socket.py
+@Time    :   2019/05/28 03:00:17
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   None
+
+Request URL: wss://live-ws-pg-group2.kuaishou.com/websocket
+Request Method: GET
+Status Code: 101 Switching Protocols
+
+Accept-Encoding: gzip, deflate, br
+Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
+Cache-Control: no-cache
+Connection: Upgrade
+Host: live-ws-pg-group2.kuaishou.com
+Origin: https://live.kuaishou.com
+Pragma: no-cache
+Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
+Sec-WebSocket-Key: opUwBCN/VZdDkpQSokZJIQ==
+Sec-WebSocket-Version: 13
+Upgrade: websocket
+User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
+
+'''
+import asyncio
+import logging
+from datetime import datetime
+from aiowebsocket.converses import AioWebSocket
+
+# url = 'wss://api.bbxapp.vip/v1/ifcontract/realTime'
+url = 'wss://live-ws-pg-group2.kuaishou.com/websocket'
+
+async def startup(uri):
+    async with AioWebSocket(uri) as aws:
+        converse = aws.manipulator
+        # 客户端给服务端发送消息
+        await converse.send('{"action":"subscribe","args":["QuoteBin5m:14"]}')
+        while True:
+            mes = await converse.receive()
+            print('{time}-Client receive: {rec}'.format(
+                time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), rec=mes))
+
+if __name__ == '__main__':
+    try:
+        asyncio.get_event_loop().run_until_complete(startup(url))
+    except KeyboardInterrupt as exc:
+        logging.info('Quit.')

+ 22 - 0
test/que.py

@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   que.py
+@Time    :   2019/05/28 02:51:02
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   None
+'''
+
+try:
+    import queue
+except ImportError:
+    import Queue as queue
+
+try:
+    import asyncio
+    print("Ss")
+except Exception as e:
+    print(e)

+ 38 - 0
test/sssocket.py

@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   socket.py
+@Time    :   2019/05/28 02:14:15
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   None
+
+pip install asyncio
+pip install aiowebsocket
+'''
+
+import asyncio
+import logging
+from datetime import datetime
+from aiowebsocket.converses import AioWebSocket
+
+
+async def startup(uri):
+    async with AioWebSocket(uri) as aws:
+        converse = aws.manipulator
+        # 客户端给服务端发送消息
+        await converse.send('{"action":"subscribe","args":["QuoteBin5m:14"]}')
+        while True:
+            mes = await converse.receive()
+            print('{time}-Client receive: {rec}'.format(
+                time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), rec=mes))
+
+
+if __name__ == '__main__':
+    url = 'wss://api.bbxapp.vip/v1/ifcontract/realTime'
+    try:
+        asyncio.get_event_loop().run_until_complete(startup(url))
+    except KeyboardInterrupt as exc:
+        logging.info('Quit.')

+ 37 - 0
test/t2.py

@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   t2.py
+@Time    :   2019/05/28 03:11:04
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   None
+'''
+
+import asyncio
+import logging
+from datetime import datetime
+from aiowebsocket.converses import AioWebSocket
+
+
+async def startup(uri):
+    async with AioWebSocket(uri) as aws:
+        converse = aws.manipulator
+        message = b'AioWebSocket - Async WebSocket Client'
+        while True:
+            await converse.send(message)
+            print('{time}-Client send: {message}'.format(
+                time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
+                message=message))
+            mes = await converse.receive()
+            print('{time}-Client receive: {rec}'.format(
+                time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), rec=mes))
+
+if __name__ == '__main__':
+    remote = 'ws://echo.websocket.org'
+    try:
+        asyncio.get_event_loop().run_until_complete(startup(remote))
+    except KeyboardInterrupt as exc:
+        logging.info('Quit.')

+ 30 - 0
update_dict.py

@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   update_dict.py
+@Time    :   2019/05/25 23:39:20
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   python copy()的作用
+
+下面要修改 baseHeader 的值为 mHeader ,java等代码中实现很简单:
+mHeader=baseHeader.update(mPartHeader) #把baseHeader update修改后赋值给mHeader即可。
+
+但是python中这样是错误。思想是先copy()一份baseHeader,然后再修改。
+
+'''
+
+baseHeader = {
+    "Accept": "application/json",
+    "Content-Type": "application/json;charset=UTF-8",
+}
+mPartHeader = {
+    "Referer": "https://live.kuaishou.com/u/3xphut7zrw7zcbq",
+}
+mHeader = baseHeader.copy()
+mHeader.update(mPartHeader)
+
+print(baseHeader)
+print(mHeader)

+ 86 - 0
user_agent.py

@@ -0,0 +1,86 @@
+# -*-coding:utf-8 -*-
+
+import random
+
+# 各种PC端
+user_agent_list_2 = [
+        # Opera
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60",
+        "Opera/8.0 (Windows NT 5.1; U; en)",
+        "Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50",
+        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50",
+        # Firefox
+        "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0",
+        "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10",
+        # Safari
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
+        # chrome
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.2171.71 Safari/537.36",
+        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/72.0.1271.64 Safari/537.11",
+        "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/66.0.648.133 Safari/534.16",
+        # 360
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36",
+        "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
+        # 淘宝浏览器
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11",
+        # 猎豹浏览器
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER",
+        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)",
+        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)",
+        # QQ浏览器
+        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)",
+        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)",
+        # sogou浏览器
+        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0",
+        "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0)",
+        # maxthon浏览器
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.3.4000 Chrome/30.0.1599.101 Safari/537.36",
+        # UC浏览器
+        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36",
+    ]
+    # 各种移动端
+user_agent_list_3 = [
+        # IPhone
+        "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
+        # IPod
+        "Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
+        # IPAD
+        "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
+        "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
+        # Android
+        "Mozilla/5.0 (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+        "Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+        # QQ浏览器 Android版本
+        "MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+        # Android Opera Mobile
+        "Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10",
+        # Android Pad Moto Xoom
+        "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
+        # BlackBerry
+        "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.337 Mobile Safari/534.1+",
+        # WebOS HP Touchpad
+        "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0",
+        # Nokia N97
+        "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124",
+        # Windows Phone Mango
+        "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; HTC; Titan)",
+        # UC浏览器
+        "UCWEB7.0.2.37/28/999",
+        "NOKIA5700/ UCWEB7.0.2.37/28/999",
+        # UCOpenwave
+        "Openwave/ UCWEB7.0.2.37/28/999",
+        # UC Opera
+        "Mozilla/4.0 (compatible; MSIE 6.0; ) Opera/UCWEB7.0.2.37/28/999"
+    ]
+
+# 返回一个随机的请求头 headers
+
+
+def getheaders():
+    UserAgent = random.choice(user_agent_list_2)  # 这里只用list1
+    headers = {'User-Agent': UserAgent}
+    return headers
+
+
+def getUA():
+    return random.choice(user_agent_list_2)

+ 0 - 0
requirement.txt → utils/__init__.py


+ 344 - 0
utils/alive.py

@@ -0,0 +1,344 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   alive.py
+@Time    :   2019/05/26 12:14:04
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   保持心跳
+
+https://live.kuaishou.com/rest/wd/live/liveStream/myfollow
+Request URL: https://live.kuaishou.com/rest/wd/live/liveStream/myfollow
+Request Method: POST
+Status Code: 200 OK
+Remote Address: 127.0.0.1:1080
+Referrer Policy: unsafe-url
+
+Accept: application/json
+Accept-Encoding: gzip, deflate, br
+Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
+Connection: keep-alive
+Content-Length: 0
+Cookie: did=web_4095924dbbb4d12df7a87725a16104b6; didv=1558790317127; Hm_lvt_86a27b7db2c5c0ae37fee4a8a35033ee=1558790317; kuaishou.live.bfb1s=9b8f70844293bed778aade6e0a8f9942; clientid=3; client_key=65890b29; Hm_lpvt_86a27b7db2c5c0ae37fee4a8a35033ee=1558793089; userId=1365365171; userId=1365365171; kuaishou.live.web_st=ChRrdWFpc2hvdS5saXZlLndlYi5zdBKgAZFHcXmdSz0ZqgeR8-TTgoi9QQRV_2I1NT-eK4Wr46MXF-NpYe4Fo00puYYJRRdqB4nJLluPiMpO7YGwHtxLbnttpwFVvU0_aelP9U7kgg9s1BVI9U1dGQsZ0_JLfL8137gJKr4CqwJaq-9LBhM5a_ATTdc5Te1meUd1st2HGg-Dy_g18QwLY84WirWBIaKm8R7r6Dd3fFKYm-gdtJYmMukaEk2hY_LIikBot7IUVtJ3ydB6KCIgx-OxXNSqmT0GdbC5rtc3vchNEkamnb0pAQf6txb5g3YoBTAB; kuaishou.live.web_ph=b1dec6f6601bf17d2cb5b72665242eea8524
+Host: live.kuaishou.com
+kpf: PC_WEB
+kpn: GAME_ZONE
+Origin: https://live.kuaishou.com
+Referer: https://live.kuaishou.com/u/fengyeYS
+User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
+
+res:
+
+'''
+
+import json
+import queue
+import threading
+import time
+
+import requests
+
+# import pymysql
+import utils.get_cookie as get_cookie
+
+baseUrl = "https://live.kuaishou.com"
+baseTokenUrl = "https://id.kuaishou.com"
+# 房间号
+# https://live.kuaishou.com/u/lol111112
+room = baseUrl + "/u/Q1998227"
+# baseUrl = "http://nginx.ok.yoqi.me:88"
+# baseTokenUrl="http://nginx.ok.yoqi.me:88"
+
+proxies = {"http": "http://120.26.110.59:8080"}
+# sessionClient=requests.session()
+sessionClients = []
+
+baseHeader = {
+    "Accept": "application/json",
+    "Origin": baseUrl,
+}
+account_alive_count = 0
+detail_url_queue = queue.Queue(maxsize=1000)
+
+
+def login(userPhone, cookies, userAgent, threadid):
+    """
+    登录快手,执行一次即可。
+    param :
+    return:
+    """
+    url = baseTokenUrl + "/pass/kuaishou/login/passToken"
+    mPartHeader = {
+        "Content-Type": "application/x-www-form-urlencoded",
+        "Referer": room,
+        "User-Agent": userAgent
+    }
+    mHeader = baseHeader.copy()
+    mHeader.update(mPartHeader)
+    proxies = []
+    res = sessionClients[threadid].post(url=url, headers=mHeader, cookies=cookies, data="sid=kuaishou.live.web"
+                                        # proxies=proxies
+                                        )
+    print(res.text)
+    resText = json.loads(res.text)
+    if resText["result"] != 1:
+        print("thread {id}: User {userPhone}.passToken failure".format(id=threadid, userPhone=userPhone))
+        return False
+    else:
+        url2 = baseUrl + "/user/login"
+        mPartHeader = {
+            "Content-Type": "application/json;charset=UTF-8",
+            "Referer": room,
+            "kpn": "GAME_ZONE",
+            "kpf": "PC_WEB",
+            "User-Agent": userAgent
+        }
+        mHeader2 = baseHeader.copy()
+        mHeader2.update(mPartHeader)
+        cookie_dict = {
+            "kuaishou.live.web.at": resText["kuaishou.live.web.at"],
+            "kuaishou.live.web_st": resText["kuaishou.live.web_st"],
+        }
+        cookies.update(cookie_dict)
+        sessionClients[threadid].cookies.update(cookie_dict)
+        mData = {"authToken": resText["kuaishou.live.web.at"], "sid": "kuaishou.live.web"}
+        mData = json.dumps(mData).replace("", "")
+        res2 = sessionClients[threadid].post(url=url2, headers=mHeader2, data=mData, cookies=cookies
+                                             # proxies=proxies
+                                             )
+        # urllib.request.
+        print(res2.text)
+        if res2.text == "'Bad Request'":
+            print("thread {id}: User {userPhone}.login failure".format(id=threadid, userPhone=userPhone))
+            return False
+        if json.loads(res2.text)["result"] != 1:
+            print("thread {id}: User {userPhone}.login failure".format(id=threadid, userPhone=userPhone))
+            return False
+        else:
+            print("thread {id}: User {userPhone}.login success".format(id=threadid, userPhone=userPhone))
+            return True
+
+
+def goToRoom(userPhone, cookies, userAgent, threadid):
+    '''
+    进入直播间
+    :param userPhone:
+    :param cookies:
+    :param userAgent:
+    :param threadid:
+    :return:
+    '''
+    url = room
+    mPartHeader = {
+        "Content-Type": "application/json;charset=UTF-8",
+        "Referer": room,
+        "User-Agent": userAgent
+    }
+    mHeader = baseHeader.copy()
+    mHeader.update(mPartHeader)
+    # cookies = requests.utils.dict_from_cookiejar(session.cookies)
+    # print(session)
+    res = sessionClients[threadid].get(
+        url=url, headers=mHeader,
+        # proxies=proxies
+    )
+    print("进入直播间结果:" + res.text[0:200])
+
+
+def firstcollect(userPhone, cookies, userAgent, threadid):
+    url = baseUrl + ""
+    '''
+    session_id: yLZP77qeoyWVjfJV
+    page_id: 1ReS9GIUNs-VyxWJ_1558897018534
+    refer_page_id: eM4eCCCOFHxvnT70_1558896991974
+    refer_show_id: 
+    refer_url: https://live.kuaishou.com/u/Q1998227
+    page_live_stream_id: 9PLaXTwT6vs
+    url: https://live.kuaishou.com/u/Q1998227
+    screen: 1366*768
+    platform: Win32
+    log_time: 1558897029472
+    type: error
+    errorDetail: Error: WebSocket timeout
+    '''
+    pass
+
+
+def watchingFeed(userPhone, cookies, userAgent, threadid):
+    url = baseUrl + "/wd/live/watchingFeed"
+    data = {"liveStreamId": "9PLaXTwT6vs"}
+    sessionClients[threadid].post(url=url, data=data)
+    pass
+
+def livefeed(userPhone, cookies, userAgent, threadid):
+    '''
+
+    :param userPhone:
+    :param cookies:
+    :param userAgent:
+    :param threadid:
+    :return:
+    '''
+    url = baseUrl + "/rest/wd/live/feed/v2"
+    data = '{"liveStreamId":"9PLaXTwT6vs","pageId":"1ReS9GIUNs-VyxWJ_1558897018534","isHeartbeat":true}'
+    data2='{"liveStreamId":"9PLaXTwT6vs","commentCursor":"syR2en5SdlY","giftCursor":"tQO_AlQBrO4","pageId":"1ReS9GIUNs-VyxWJ_1558897018534","isHeartbeat":false}'
+    sessionClients[threadid].post(url=url, data=data)
+    pass
+
+def wssLogin():
+    url = "wss://live-ws-pg-group3.kuaishou.com/websocket"
+
+    pass
+
+
+def myfollow(userPhone, cookies, userAgent, threadid):
+    '''
+    维持心跳,更新cookie。
+    :param userPhone:
+    :param cookies:
+    :param userAgent:
+    :param threadid:
+    :return:
+    '''
+    url = baseUrl + "/rest/wd/live/liveStream/myfollow"
+    mPartHeader = {
+        "Content-Type": "application/json;charset=UTF-8",
+        "Referer": room,
+        "User-Agent": userAgent
+    }
+    mHeader = baseHeader.copy()
+    mHeader.update(mPartHeader)
+    # cookies = requests.utils.dict_from_cookiejar(session.cookies)
+    # print(session)
+    res = sessionClients[threadid].get(
+        url=url, headers=mHeader, cookies=cookies,
+        # proxies=proxies
+    )
+    print(res.text)
+
+    if (not json.loads(res.text).get("result")) or json.loads(res.text)["result"] != 1:
+        return False
+    else:
+        return True
+
+
+def collect(userPhone, cookies, userAgent, threadid):
+    {
+        "kbytes_received": 5865,
+        "kernel_version": "1.4.4",
+        "session_id": "326fa539-4620-4892-a38f-42e0163c92d1",
+        "tick_index": 18,
+        "play_url": "https://tx-adaptive.pull.yximgs.com/gifshow/9PLaXTwT6vs.flv?txSecret=3d78c0935d21b9fc7a2cc869280bc1fc&txTime=5cec3114&stat=K5DJraklhpYTr46EqykzzDPJ3eereyUOENGTqe69syLjKCw6RVyHE3Gg0nSpfL/6&oidc=txhb",
+        "domain": "tx-adaptive.pull.yximgs.com",
+        "play_start_time": 1558896531540,
+        "tick_start": 1558896701559,
+        "tick_duration": 10002,
+        "block_count": 0,
+        "buffer_time": 0,
+        "pause_duration": 0,
+        "play_duration": 10002,
+        "played_video_duration": 10002,
+        "a_buf_len": 9880,
+        "a_buf_slices": 1,
+        "v_buf_len": 9903,
+        "v_buf_slices": 1,
+        "speed_chg_metric": {
+            "0.9x": 259,
+            "1.1x": 7214
+        },
+        "block_count_with_buffer": 0,
+        "buffer_during_block": 0,
+        "decoded_video_frames": 95,
+        "dropped_video_frames": 4,
+        "adaptive_multi_rate": 0,
+        "play_pos": 158379,
+        "v_data_rate": 7981,
+        "a_data_rate": 114,
+        "error_code": 0,
+        "error_message": "",
+        "v_bandwidth": 0,
+        "buffer_queue_count": 0,
+        "v_segment_count": 102,
+        "a_segment_count": 102,
+        "hidden": 0,
+        "first_screen_total_duration": -1,
+        "stream_duration": "null",
+        "skip_cnt": 0,
+        "skip_duration": 0,
+        "demuxed_video_duration": 5916,
+        "dropped_packet_duration": 0,
+        "v_rec_delay": 9984,
+        "v_render_delay": 22865,
+        "a_render_delay": 22872,
+        "stream_id": "9PLaXTwT6vs",
+        "server_ip": "",
+        "retry_cnt": 0,
+        "cpu": 0
+    }
+    url = baseUrl + "/rest/wd/live/liveStream/myfollow"
+    mPartHeader = {
+        "Content-Type": "application/json;charset=UTF-8",
+        "Referer": room,
+        "User-Agent": userAgent
+    }
+    mHeader = baseHeader.copy()
+    mHeader.update(mPartHeader)
+    # cookies = requests.utils.dict_from_cookiejar(session.cookies)
+    # print(session)
+    res = sessionClients[threadid].get(
+        url=url, headers=mHeader, cookies=cookies,
+        # proxies=proxies
+    )
+    print(res.text)
+
+    if (not json.loads(res.text).get("result")) or json.loads(res.text)["result"] != 1:
+        return False
+    else:
+        return True
+
+
+def run(userPhone, cookies, userAgent, threadid):
+    '''
+    执行多线程批量登录,维持在线
+    :param userPhone: 用户手机号
+    :param cookies: 用户初始化cookie
+    :param userAgent: 用户agent
+    :param threadid: 线程id
+    :return:
+    '''
+    state = False  # 登录状态
+    state = login(userPhone, cookies, userAgent, threadid)
+    # 进入直播间
+    goToRoom(userPhone, cookies, userAgent, threadid)
+    while True:
+        state = myfollow(userPhone, cookies, userAgent, threadid)
+        if state == False:
+            print("thread {id}: User {userPhone}. is alive".format(id=threadid, userPhone=userPhone))
+            break
+        else:
+            print("thread {id}: User {userPhone}. is alive".format(id=threadid, userPhone=userPhone))
+        time.sleep(10)
+
+
+def logout():
+    '''
+    登出,如果需要暂停,则登出所有账号
+    :return:
+    '''
+    pass
+
+
+if __name__ == "__main__":
+    start_time = time.time()
+    mUser = get_cookie.getUser()
+    account_alive_count = len(mUser["userPhone"])
+    # print(account_alive_count)
+    # exit()
+    for i in range(account_alive_count):
+        sessionClients.append(requests.session())  # 新建一个session
+        threading.Thread(target=run,
+                         args=(mUser["userPhone"][i], mUser["cookies"][i], mUser["userAgent"][i], i)).start()
+
+    print("last time: {} s".format(time.time() - start_time))

+ 55 - 0
utils/collect.py

@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   collect.py
+@Time    :   2019/05/26 12:29:25
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   None
+
+https://live.kuaishou.com/rest/wd/live/web/collect
+
+Request URL: https://live.kuaishou.com/rest/wd/live/web/collect
+Request Method: POST
+Status Code: 200 OK
+Remote Address: 114.118.4.4:443
+Referrer Policy: unsafe-url
+
+Accept: */*
+Accept-Encoding: gzip, deflate, br
+Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
+Connection: keep-alive
+Content-Length: 3162
+Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryqCWW56sc8L7fQ2qJ
+Cookie: did=web_4095924dbbb4d12df7a87725a16104b6; didv=1558790317127; Hm_lvt_86a27b7db2c5c0ae37fee4a8a35033ee=1558790317; kuaishou.live.bfb1s=9b8f70844293bed778aade6e0a8f9942; clientid=3; client_key=65890b29; Hm_lpvt_86a27b7db2c5c0ae37fee4a8a35033ee=1558793089; userId=1365365171; userId=1365365171; kuaishou.live.web_st=ChRrdWFpc2hvdS5saXZlLndlYi5zdBKgAeLqVli2ylW_RqILieJA5M7WER8j-O6HgZ7dU5p1NUGVTdFetnPaPbE2w677IiOnBGMKIGlwFS3ZWgls-nm7MgtEeiYOqLJ7BL-fVgjHGevHk2i6DUW5aD7k8tAJyBzPyiSQcX-0oeTGqQMErN4DQ6hdfyuiGNYoLOOBTVbqLtwgmJlElEMtqr51L0skzodfrvpt65U-1FQ9cJpxJNKVG98aEhqtgBlt9k0TlHg5Y4Goo9D9kyIgNCO7Z8nLU6riZ2yR2yxVxRWy5wzGPpUjAE_gKAPjt9soBTAB; kuaishou.live.web_ph=21f148cee5fd1b69b2b06882a149f9954b54
+Host: live.kuaishou.com
+kpf: PC_WEB
+kpn: GAME_ZONE
+Origin: https://live.kuaishou.com
+Referer: https://live.kuaishou.com/u/miaowu66
+User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
+
+
+session_id: spKrN7MpJVGSvrnm
+page_id: eGZ7-VqgdI7llXcl_1558844873536
+refer_page_id: GdWPtfWNHnUBSHj9_1558844721551
+refer_show_id: 
+refer_url: https://live.kuaishou.com/
+page_live_stream_id: 6KxDomQOYyM
+url: https://live.kuaishou.com/u/miaowu66
+screen: 1366*768
+platform: Win32
+log_time: 1558844900450
+type: player
+client_timestamp: 1558844900450
+browser_name: Chrome
+browser_version: 73.0.3683.86
+os_type: Windows
+os_version: 10
+qos_info: {"kbytes_received":3787,"kernel_version":"1.4.4","session_id":"b2f359d6-e9e8-45a9-86f2-349b5154e0f8","tick_index":3,"play_url":"https://tx-adaptive.pull.yximgs.com/gifshow/6KxDomQOYyM.flv?txSecret=32f1e6718680ab01d7858b0d30aa6a0d&txTime=5ceb6749&stat=7Lm4rJjgbtQIPfFcNid0rYCnMX3bvXsAzFKMznfjlCEpA1dEQV1/d2dkWUkL3ovV&highTraffic=1&oidc=alihb","domain":"tx-adaptive.pull.yximgs.com","play_start_time":1558844874064,"tick_start":1558844894067,"tick_duration":6383,"block_count":1,"buffer_time":4168,"pause_duration":0,"play_duration":2215,"played_video_duration":2215,"a_buf_len":2276,"a_buf_slices":1,"v_buf_len":2272,"v_buf_slices":1,"speed_chg_metric":{"0.9x":6383},"block_count_with_buffer":0,"buffer_during_block":0,"decoded_video_frames":120,"dropped_video_frames":2,"adaptive_multi_rate":0,"play_pos":13228,"v_data_rate":8423,"a_data_rate":117,"error_code":0,"error_message":"","v_bandwidth":0,"buffer_queue_count":0,"v_segment_count":73,"a_segment_count":73,"hidden":0,"first_screen_total_duration":-1,"stream_duration":null,"skip_cnt":0,"skip_duration":0,"demuxed_video_duration":3451,"dropped_packet_duration":0,"v_rec_delay":16329,"v_render_delay":18275,"a_render_delay":18233,"stream_id":"6KxDomQOYyM","server_ip":"","retry_cnt":0,"cpu":0}
+
+'''
+
+

+ 49 - 0
utils/get_cookie.py

@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   get_cookie.py
+@Time    :   2019/05/26 11:53:58
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   None
+'''
+
+def getCookies():
+    with open("../data/cookie.txt", "r") as f:
+        res = []
+        for line in f.readlines():
+            res.append(extract_cookies(line.split("----")[0]))
+        # print(res[0])
+        # cookies
+        # print(res[0].split("----")[0])
+        # print(res[0].split("----")[1])
+        # print(len(res))
+        return res
+
+
+def getUser():
+    with open("../data/cookie.txt", "r",encoding="utf8",errors="ignore") as f:
+        mCookies = []
+        mUser = []
+        mUA = []
+        for line in f.readlines():
+            mCookies.append(extract_cookies(line.split("----")[0]))
+            mUA.append(line.split("----")[1])
+            mUser.append(str(extract_cookies(line.split("----")[2])).split(":")[4].split("\"")[1])
+        return {
+            "cookies": mCookies, "userPhone": mUser, "userAgent": mUA
+            }
+
+def extract_cookies(cookie):
+    """从浏览器或者request headers中拿到cookie字符串,提取为字典格式的cookies"""
+    cookies = dict([l.split("=", 1) for l in cookie.split("; ")])
+    return cookies
+
+    # if __name__ == "__main__":
+    # cookie = "continue=http://www.bj.10086.cn/service/fee/zdcx/; continuelogout=http://www.bj.10086.cn/service/fee/zdcx/; CmLocation=100|100; CmProvid=bj; WT_FPC=id=2e4f7c373760da4bead2e31489565793714:lv=1489635199762:ss=1489635053131; Webtrends=58.132.171.245.1489565794320746; JSESSIONID=0000UGBr1eur3P3Yp6EalieXCp8GP2T:16vf1jlcr; input_loginName=15210357242; c_loginName=15210357242; SSOTime=2017-03-15 16:17:16; mobileNo1=6251a6b7d69b5b5047495ale16ad8b5a5c149d6f2c0@@b50883ee4753ba0784210ce85435ee29c7oesl24a856f3@@1489565836722"
+    # cookies = extract_cookies(cookie)
+    # print(cookies)
+
+# print(getUser()["userPhone"])

+ 26 - 0
utils/kuaishou.py

@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   kuaishou.py
+@Time    :   2019/05/26 00:15:03
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   快手工具类
+'''
+
+class Kuaishou():
+    def __init__(self):
+        self.baseUrl = "https://live.kuaishou.com"
+        # baseUrl = "http://nginx.ok.yoqi.me:88"
+
+    def login(self, parameter_list):
+        pass
+
+    def comment(self, parameter_list):
+        pass
+
+    def saveData(self):
+        pass
+

+ 13 - 0
video/download.py

@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+'''
+@File    :   download.py
+@Time    :   2019/05/25 21:55:32
+@Author  :   Liuyuqi 
+@Version :   1.0
+@Contact :   liuyuqi.gov@msn.cn
+@License :   (C)Copyright 2019
+@Desc    :   下载快手视频
+'''
+import xml
+