店播爬取Python脚本

douyin_class.py 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import time
  2. import requests
  3. import random
  4. import uuid
  5. import json
  6. from libs.aesgzip import tt_encrypt
  7. from xlog03 import *
  8. from rds_model.db_redis import DbRedis
  9. def get_mc():
  10. def a():
  11. seed = "1234567890ABCDEF"
  12. sa = []
  13. for i in range(2):
  14. sa.append(random.choice(seed))
  15. salt = ''.join(sa)
  16. return salt
  17. k = ''
  18. for i in range(6):
  19. k += a() + ':'
  20. return k[:-1]
  21. def get_random(i, random_type=1):
  22. if random_type == 1:
  23. return str(random.randint(1 * 10 ** (i - 1), 1 * 10 ** i - 1))
  24. elif random_type == 8:
  25. seed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  26. sa = []
  27. for i in range(i):
  28. sa.append(random.choice(seed))
  29. salt = ''.join(sa)
  30. return salt
  31. else:
  32. seed = "1234567890abcde"
  33. sa = []
  34. for i in range(i):
  35. sa.append(random.choice(seed))
  36. salt = ''.join(sa)
  37. return salt
  38. V1 = '6'
  39. V2 = '8'
  40. channel = 'huawei'
  41. device_type = 'RKK-YZ00'
  42. device_brand = 'HUAWEI'
  43. print(channel, device_type)
  44. class DouYinApi:
  45. USER_AGENT = f'com.ss.android.ugc.aweme/{V1}{V2}0 (Linux; U; Android 5.1.1; zh_CN; {device_type}; Build/LMY47V; Cronet/58.0.2991.0)'
  46. COMMON_DEVICE_PARAMS = {
  47. 'retry_type': 'no_retry',
  48. 'ac': '4g',
  49. 'channel': channel,
  50. 'aid': '1128',
  51. 'app_name': 'aweme',
  52. 'version_code': f'{V1}{V2}0',
  53. 'version_name': f'{V1}.{V2}.0',
  54. 'device_platform': 'android',
  55. 'ssmix': 'a',
  56. 'device_type': device_type,
  57. 'device_brand': device_brand,
  58. 'language': 'zh',
  59. 'os_api': '26',
  60. 'os_version': '8.0.0',
  61. 'manifest_version_code': f'{V1}{V2}0',
  62. 'resolution': '720*1280',
  63. 'dpi': '320',
  64. 'update_version_code': f'{V1}{V2}02',
  65. 'mcc_mnc': '46000'
  66. }
  67. PROXY = {}
  68. def __init__(self, sessionid, proxies):
  69. """
  70. :param cid: client id
  71. """
  72. self.proxies = proxies
  73. self.__cid = ''
  74. self.__device_id = ''
  75. self.__iid = ''
  76. self.__uuid = ''
  77. self.__openudid = ''
  78. self.__device_params = {}
  79. self.__cookie = {
  80. }
  81. def init_device_ids(self, device_id, iid, udid, openudid, cc=None):
  82. self.__device_id = device_id
  83. self.__iid = iid
  84. self.__uuid = udid
  85. self.__openudid = openudid
  86. device_ids = {
  87. 'uuid': udid,
  88. 'openudid': openudid
  89. }
  90. if device_id and iid:
  91. device_ids.update({
  92. 'device_id': device_id,
  93. 'iid': iid,
  94. })
  95. self.__device_params = self.COMMON_DEVICE_PARAMS.copy()
  96. self.__device_params.update(device_ids)
  97. if cc:
  98. self.__cookie.update(cc)
  99. def __get_encrypted_device_info(self, device_id, openudid, udid, clientudid, serial_number, mac, iid):
  100. register_info = {
  101. "magic_tag": "ss_app_log",
  102. "header": {
  103. "display_name": "抖音短视频",
  104. "update_version_code": int(self.COMMON_DEVICE_PARAMS['update_version_code']),
  105. "manifest_version_code": int(self.COMMON_DEVICE_PARAMS['manifest_version_code']),
  106. "aid": 1128,
  107. "channel": self.COMMON_DEVICE_PARAMS['channel'],
  108. "package": "com.ss.android.ugc.aweme",
  109. "app_version": self.COMMON_DEVICE_PARAMS['version_name'],
  110. "version_code": int(self.COMMON_DEVICE_PARAMS['version_code']),
  111. "sdk_version": "2.7.5.8",
  112. "os": "Android",
  113. "os_version": self.COMMON_DEVICE_PARAMS['os_version'],
  114. "os_api": self.COMMON_DEVICE_PARAMS['os_api'],
  115. "device_model": self.COMMON_DEVICE_PARAMS['device_type'],
  116. "device_brand": self.COMMON_DEVICE_PARAMS['device_brand'],
  117. "device_manufacturer": self.COMMON_DEVICE_PARAMS['device_brand'],
  118. "cpu_abi": "armeabi-v7a",
  119. "build_serial": serial_number,
  120. "release_build": "2132ca7_20190320",
  121. "density_dpi": self.COMMON_DEVICE_PARAMS['dpi'],
  122. "display_density": "xhdpi",
  123. "resolution": "1280x720",
  124. "language": "zh",
  125. "mc": mac,
  126. "timezone": 8,
  127. "access": "4G",
  128. "not_request_sender": 0,
  129. "rom": "MIUI-9.11.7",
  130. "rom_version": "miui_V11_9.11.7",
  131. "openudid": str(openudid),
  132. "udid": str(udid),
  133. "clientudid": str(clientudid),
  134. "serial_number": str(serial_number),
  135. "sim_serial_number": [
  136. ],
  137. "region": "CN",
  138. "tz_name": "Asia/Shanghai",
  139. "tz_offset": 28800
  140. },
  141. "_gen_time": str(round(time.time() * 1000))
  142. }
  143. if device_id:
  144. register_info['header']['device_id'] = str(device_id)
  145. if iid:
  146. register_info['header']['iid'] = str(iid)
  147. register_info['header']['push_sdk'] = '[1, 2, 6, 7, 8, 9]'
  148. return tt_encrypt((json.dumps(register_info)))
  149. def register_device(self):
  150. udid = '8604' + get_random(11)
  151. serial_number = str(uuid.uuid4())[-12:]
  152. openudid = '3b22' + str(uuid.uuid4())[-12:]
  153. clientudid = str(uuid.uuid4())
  154. mc = get_mc()
  155. params = {
  156. 'uuid': udid,
  157. 'openudid': openudid,
  158. '_rticket': str(int(round(time.time() * 1000)))
  159. }
  160. params.update(self.COMMON_DEVICE_PARAMS)
  161. device_register_url = 'https://log.snssdk.com/service/2/device_register/?' + parse.urlencode(params)
  162. headers = {
  163. 'User-Agent': DouYinApi.USER_AGENT
  164. }
  165. d = self.__get_encrypted_device_info(None, openudid, udid, clientudid, serial_number, mc, iid=None)
  166. if self.proxies:
  167. resp = requests.post(device_register_url,
  168. data=d, proxies=self.proxies,
  169. headers=headers, verify=False)
  170. else:
  171. resp = requests.post(device_register_url,
  172. data=d,
  173. headers=headers, verify=False)
  174. cookie = resp.cookies.get_dict()
  175. if len(cookie) != 0:
  176. self.__cookie.update(cookie)
  177. resp = resp.json()
  178. ids = {
  179. 'new_user': resp['new_user'],
  180. 'device_id': str(resp['device_id']),
  181. 'iid': str(resp['install_id']),
  182. 'uuid': udid,
  183. 'openudid': openudid,
  184. 'serial_number': serial_number,
  185. 'clientudid': clientudid,
  186. 'mc': mc,
  187. 'cookie': parse.urlencode(self.__cookie),
  188. 'times': 0
  189. }
  190. return ids
  191. def __get_random(self, len):
  192. return ''.join(str(random.choice(range(10))) for _ in range(len))
  193. def __get_msg(self, resp):
  194. return json.loads(resp.text)['msg']
  195. def __get_random_mac(self):
  196. mac = [0x10, 0x2a, 0xb3,
  197. random.randint(0x00, 0x7f),
  198. random.randint(0x00, 0xff),
  199. random.randint(0x00, 0xff)]
  200. return ':'.join(map(lambda x: "%02x" % x, mac))
  201. def __add_other_params(self, douyin_url, params=None):
  202. if params is None:
  203. params = {}
  204. if not douyin_url.__contains__('?'):
  205. douyin_url = douyin_url + '?'
  206. common_params = parse.urlencode(self.__device_params)
  207. if douyin_url.endswith('?') or douyin_url.endswith('&'):
  208. douyin_url = douyin_url + common_params
  209. else:
  210. douyin_url = douyin_url + '&' + common_params
  211. if len(params) > 0:
  212. douyin_url = douyin_url + '&' + parse.urlencode(params)
  213. douyin_url = douyin_url + "&_rticket=" + str(int(round(time.time() * 1000))) + "&ts=" + str(int(time.time()))
  214. return douyin_url
  215. def __http_get(self, url, query_params=None):
  216. if query_params is None:
  217. query_params = {}
  218. url = self.__add_other_params(url, query_params)
  219. print(url)
  220. sign = self.__get_sign(url)
  221. if self.proxies:
  222. resp = requests.get(url, headers=self.__get_headers(sign), cookies=self.__cookie, proxies=self.proxies,
  223. verify=False)
  224. else:
  225. resp = requests.get(url, headers=self.__get_headers(sign), cookies=self.__cookie, verify=False)
  226. cookie = resp.cookies.get_dict()
  227. if len(cookie) != 0:
  228. self.__cookie.update(cookie)
  229. # print(resp.text)
  230. # return resp.json()
  231. return resp
  232. def __get_sign(self, url, form_params=None):
  233. stub = ''
  234. if form_params:
  235. a = parse.urlencode(form_params)
  236. stub = hashlib.md5(a.encode('utf-8')).hexdigest()
  237. ts = int(time.time())
  238. ppp = url[url.index('?') + 1:]
  239. s = getXGon(ppp, stub, parse.urlencode(self.__cookie))
  240. gorgon = xGorgon(ts, strToByte(s))
  241. sign = {
  242. 'X-Khronos': str(ts),
  243. 'X-Gorgon': gorgon,
  244. 'X-Pods': ''
  245. }
  246. print(gorgon)
  247. if stub:
  248. sign.update({
  249. 'X-SS-STUB': stub.upper()
  250. })
  251. return sign
  252. def __get_headers(self, sign=None):
  253. if sign is None:
  254. sign = {}
  255. headers = {
  256. 'User-Agent': DouYinApi.USER_AGENT,
  257. 'X-SS-REQ-TICKET': str(round(time.time() * 1000)),
  258. }
  259. headers.update(sign)
  260. return headers
  261. def get_user_info(self, user_id):
  262. """获取用户信息
  263. :param user_id: 用户ID
  264. :return:
  265. """
  266. params = {
  267. 'user_id': user_id
  268. }
  269. douyin_url = 'https://aweme-eagle.snssdk.com/aweme/v1/user/?'
  270. return self.__http_get(douyin_url, params)