qpl_cljx.py 15 KB

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