alive.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. '''
  4. @File : alive.py
  5. @Time : 2019/05/26 12:14:04
  6. @Author : Liuyuqi
  7. @Version : 1.0
  8. @Contact : liuyuqi.gov@msn.cn
  9. @License : (C)Copyright 2019
  10. @Desc : 保持心跳
  11. https://live.kuaishou.com/rest/wd/live/liveStream/myfollow
  12. Request URL: https://live.kuaishou.com/rest/wd/live/liveStream/myfollow
  13. Request Method: POST
  14. Status Code: 200 OK
  15. Remote Address: 127.0.0.1:1080
  16. Referrer Policy: unsafe-url
  17. Accept: application/json
  18. Accept-Encoding: gzip, deflate, br
  19. Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
  20. Connection: keep-alive
  21. Content-Length: 0
  22. 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
  23. Host: live.kuaishou.com
  24. kpf: PC_WEB
  25. kpn: GAME_ZONE
  26. Origin: https://live.kuaishou.com
  27. Referer: https://live.kuaishou.com/u/fengyeYS
  28. 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
  29. res:
  30. '''
  31. import json
  32. import queue
  33. import threading
  34. import time
  35. import requests
  36. # import pymysql
  37. import utils.get_cookie as get_cookie
  38. baseUrl = "https://live.kuaishou.com"
  39. baseTokenUrl = "https://id.kuaishou.com"
  40. # 房间号
  41. # https://live.kuaishou.com/u/lol111112
  42. room = baseUrl + "/u/Q1998227"
  43. # baseUrl = "http://nginx.ok.yoqi.me:88"
  44. # baseTokenUrl="http://nginx.ok.yoqi.me:88"
  45. proxies = {"http": "http://120.26.110.59:8080"}
  46. # sessionClient=requests.session()
  47. sessionClients = []
  48. baseHeader = {
  49. "Accept": "application/json",
  50. "Origin": baseUrl,
  51. }
  52. account_alive_count = 0
  53. detail_url_queue = queue.Queue(maxsize=1000)
  54. def login(userPhone, cookies, userAgent, threadid):
  55. """
  56. 登录快手,执行一次即可。
  57. param :
  58. return:
  59. """
  60. url = baseTokenUrl + "/pass/kuaishou/login/passToken"
  61. mPartHeader = {
  62. "Content-Type": "application/x-www-form-urlencoded",
  63. "Referer": room,
  64. "User-Agent": userAgent
  65. }
  66. mHeader = baseHeader.copy()
  67. mHeader.update(mPartHeader)
  68. proxies = []
  69. res = sessionClients[threadid].post(url=url, headers=mHeader, cookies=cookies, data="sid=kuaishou.live.web"
  70. # proxies=proxies
  71. )
  72. print(res.text)
  73. resText = json.loads(res.text)
  74. if resText["result"] != 1:
  75. print("thread {id}: User {userPhone}.passToken failure".format(id=threadid, userPhone=userPhone))
  76. return False
  77. else:
  78. url2 = baseUrl + "/user/login"
  79. mPartHeader = {
  80. "Content-Type": "application/json;charset=UTF-8",
  81. "Referer": room,
  82. "kpn": "GAME_ZONE",
  83. "kpf": "PC_WEB",
  84. "User-Agent": userAgent
  85. }
  86. mHeader2 = baseHeader.copy()
  87. mHeader2.update(mPartHeader)
  88. cookie_dict = {
  89. "kuaishou.live.web.at": resText["kuaishou.live.web.at"],
  90. "kuaishou.live.web_st": resText["kuaishou.live.web_st"],
  91. }
  92. cookies.update(cookie_dict)
  93. sessionClients[threadid].cookies.update(cookie_dict)
  94. mData = {"authToken": resText["kuaishou.live.web.at"], "sid": "kuaishou.live.web"}
  95. mData = json.dumps(mData).replace("", "")
  96. res2 = sessionClients[threadid].post(url=url2, headers=mHeader2, data=mData, cookies=cookies
  97. # proxies=proxies
  98. )
  99. # urllib.request.
  100. print(res2.text)
  101. if res2.text == "'Bad Request'":
  102. print("thread {id}: User {userPhone}.login failure".format(id=threadid, userPhone=userPhone))
  103. return False
  104. if json.loads(res2.text)["result"] != 1:
  105. print("thread {id}: User {userPhone}.login failure".format(id=threadid, userPhone=userPhone))
  106. return False
  107. else:
  108. print("thread {id}: User {userPhone}.login success".format(id=threadid, userPhone=userPhone))
  109. return True
  110. def goToRoom(userPhone, cookies, userAgent, threadid):
  111. '''
  112. 进入直播间
  113. :param userPhone:
  114. :param cookies:
  115. :param userAgent:
  116. :param threadid:
  117. :return:
  118. '''
  119. url = room
  120. mPartHeader = {
  121. "Content-Type": "application/json;charset=UTF-8",
  122. "Referer": room,
  123. "User-Agent": userAgent
  124. }
  125. mHeader = baseHeader.copy()
  126. mHeader.update(mPartHeader)
  127. # cookies = requests.utils.dict_from_cookiejar(session.cookies)
  128. # print(session)
  129. res = sessionClients[threadid].get(
  130. url=url, headers=mHeader,
  131. # proxies=proxies
  132. )
  133. print("进入直播间结果:" + res.text[0:200])
  134. def firstcollect(userPhone, cookies, userAgent, threadid):
  135. url = baseUrl + ""
  136. '''
  137. session_id: yLZP77qeoyWVjfJV
  138. page_id: 1ReS9GIUNs-VyxWJ_1558897018534
  139. refer_page_id: eM4eCCCOFHxvnT70_1558896991974
  140. refer_show_id:
  141. refer_url: https://live.kuaishou.com/u/Q1998227
  142. page_live_stream_id: 9PLaXTwT6vs
  143. url: https://live.kuaishou.com/u/Q1998227
  144. screen: 1366*768
  145. platform: Win32
  146. log_time: 1558897029472
  147. type: error
  148. errorDetail: Error: WebSocket timeout
  149. '''
  150. pass
  151. def watchingFeed(userPhone, cookies, userAgent, threadid):
  152. url = baseUrl + "/wd/live/watchingFeed"
  153. data = {"liveStreamId": "9PLaXTwT6vs"}
  154. sessionClients[threadid].post(url=url, data=data)
  155. pass
  156. def livefeed(userPhone, cookies, userAgent, threadid):
  157. '''
  158. :param userPhone:
  159. :param cookies:
  160. :param userAgent:
  161. :param threadid:
  162. :return:
  163. '''
  164. url = baseUrl + "/rest/wd/live/feed/v2"
  165. data = '{"liveStreamId":"9PLaXTwT6vs","pageId":"1ReS9GIUNs-VyxWJ_1558897018534","isHeartbeat":true}'
  166. data2='{"liveStreamId":"9PLaXTwT6vs","commentCursor":"syR2en5SdlY","giftCursor":"tQO_AlQBrO4","pageId":"1ReS9GIUNs-VyxWJ_1558897018534","isHeartbeat":false}'
  167. sessionClients[threadid].post(url=url, data=data)
  168. pass
  169. def wssLogin():
  170. url = "wss://live-ws-pg-group3.kuaishou.com/websocket"
  171. pass
  172. def myfollow(userPhone, cookies, userAgent, threadid):
  173. '''
  174. 维持心跳,更新cookie。
  175. :param userPhone:
  176. :param cookies:
  177. :param userAgent:
  178. :param threadid:
  179. :return:
  180. '''
  181. url = baseUrl + "/rest/wd/live/liveStream/myfollow"
  182. mPartHeader = {
  183. "Content-Type": "application/json;charset=UTF-8",
  184. "Referer": room,
  185. "User-Agent": userAgent
  186. }
  187. mHeader = baseHeader.copy()
  188. mHeader.update(mPartHeader)
  189. # cookies = requests.utils.dict_from_cookiejar(session.cookies)
  190. # print(session)
  191. res = sessionClients[threadid].get(
  192. url=url, headers=mHeader, cookies=cookies,
  193. # proxies=proxies
  194. )
  195. print(res.text)
  196. if (not json.loads(res.text).get("result")) or json.loads(res.text)["result"] != 1:
  197. return False
  198. else:
  199. return True
  200. def collect(userPhone, cookies, userAgent, threadid):
  201. {
  202. "kbytes_received": 5865,
  203. "kernel_version": "1.4.4",
  204. "session_id": "326fa539-4620-4892-a38f-42e0163c92d1",
  205. "tick_index": 18,
  206. "play_url": "https://tx-adaptive.pull.yximgs.com/gifshow/9PLaXTwT6vs.flv?txSecret=3d78c0935d21b9fc7a2cc869280bc1fc&txTime=5cec3114&stat=K5DJraklhpYTr46EqykzzDPJ3eereyUOENGTqe69syLjKCw6RVyHE3Gg0nSpfL/6&oidc=txhb",
  207. "domain": "tx-adaptive.pull.yximgs.com",
  208. "play_start_time": 1558896531540,
  209. "tick_start": 1558896701559,
  210. "tick_duration": 10002,
  211. "block_count": 0,
  212. "buffer_time": 0,
  213. "pause_duration": 0,
  214. "play_duration": 10002,
  215. "played_video_duration": 10002,
  216. "a_buf_len": 9880,
  217. "a_buf_slices": 1,
  218. "v_buf_len": 9903,
  219. "v_buf_slices": 1,
  220. "speed_chg_metric": {
  221. "0.9x": 259,
  222. "1.1x": 7214
  223. },
  224. "block_count_with_buffer": 0,
  225. "buffer_during_block": 0,
  226. "decoded_video_frames": 95,
  227. "dropped_video_frames": 4,
  228. "adaptive_multi_rate": 0,
  229. "play_pos": 158379,
  230. "v_data_rate": 7981,
  231. "a_data_rate": 114,
  232. "error_code": 0,
  233. "error_message": "",
  234. "v_bandwidth": 0,
  235. "buffer_queue_count": 0,
  236. "v_segment_count": 102,
  237. "a_segment_count": 102,
  238. "hidden": 0,
  239. "first_screen_total_duration": -1,
  240. "stream_duration": "null",
  241. "skip_cnt": 0,
  242. "skip_duration": 0,
  243. "demuxed_video_duration": 5916,
  244. "dropped_packet_duration": 0,
  245. "v_rec_delay": 9984,
  246. "v_render_delay": 22865,
  247. "a_render_delay": 22872,
  248. "stream_id": "9PLaXTwT6vs",
  249. "server_ip": "",
  250. "retry_cnt": 0,
  251. "cpu": 0
  252. }
  253. url = baseUrl + "/rest/wd/live/liveStream/myfollow"
  254. mPartHeader = {
  255. "Content-Type": "application/json;charset=UTF-8",
  256. "Referer": room,
  257. "User-Agent": userAgent
  258. }
  259. mHeader = baseHeader.copy()
  260. mHeader.update(mPartHeader)
  261. # cookies = requests.utils.dict_from_cookiejar(session.cookies)
  262. # print(session)
  263. res = sessionClients[threadid].get(
  264. url=url, headers=mHeader, cookies=cookies,
  265. # proxies=proxies
  266. )
  267. print(res.text)
  268. if (not json.loads(res.text).get("result")) or json.loads(res.text)["result"] != 1:
  269. return False
  270. else:
  271. return True
  272. def run(userPhone, cookies, userAgent, threadid):
  273. '''
  274. 执行多线程批量登录,维持在线
  275. :param userPhone: 用户手机号
  276. :param cookies: 用户初始化cookie
  277. :param userAgent: 用户agent
  278. :param threadid: 线程id
  279. :return:
  280. '''
  281. state = False # 登录状态
  282. state = login(userPhone, cookies, userAgent, threadid)
  283. # 进入直播间
  284. goToRoom(userPhone, cookies, userAgent, threadid)
  285. while True:
  286. state = myfollow(userPhone, cookies, userAgent, threadid)
  287. if state == False:
  288. print("thread {id}: User {userPhone}. is alive".format(id=threadid, userPhone=userPhone))
  289. break
  290. else:
  291. print("thread {id}: User {userPhone}. is alive".format(id=threadid, userPhone=userPhone))
  292. time.sleep(10)
  293. def logout():
  294. '''
  295. 登出,如果需要暂停,则登出所有账号
  296. :return:
  297. '''
  298. pass
  299. if __name__ == "__main__":
  300. start_time = time.time()
  301. mUser = get_cookie.getUser()
  302. account_alive_count = len(mUser["userPhone"])
  303. # print(account_alive_count)
  304. # exit()
  305. for i in range(account_alive_count):
  306. sessionClients.append(requests.session()) # 新建一个session
  307. threading.Thread(target=run,
  308. args=(mUser["userPhone"][i], mUser["cookies"][i], mUser["userAgent"][i], i)).start()
  309. print("last time: {} s".format(time.time() - start_time))