123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- import random
- import time
- from datetime import datetime
- import requests
- import json
- from common import Feishu
- from common.sql_help import sqlCollect
- class QplKs:
- @classmethod
- def ks_star_info(cls):
- content_type = [{'美食': '673'}, {'旅游': '679'}, {'音乐': '687'}, {'时政资讯': '692'}, {'健康医疗': '684'},
- {'军事': '701'}, {'教育培训': '685'}, {'生活': '677'}, {'舞蹈': '688'},
- {'母婴亲子': '676'}, {'萌宠': '691'}, {'情感': '696'}, {'搞笑': '695'}, {'人文': '697'},
- {'三农': '694'}, {'科学与法律': '693'}, {'读书': '689'}, {'奇人异象': '700'}, {'民生资讯': '703'},
- {'纪实类': '705'}, {'财经投资': '690'}, {'摄影': '704'}, {'艺术文化': '682'}, {'房产家居': '683'},
- {'短剧': '674'}, {'时尚': '675'}, {'影视娱乐': '702'}, {'体育运动': '680'}, {'健身达人': '706'},
- {'星座命理': '699'}, {'汽车': '678'}, {'高新数码': '686'}]
- # fans_count = [{10000000: 0}, {5000000: 10000000}, {3000000: 5000000}, {1000000: 3000000}, {100000: 1000000}, {0: 100000}]
- fans_count = [{1000000: 3000000}, {100000: 1000000}, {0: 100000}]
- # fans_count = [{10000000: 0}, {5000000: 10000000}]
- url = "https://k.kuaishou.com/rest/web/star/list"
- headers = {
- 'Accept': 'application/json',
- 'Accept-Language': 'zh-CN,zh;q=0.9',
- 'Content-Type': 'application/json',
- '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=',
- 'Origin': 'https://k.kuaishou.com',
- 'Pragma': 'no-cache',
- 'Referer': 'https://k.kuaishou.com/',
- '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',
- }
- for count in fans_count:
- (fans_min_num, fans_max_num), = count.items()
- for content in content_type:
- (content_name, content_id), = content.items()
- current_page = 1
- while True:
- payload_data = {
- "currentPage": current_page,
- "pageSize": 20,
- "starOrderTag": 3,
- "taskType": 1,
- "marketingGoal": 1,
- "viewerAgeList": [ # 观众画像 50+
- {
- "from": "0.50",
- "to": "1.00",
- "queryName": "50+"
- }
- ],
- "userName": "",
- "vitalityTags": [ # 活跃度 近期短视频活跃
- "668"
- ],
- "contentTagIdList": [ # 内容类型
- {
- "id": str(content_id),
- "selectFirstLevelId": True
- }
- ],
- # "starTagIds": [ # 高调性
- # 13
- # ]
- # "fansMinNum": 1000000, # 粉丝数量
- # "fansMaxNum": 3000000, # 粉丝数量
- }
- if fans_min_num > 0:
- payload_data["fansMinNum"] = fans_min_num
- if fans_max_num > 0:
- payload_data["fansMaxNum"] = fans_max_num
- payload = json.dumps(payload_data)
- time.sleep(random.randint(5, 10))
- response = requests.request("POST", url, headers=headers, data=payload)
- response = response.json()
- print(f"开始扫描{content}")
- result = response["result"]
- if result == 1:
- try:
- total = response["total"] # 总条数
- if total == 0:
- print(f"没有扫描到数据{content}")
- break
- star_list = response["starList"]
- if len(star_list) == 0 or star_list == []:
- break
- for star in star_list:
- print(f"扫描到一条数据{content}")
- user_id = star["userId"]
- star_id = star["starId"]
- name = star["name"] # 用户名
- kwai_id = star["kwaiId"] # 用户名id
- gender = star["gender"] # 性别
- fans_number = star["fansNumber"] # 粉丝数
- profile_id = star["profileId"] # 主页id
- id = sqlCollect.select_ks_star_data(profile_id)
- if id:
- continue
- star_tag_str = star["starTagStr"] # 内容类型1
- industry_tag_str = star["industryTagStr"] # 内容类型2
- photo_expect_play = star["photoExpectPlay"] # 预期播放量
- photo_expect_cpm = star["photoExpectCpm"] # 预期CPM
- photo_interaction_rate = star["photoInteractionRate"] # 互动率
- photo_complete_play_rate = star["photoCompletePlayRate"] # 完播率
- fans_increase_num = star["fansIncreaseNum"] # 粉丝增长量
- fans_increase_rate = star["fansIncreaseRate"] # 粉丝增长率
- 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)
- print(f"{star_id}-{profile_id}获取列表入库成功")
- cls.ks_star_works_info(star_id, profile_id)
- time.sleep(random.randint(10, 20))
- cls.ks_list_portrait_info(star_id, profile_id)
- time.sleep(random.randint(10, 20))
- # # if res == 1:
- # current_time = datetime.now()
- # formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
- # if fans_min_num == 0:
- # fans = f"{fans_max_num}及以下"
- # if fans_max_num == 0:
- # fans = f"{fans_min_num}及以上"
- # else:
- # fans = f"{fans_min_num}~{fans_max_num}"
- # values = [
- # [
- # name,
- # gender,
- # fans_number,
- # profile_id,
- # "https://www.kuaishou.com/profile/"+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,
- # fans,
- # formatted_time
- # ]
- # ]
- # Feishu.insert_columns("GjGZsmW2ahaCe4tmzDTc58tVnbe", "COyUUm", "ROWS", 1, 2)
- # time.sleep(0.5)
- # Feishu.update_values("GjGZsmW2ahaCe4tmzDTc58tVnbe", "COyUUm", "A2:Z2", values)
- # print(f"入库到一条数据{content}")
- current_page += 1
- if total < 20:
- break
- else:
- page = int(total)/20
- if current_page > int(page)+1:
- break
- id = sqlCollect.select_ks_star_data(profile_id)
- if id:
- break
- except Exception as e:
- print(f"{e}")
- """
- 传播表现
- """
- @classmethod
- def ks_star_works_info(cls, star_id: str, profile_id: str):
- url = "https://k.kuaishou.com/rest/web/star/starWorksInfo"
- payload = json.dumps({
- "starId": star_id,
- "starType": 1
- })
- headers = {
- 'Accept': 'application/json',
- 'Accept-Language': 'zh-CN,zh;q=0.9',
- 'Connection': 'keep-alive',
- 'Content-Type': 'application/json',
- '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=',
- 'Origin': 'https://k.kuaishou.com',
- 'Referer': 'https://k.kuaishou.com/'
- }
- response = requests.request("POST", url, headers=headers, data=payload)
- response = response.json()
- result = response['result']
- if result == 1:
- try:
- star_work_report = response['starWorksInfo']['starWorkReport']
- pplay_median_data = star_work_report['pplayMedianData'] # 播放量中位数
- pplay_median_data_90 = pplay_median_data['90'] # 获取键 '90' 对应的值
- pplay_median_data_30 = pplay_median_data['30'] # 获取键 '30' 对应的值
- pphoto_cnt_data = star_work_report['pphotoCntData'] # 视频数量
- pphoto_cnt_data_90 = pphoto_cnt_data['90'] # 获取键 '90' 对应的值
- pphoto_cnt_data_30 = pphoto_cnt_data['30'] # 获取键 '30' 对应的值
- pavg_video_duration_data = star_work_report['pavgVideoDurationData'] # 平均时长
- # 处理 '90' 键的值
- value_90 = pavg_video_duration_data['90']
- pavg_video_duration_data_90 = f"{float(value_90):.3f}%" if value_90 else "0.000%"
- # 处理 '30' 键的值
- value_30 = pavg_video_duration_data['30']
- pavg_video_duration_data_30 = f"{float(value_30):.3f}%" if value_30 else "0.000%"
- pavg_like_cnt_data = star_work_report['pavgLikeCntData'] # 平均点赞
- star_work_report_90 = pavg_like_cnt_data['90'] # 获取键 '90' 对应的值
- star_work_report_30 = pavg_like_cnt_data['30'] # 获取键 '30' 对应的值
- pavg_share_cnt_data = star_work_report['pavgShareCntData'] # 平均分享
- pavg_share_cnt_90 = pavg_share_cnt_data['90'] # 获取键 '90' 对应的值
- pavg_share_cnt_30 = pavg_share_cnt_data['30'] # 获取键 '30' 对应的值
- 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)
- print(f"{star_id}-{profile_id}获取传播表现入库成功")
- except Exception as e:
- print(f"{star_id}-{profile_id}:{e}")
- else:
- print(f"{star_id}-{profile_id}获取传播表现失败")
- """
- 受众分析
- """
- @classmethod
- def ks_list_portrait_info(cls, star_id: str, profile_id: str):
- url = "https://k.kuaishou.com/rest/web/star/listPortrait"
- payload = json.dumps({
- "starId": star_id,
- "starType": 1
- })
- headers = {
- 'Accept': 'application/json',
- 'Accept-Language': 'zh-CN,zh;q=0.9',
- 'Connection': 'keep-alive',
- 'Content-Type': 'application/json',
- '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=',
- 'Origin': 'https://k.kuaishou.com',
- 'Referer': 'https://k.kuaishou.com/'
- }
- response = requests.request("POST", url, headers=headers, data=payload)
- response = response.json()
- result = response['result']
- if result == 1:
- viewer_portrait = response['data']['viewerPortrait']
- sex_percentage = viewer_portrait['sexPercentage'] # 性别占比
- try:
- for sex in sex_percentage:
- sex_type = 'sex_percentage'
- sex_name = sex['label']
- value = sex['value']
- sex_proportion = f"{float(value):.3f}%" if value else "0.000%"
- sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, sex_type, sex_name, sex_proportion)
- age_percentage = viewer_portrait['agePercentage'] # 年龄占比
- for age in age_percentage:
- age_type = 'age_percentage'
- age_name = age['label']
- value = age['value']
- age_proportion = f"{float(value):.3f}%" if value else "0.000%"
- sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, age_type, age_name, age_proportion)
- area_percentage = viewer_portrait['areaPercentage'] # 城市占比
- for area in area_percentage:
- area_type = 'area_percentage'
- area_name = area['label']
- value = area['value']
- area_proportion = f"{float(value):.3f}%" if value else "0.000%"
- sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, area_type, area_name, area_proportion)
- mobile_brand_percentage = viewer_portrait['mobileBrandPercentage'] # 设备占比
- for brand in mobile_brand_percentage:
- brand_type = 'mobile_brand_percentage'
- brand_name = brand['label']
- value = brand['value']
- brand_proportion = f"{float(value):.3f}%" if value else "0.000%"
- sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, brand_type, brand_name, brand_proportion)
- except Exception as e:
- print(f"{star_id}-{profile_id}:{e}")
- mobile_price_percentage = viewer_portrait['mobilePricePercentage'] # 设备价格占比
- for price in mobile_price_percentage:
- price_type = 'mobile_price_percentage'
- price_name = price['label']
- value = price['value']
- price_proportion = f"{float(value):.3f}%" if value else "0.000%"
- sqlCollect.insert_ks_list_portrait_info(star_id, profile_id, price_type, price_name, price_proportion)
- print(f"{star_id}-{profile_id}获取受众分析入库成功")
- else:
- print(f"{star_id}-{profile_id}获取受众分析失败")
- if __name__ == '__main__':
- QplKs.ks_star_info()
|