qpl_cljx.py 15 KB

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