qpl_cljx.py 18 KB

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