qpl_cljx.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. import random
  2. import time
  3. from datetime import datetime
  4. import requests
  5. import json
  6. from common import Feishu
  7. from common.sql_help import sqlCollect
  8. class QplKs:
  9. @classmethod
  10. def ks_star_info(cls):
  11. content_type = [{'美食': '673'}, {'旅游': '679'}, {'音乐': '687'}, {'时政资讯': '692'}, {'健康医疗': '684'},
  12. {'军事': '701'}, {'教育培训': '685'}, {'生活': '677'}, {'舞蹈': '688'},
  13. {'母婴亲子': '676'}, {'萌宠': '691'}, {'情感': '696'}, {'搞笑': '695'}, {'人文': '697'},
  14. {'三农': '694'}, {'科学与法律': '693'}, {'读书': '689'}, {'奇人异象': '700'}, {'民生资讯': '703'},
  15. {'纪实类': '705'}, {'财经投资': '690'}, {'摄影': '704'}, {'艺术文化': '682'}, {'房产家居': '683'},
  16. {'短剧': '674'}, {'时尚': '675'}, {'影视娱乐': '702'}, {'体育运动': '680'}, {'健身达人': '706'},
  17. {'星座命理': '699'}, {'汽车': '678'}, {'高新数码': '686'}]
  18. fans_count = [{10000000: 0}, {5000000: 10000000}, {3000000: 5000000}, {1000000: 3000000}, {100000: 1000000}, {0: 100000}]
  19. # fans_count = [{10000000: 0}, {5000000: 10000000}]
  20. url = "https://k.kuaishou.com/rest/web/star/list"
  21. headers = {
  22. 'Accept': 'application/json',
  23. 'Accept-Language': 'zh-CN,zh;q=0.9',
  24. 'Content-Type': 'application/json',
  25. 'Cookie': 'did=web_9c6a04a4004fdb7c95a658a56ed275b6; didv=1711519980000; apdid=328ac94f-4040-41fe-a038-b60140291aca99fb22e9862c74736f53d57b666ee53b:1719580529:1; language=zh-CN; ud=2205012540; app_id=ks686235996059836592; expire_time=1800; userId=2574854626; access_token=ChFvYXV0aC5hY2Nlc3NUb2tlbhIwIRvxysHMF86NQiMYMtw1_s0zM4gAEA9_4VrJixHfjYqD8RBNius0YXow_kWI0B8sGhINVY3cQVhC4YDnv5YNyfZ0IKwiIObPEx_s6MCNTBHJclEO0mnOPHspy1vnwt-9536AWyqYKAUwAQ; nc_user_id=CiVhZC5ub3RpZnkuY2VudGVyLm9hdXRoLnVzZXIuaWQuc2VjcmV0EiAtVd5hI6zlT9/UG3HxzRPGDpAxZul8rkwLeQzpGx4y5xoS0fOAqkTADrggSZ6ZpciI2NO9IiBQFbr8Uk6ApRwM5LcFRtS+AAj/QbpiELCRBW7L200+nCgFMAE=; kuaishou.ad.social_st=ChVrdWFpc2hvdS5hZC5zb2NpYWwuc3QSoAFByWIrb3A2KGuX_eJCqlJa6wQTlc2l7mp_MQN_5RLJ4INIE2O3-v18nVEBafp8VK9sY5-ExW_XMpfak7gT8EoI0ft5snPqXur9Ki4gVWIbK-Z-VkyQFkAaD6qB-VtBsqiUoHEmAI9s1H-1kLMKYTCwBUbPH8TsBbnPQw0Lg8NvSQ2Gl4_DP0uA4ouuPFjKJtcoEs9SEz9VbPFfC7X0iDQFGhIk8-y_Rw9CUpd3ZdyZev2LvtUiIKLFKmL283X9GwjqcIMqjlF3erFhqI1QIA9aK-z1gQh3KAUwAQ; kuaishou.ad.social_ph=8764c8e6b60f8cff08b469a56da3fdbe2482; did=web_9c6a04a4004fdb7c95a658a56ed275b6; didv=1711522726000',
  26. 'Origin': 'https://k.kuaishou.com',
  27. 'Pragma': 'no-cache',
  28. 'Referer': 'https://k.kuaishou.com/',
  29. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
  30. }
  31. for count in fans_count:
  32. (fans_min_num, fans_max_num), = count.items()
  33. for content in content_type:
  34. (content_name, content_id), = content.items()
  35. current_page = 1
  36. while True:
  37. payload_data = {
  38. "currentPage": current_page,
  39. "pageSize": 20,
  40. "starOrderTag": 3,
  41. "taskType": 1,
  42. "marketingGoal": 1,
  43. "viewerAgeList": [ # 观众画像 50+
  44. {
  45. "from": "0.50",
  46. "to": "1.00",
  47. "queryName": "50+"
  48. }
  49. ],
  50. "userName": "",
  51. "vitalityTags": [ # 活跃度 近期短视频活跃
  52. "668"
  53. ],
  54. "contentTagIdList": [ # 内容类型
  55. {
  56. "id": str(content_id),
  57. "selectFirstLevelId": True
  58. }
  59. ],
  60. # "starTagIds": [ # 高调性
  61. # 13
  62. # ]
  63. # "fansMinNum": 1000000, # 粉丝数量
  64. # "fansMaxNum": 3000000, # 粉丝数量
  65. }
  66. if fans_min_num > 0:
  67. payload_data["fansMinNum"] = fans_min_num
  68. if fans_max_num > 0:
  69. payload_data["fansMaxNum"] = fans_max_num
  70. payload = json.dumps(payload_data)
  71. time.sleep(random.randint(10, 20))
  72. response = requests.request("POST", url, headers=headers, data=payload)
  73. response = response.json()
  74. print(f"开始扫描{content}")
  75. result = response["result"]
  76. if result == 1:
  77. try:
  78. total = response["total"] # 总条数
  79. if total == 0:
  80. print(f"没有扫描到数据{content}")
  81. break
  82. star_list = response["starList"]
  83. if len(star_list) == 0 or star_list == []:
  84. break
  85. for star in star_list:
  86. print(f"扫描到一条数据{content}")
  87. user_id = star["userId"]
  88. star_id = star["starId"]
  89. name = star["name"] # 用户名
  90. kwai_id = star["kwaiId"] # 用户名id
  91. gender = star["gender"] # 性别
  92. fans_number = star["fansNumber"] # 粉丝数
  93. profile_id = star["profileId"] # 主页id
  94. star_tag_str = star["starTagStr"] # 内容类型1
  95. industry_tag_str = star["industryTagStr"] # 内容类型2
  96. photo_expect_play = star["photoExpectPlay"] # 预期播放量
  97. photo_expect_cpm = star["photoExpectCpm"] # 预期CPM
  98. photo_interaction_rate = star["photoInteractionRate"] # 互动率
  99. photo_complete_play_rate = star["photoCompletePlayRate"] # 完播率
  100. fans_increase_num = star["fansIncreaseNum"] # 粉丝增长量
  101. fans_increase_rate = star["fansIncreaseRate"] # 粉丝增长率
  102. sqlCollect.insert_ks_star_data(user_id, star_id, name, kwai_id, gender, fans_number, profile_id, star_tag_str, industry_tag_str, photo_expect_play, photo_expect_cpm, photo_interaction_rate, photo_complete_play_rate, fans_increase_num, fans_increase_rate)
  103. print(f"{star_id}-{profile_id}获取列表入库成功")
  104. cls.ks_star_works_info(star_id, profile_id)
  105. time.sleep(random.randint(10, 20))
  106. cls.ks_list_portrait_info(star_id, profile_id)
  107. time.sleep(random.randint(10, 20))
  108. # # if res == 1:
  109. # current_time = datetime.now()
  110. # formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
  111. # if fans_min_num == 0:
  112. # fans = f"{fans_max_num}及以下"
  113. # if fans_max_num == 0:
  114. # fans = f"{fans_min_num}及以上"
  115. # else:
  116. # fans = f"{fans_min_num}~{fans_max_num}"
  117. # values = [
  118. # [
  119. # name,
  120. # gender,
  121. # fans_number,
  122. # profile_id,
  123. # "https://www.kuaishou.com/profile/"+profile_id,
  124. # star_tag_str,
  125. # industry_tag_str,
  126. # photo_expect_play,
  127. # photo_expect_cpm,
  128. # photo_interaction_rate,
  129. # photo_complete_play_rate,
  130. # fans_increase_num,
  131. # fans_increase_rate,
  132. # fans,
  133. # formatted_time
  134. # ]
  135. # ]
  136. # Feishu.insert_columns("GjGZsmW2ahaCe4tmzDTc58tVnbe", "COyUUm", "ROWS", 1, 2)
  137. # time.sleep(0.5)
  138. # Feishu.update_values("GjGZsmW2ahaCe4tmzDTc58tVnbe", "COyUUm", "A2:Z2", values)
  139. # print(f"入库到一条数据{content}")
  140. current_page += 1
  141. if total < 20:
  142. break
  143. else:
  144. page = int(total)/20
  145. if current_page > int(page)+1:
  146. break
  147. except Exception as e:
  148. print(f"{e}")
  149. """
  150. 传播表现
  151. """
  152. @classmethod
  153. def ks_star_works_info(cls, star_id: str, profile_id: str):
  154. url = "https://k.kuaishou.com/rest/web/star/starWorksInfo"
  155. payload = json.dumps({
  156. "starId": star_id,
  157. "starType": 1
  158. })
  159. headers = {
  160. 'Accept': 'application/json',
  161. 'Accept-Language': 'zh-CN,zh;q=0.9',
  162. 'Connection': 'keep-alive',
  163. 'Content-Type': 'application/json',
  164. 'Cookie': 'did=web_9c6a04a4004fdb7c95a658a56ed275b6; apdid=328ac94f-4040-41fe-a038-b60140291aca99fb22e9862c74736f53d57b666ee53b:1719580529:1; language=zh-CN; ud=2205012540; app_id=ks686235996059836592; expire_time=1800; userId=2574854626; didv=1723085291918; ktrace-context=1|MS44NDczNjc0NTc4Njk4ODg0LjkyNDY3NjQzLjE3MjM2MTQ2Mjg2NjEuMzc1MTU4NQ==|MS44NDczNjc0NTc4Njk4ODg0Ljg1OTQzNzM2LjE3MjM2MTQ2Mjg2NjEuMzc1MTU4Ng==|0|kfx-static-next|webservice|true|src-Js; access_token=ChFvYXV0aC5hY2Nlc3NUb2tlbhIwEfqwf_iXlB7qZC-yBIZ7wzfbtvVxWEtcqvOjV3Ahucb4bcg4eEU4ZXJdiGjXL0_DGhImjeJINItPIItBy5OsJyVmCSAiIJC7zfaxc6aWMUNcZnaovyHman1q9FuX6SVwvv78r766KAUwAQ; nc_user_id=CiVhZC5ub3RpZnkuY2VudGVyLm9hdXRoLnVzZXIuaWQuc2VjcmV0EiA9Xlc6pQrv/CfDOcZkppkPR/m+EmFPauz504UqHlT6NhoSrafgX8ChvRXqqk8sQBmlX0bHIiDVB56hHXHIm6E7T5fG/voyXk4XLCiSfZmJ+cBMIezaNigFMAE=; kuaishou.ad.social_st=ChVrdWFpc2hvdS5hZC5zb2NpYWwuc3QSoAFoZ_IW4vs9mw9faWsm7l1U1unH1_dkj033-ggljw2O8ynkHvCFFt0YYAU2ChQgd06Jj53lsHtNgoGFBhkI7zk7h2UJZYTwI5jM0lSBGYTBBz9xGMIfOLqb4WSb5B6YUPfXVNn4wJnUTHrjTkfGjVwbIpVUgu4ybTeDVOstpJDjZF094_Uy-wpsCFXn3cIW60eFgxTmm07hm2BC1yk26r8BGhJtJytzzT9F3o-MaB2XfjahhY8iIPEDbdiIyKie8z8u56eji4V8xu3h7G7Fg-rsS4gxHlrRKAUwAQ; kuaishou.ad.social_ph=dca9139add9f00215f47609bc3d88e43272c; did=web_9c6a04a4004fdb7c95a658a56ed275b6; didv=1711522726000',
  165. 'Origin': 'https://k.kuaishou.com',
  166. 'Referer': 'https://k.kuaishou.com/'
  167. }
  168. response = requests.request("POST", url, headers=headers, data=payload)
  169. response = response.json()
  170. result = response['result']
  171. if result == 1:
  172. try:
  173. star_work_report = response['starWorksInfo']['starWorkReport']
  174. pplay_median_data = star_work_report['pplayMedianData'] # 播放量中位数
  175. pplay_median_data_90 = pplay_median_data['90'] # 获取键 '90' 对应的值
  176. pplay_median_data_30 = pplay_median_data['30'] # 获取键 '30' 对应的值
  177. pphoto_cnt_data = star_work_report['pphotoCntData'] # 视频数量
  178. pphoto_cnt_data_90 = pphoto_cnt_data['90'] # 获取键 '90' 对应的值
  179. pphoto_cnt_data_30 = pphoto_cnt_data['30'] # 获取键 '30' 对应的值
  180. pavg_video_duration_data = star_work_report['pavgVideoDurationData'] # 平均时长
  181. # 处理 '90' 键的值
  182. value_90 = pavg_video_duration_data['90']
  183. pavg_video_duration_data_90 = f"{float(value_90):.3f}%" if value_90 else "0.000%"
  184. # 处理 '30' 键的值
  185. value_30 = pavg_video_duration_data['30']
  186. pavg_video_duration_data_30 = f"{float(value_30):.3f}%" if value_30 else "0.000%"
  187. pavg_like_cnt_data = star_work_report['pavgLikeCntData'] # 平均点赞
  188. star_work_report_90 = pavg_like_cnt_data['90'] # 获取键 '90' 对应的值
  189. star_work_report_30 = pavg_like_cnt_data['30'] # 获取键 '30' 对应的值
  190. pavg_share_cnt_data = star_work_report['pavgShareCntData'] # 平均分享
  191. pavg_share_cnt_90 = pavg_share_cnt_data['90'] # 获取键 '90' 对应的值
  192. pavg_share_cnt_30 = pavg_share_cnt_data['30'] # 获取键 '30' 对应的值
  193. sqlCollect.insert_ks_star_works_info(star_id, profile_id, pplay_median_data_90, pplay_median_data_30, pphoto_cnt_data_90, pphoto_cnt_data_30, pavg_video_duration_data_90, pavg_video_duration_data_30, star_work_report_90, star_work_report_30, pavg_share_cnt_90, pavg_share_cnt_30)
  194. print(f"{star_id}-{profile_id}获取传播表现入库成功")
  195. except Exception as e:
  196. print(f"{star_id}-{profile_id}:{e}")
  197. else:
  198. print(f"{star_id}-{profile_id}获取传播表现失败")
  199. """
  200. 受众分析
  201. """
  202. @classmethod
  203. def ks_list_portrait_info(cls, star_id: str, profile_id: str):
  204. url = "https://k.kuaishou.com/rest/web/star/listPortrait"
  205. payload = json.dumps({
  206. "starId": star_id,
  207. "starType": 1
  208. })
  209. headers = {
  210. 'Accept': 'application/json',
  211. 'Accept-Language': 'zh-CN,zh;q=0.9',
  212. 'Connection': 'keep-alive',
  213. 'Content-Type': 'application/json',
  214. 'Cookie': 'did=web_9c6a04a4004fdb7c95a658a56ed275b6; apdid=328ac94f-4040-41fe-a038-b60140291aca99fb22e9862c74736f53d57b666ee53b:1719580529:1; language=zh-CN; ud=2205012540; app_id=ks686235996059836592; expire_time=1800; userId=2574854626; didv=1723085291918; ktrace-context=1|MS44NDczNjc0NTc4Njk4ODg0LjkyNDY3NjQzLjE3MjM2MTQ2Mjg2NjEuMzc1MTU4NQ==|MS44NDczNjc0NTc4Njk4ODg0Ljg1OTQzNzM2LjE3MjM2MTQ2Mjg2NjEuMzc1MTU4Ng==|0|kfx-static-next|webservice|true|src-Js; access_token=ChFvYXV0aC5hY2Nlc3NUb2tlbhIwEfqwf_iXlB7qZC-yBIZ7wzfbtvVxWEtcqvOjV3Ahucb4bcg4eEU4ZXJdiGjXL0_DGhImjeJINItPIItBy5OsJyVmCSAiIJC7zfaxc6aWMUNcZnaovyHman1q9FuX6SVwvv78r766KAUwAQ; nc_user_id=CiVhZC5ub3RpZnkuY2VudGVyLm9hdXRoLnVzZXIuaWQuc2VjcmV0EiA9Xlc6pQrv/CfDOcZkppkPR/m+EmFPauz504UqHlT6NhoSrafgX8ChvRXqqk8sQBmlX0bHIiDVB56hHXHIm6E7T5fG/voyXk4XLCiSfZmJ+cBMIezaNigFMAE=; kuaishou.ad.social_st=ChVrdWFpc2hvdS5hZC5zb2NpYWwuc3QSoAFoZ_IW4vs9mw9faWsm7l1U1unH1_dkj033-ggljw2O8ynkHvCFFt0YYAU2ChQgd06Jj53lsHtNgoGFBhkI7zk7h2UJZYTwI5jM0lSBGYTBBz9xGMIfOLqb4WSb5B6YUPfXVNn4wJnUTHrjTkfGjVwbIpVUgu4ybTeDVOstpJDjZF094_Uy-wpsCFXn3cIW60eFgxTmm07hm2BC1yk26r8BGhJtJytzzT9F3o-MaB2XfjahhY8iIPEDbdiIyKie8z8u56eji4V8xu3h7G7Fg-rsS4gxHlrRKAUwAQ; kuaishou.ad.social_ph=dca9139add9f00215f47609bc3d88e43272c; did=web_9c6a04a4004fdb7c95a658a56ed275b6; didv=1711522726000',
  215. 'Origin': 'https://k.kuaishou.com',
  216. 'Referer': 'https://k.kuaishou.com/'
  217. }
  218. response = requests.request("POST", url, headers=headers, data=payload)
  219. response = response.json()
  220. result = response['result']
  221. if result == 1:
  222. viewer_portrait = response['data']['viewerPortrait']
  223. sex_percentage = viewer_portrait['sexPercentage'] # 性别占比
  224. try:
  225. for sex in sex_percentage:
  226. sex_type = 'sex_percentage'
  227. sex_name = sex['label']
  228. value = sex['value']
  229. sex_proportion = f"{float(value):.3f}%" if value else "0.000%"
  230. sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, sex_type, sex_name, sex_proportion)
  231. age_percentage = viewer_portrait['agePercentage'] # 年龄占比
  232. for age in age_percentage:
  233. age_type = 'age_percentage'
  234. age_name = age['label']
  235. value = age['value']
  236. age_proportion = f"{float(value):.3f}%" if value else "0.000%"
  237. sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, age_type, age_name, age_proportion)
  238. area_percentage = viewer_portrait['areaPercentage'] # 城市占比
  239. for area in area_percentage:
  240. area_type = 'area_percentage'
  241. area_name = area['label']
  242. value = area['value']
  243. area_proportion = f"{float(value):.3f}%" if value else "0.000%"
  244. sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, area_type, area_name, area_proportion)
  245. mobile_brand_percentage = viewer_portrait['mobileBrandPercentage'] # 设备占比
  246. for brand in mobile_brand_percentage:
  247. brand_type = 'mobile_brand_percentage'
  248. brand_name = brand['label']
  249. value = brand['value']
  250. brand_proportion = f"{float(value):.3f}%" if value else "0.000%"
  251. sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, brand_type, brand_name, brand_proportion)
  252. except Exception as e:
  253. print(f"{star_id}-{profile_id}:{e}")
  254. mobile_price_percentage = viewer_portrait['mobilePricePercentage'] # 设备价格占比
  255. for price in mobile_price_percentage:
  256. price_type = 'mobile_price_percentage'
  257. price_name = price['label']
  258. value = price['value']
  259. price_proportion = f"{float(value):.3f}%" if value else "0.000%"
  260. sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, price_type, price_name, price_proportion)
  261. print(f"{star_id}-{profile_id}获取受众分析入库成功")
  262. else:
  263. print(f"{star_id}-{profile_id}获取受众分析失败")
  264. if __name__ == '__main__':
  265. QplKs.ks_star_info()