qpl_cljx.py 15 KB

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