# coding=utf-8 # !/usr/bin/python # by嗷呜 import random import sys from base64 import b64encode, b64decode from concurrent.futures import ThreadPoolExecutor, as_completed from pprint import pprint from urllib.parse import urlencode sys.path.append('..') from base.spider import Spider class Spider(Spider): def init(self, extend=""): self.did = self.random_str(32) pass def getName(self): pass def isVideoFormat(self, url): pass def manualVideoCheck(self): pass def destroy(self): pass rhost = 'https://www.iqiyi.com' hhost='https://mesh.if.iqiyi.com' dhost='https://miniapp.iqiyi.com' headers = { 'Origin': rhost, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36', 'Referer': f'{rhost}/', } def homeContent(self, filter): result = {} cateManual = { "全部": "1009", "电影": "1", "剧集": "2", "综艺": "6", "动漫": "4", "儿童": "15", "微剧": "35", "纪录片": "3" } classes = [] filters = {} for k in cateManual: classes.append({ 'type_name': k, 'type_id': cateManual[k] }) with ThreadPoolExecutor(max_workers=len(classes)) as executor: results = executor.map(self.getf, classes) for id, ft in results: if len(ft):filters[id] = ft result['class'] = classes result['filters'] = filters return result def homeVideoContent(self): data=self.fetch(f'{self.hhost}/portal/lw/v5/channel/recommend?v=13.014.21150', headers=self.headers).json() vlist = [] for i in data['items']: for j in i['video'][0]['data']: id = j.get('firstId') if id: pu=j.get('prevue',{}).get('page_url') or j.get('page_url').split('?')[0] id = f'{id}@{self.e64(pu)}' vlist.append({ 'vod_id': id, 'vod_name': j.get('display_name'), 'vod_pic': j.get('prevue',{}).get('image_url'), 'vod_year': j.get('sns_score'), 'vod_remarks': j.get('dq_updatestatus') or j.get('rank_prefix') }) return {'list':vlist} def categoryContent(self, tid, pg, filter, extend): if pg == "1": self.sid = '' new_data = {'mode':'24'} for key, value in extend.items(): if value: key_value_pairs = self.d64(value).split(',') for pair in key_value_pairs: k, v = pair.split('=') if k in new_data: new_data[k] += "," + v else: new_data[k] = v path=f'/portal/lw/videolib/data?uid=&passport_id=&ret_num=60&version=13.014.21150&device_id={self.did}&channel_id={tid}&page_id={pg}&session={self.sid}&os=&conduit_id=&vip=0&auth&recent_selected_tag=&ad=%5B%7B%22lm%22:%225%22,%22ai%22:%225%22,%22fp%22:%226%22,%22sei%22:%22Sa867aa9d326e2bd8654d8c2a8636055e%22,%22position%22:%22library%22%7D%5D&adExt=%7B%22r%22:%221.2.1-ares6-pure%22%7D&dfp=a12f96215b2f7842a98c082799ca0c3d9236be00946701b106829754d8ece3aaf8&filter={urlencode(new_data)}' data=self.fetch(f'{self.hhost}{path}', headers=self.headers).json() self.sid = data['session'] videos = [] for i in data['data']: id = i.get('firstId') or i.get('tv_id') if not id: id=i.get('play_url').split(';')[0].split('=')[-1] if id and not i.get('h'): id=f'{id}@{self.e64(i.get("page_url"))}' videos.append({ 'vod_id': id, 'vod_name': i.get('display_name'), 'vod_pic': i.get('album_image_url_hover'), 'vod_year': i.get('sns_score'), 'vod_remarks': i.get('dq_updatestatus') or i.get('pay_mark') }) result = {} result['list'] = videos result['page'] = pg result['pagecount'] = 9999 result['limit'] = 90 result['total'] = 999999 return result def detailContent(self, ids): ids = ids[0].split('@') ids[-1] = self.d64(ids[-1]) data = self.fetch(f'{self.dhost}/h5/mina/baidu/play/body/v1/{ids[0]}/', headers=self.headers).json() # t=str(int(time.time()*1000)) # e = 'ad_ext={"r":"1.2.1-ares6-pure"}&ad_param=[{"azt":"730","azd":"1000000000942","lm":1,"position":"related"},{"azt":"731","azd":"1000000000943","lm":1,"position":"recommend"},{"azt":"734","azd":"1000000000910","lm":1,"position":"middlecard"},{"azt":"738","azd":"1000000000911","lm":1,"position":"bottomcard"},{"azt":"612","azd":"1000000000695","lm":2,"position":"recommend_full"},{"azt":"","azd":"1000000000912","lm":1,"position":"rcd_image"}]&app_mode=standard&app_version=13.014.21150&auth_cookie=&conduit_id=&device_id='+self.did+'&entity_id='+ids[0]+'&entity_type=1&filter=&ext=&os=&src=pca_tvg×tamp=' + t + '&user_id=0&vip_status=0&vip_type=-1&secret_key=howcuteitis' # sign=self.md5(e).upper() # path=f'/tvg/v2/lw/base_info?entity_id={ids[0]}&device_id={self.did}&auth_cookie&user_id=0&vip_type=-1&vip_status=0&conduit_id&app_version=13.014.21150&ext&app_mode=standard×tamp={t}&src=pca_tvg&os&ad_param=%5B%7B%22azt%22:%22730%22,%22azd%22:%221000000000942%22,%22lm%22:1,%22position%22:%22related%22%7D,%7B%22azt%22:%22731%22,%22azd%22:%221000000000943%22,%22lm%22:1,%22position%22:%22recommend%22%7D,%7B%22azt%22:%22734%22,%22azd%22:%221000000000910%22,%22lm%22:1,%22position%22:%22middlecard%22%7D,%7B%22azt%22:%22738%22,%22azd%22:%221000000000911%22,%22lm%22:1,%22position%22:%22bottomcard%22%7D,%7B%22azt%22:%22612%22,%22azd%22:%221000000000695%22,%22lm%22:2,%22position%22:%22recommend_full%22%7D,%7B%22azt%22:%22%22,%22azd%22:%221000000000912%22,%22lm%22:1,%22position%22:%22rcd_image%22%7D%5D&ad_ext=%7B%22r%22:%221.2.1-ares6-pure%22%7D&sign={sign}' # vdata=self.fetch(f'{self.hhost}{path}', headers=self.headers).json() # print(vdata) v=data['data']['playInfo'] vod = { 'vod_name': v.get('albumName'), 'type_name': v.get('tags'), 'vod_year': v.get('albumYear'), 'vod_remarks': v.get('updateStrategy'), 'vod_actor': v.get('mainActors'), 'vod_director': v.get('directors'), 'vod_content': v.get('albumDesc'), 'vod_play_from': '爱奇艺', 'vod_play_url': '' } if data.get('data') and data['data'].get('videoList') and data['data']['videoList'].get('videos'): purl=[f'{i["shortTitle"]}${i["pageUrl"]}' for i in data['data']['videoList']['videos']] pg=data['data']['videoList'].get('totalPages') if pg and pg > 1: id = v['albumId'] pages = list(range(2, pg + 1)) page_results = {} with ThreadPoolExecutor(max_workers=10) as executor: future_to_page = { executor.submit(self.fetch_page_data, page, id): page for page in pages } for future in as_completed(future_to_page): page = future_to_page[future] try: result = future.result() page_results[page] = result except Exception as e: print(f"Error fetching page {page}: {e}") for page in sorted(page_results.keys()): purl.extend(page_results[page]) vod['vod_play_url'] = '#'.join(purl) else: vdata=self.fetch(f'{self.dhost}/h5/mina/baidu/play/head/v1/{ids[0]}/', headers=self.headers).json() v=vdata['data']['playInfo'] vod = { 'vod_name': v.get('shortTitle'), 'type_name': v.get('channelName'), 'vod_year': v.get('year'), 'vod_remarks': v.get('focus'), 'vod_actor': v.get('mainActors'), 'vod_director': v.get('directors'), 'vod_content': v.get('desc'), 'vod_play_from': '爱奇艺', 'vod_play_url': f'{v.get("shortTitle")}${ids[-1]}' } return {'list':[vod]} def searchContent(self, key, quick, pg="1"): data=self.fetch(f'{self.hhost}/portal/lw/search/homePageV3?key={key}¤t_page={pg}&mode=1&source=input&suggest=&version=13.014.21150&pageNum={pg}&pageSize=25&pu=&u={self.did}&scale=150&token=&userVip=0&conduit=&vipType=-1&os=&osShortName=win10&dataType=&appMode=', headers=self.headers).json() videos = [] vdata=data['data']['templates'] for i in data['data']['templates']: if i.get('intentAlbumInfos'): vdata=[{'albumInfo': c} for c in i['intentAlbumInfos']]+vdata for i in vdata: if i.get('albumInfo') and (i['albumInfo'].get('playQipuId','') or i['albumInfo'].get('qipuId')) and i['albumInfo'].get('pageUrl'): b=i['albumInfo'] id=f"{(b.get('playQipuId','') or b.get('qipuId'))}@{self.e64(b.get('pageUrl'))}" videos.append({ 'vod_id': id, 'vod_name': b.get('title'), 'vod_pic': b.get('img'), 'vod_year': (b.get('year',{}) or {}).get('value'), 'vod_remarks': b.get('subscriptContent') or b.get('channel') or b.get('vipTips') }) return {'list':videos,'page':pg} def playerContent(self, flag, id, vipFlags): video_url = f'https://jx.xmflv.com/?url={id}' return {'parse': 1, 'url': video_url, 'header': ''} def localProxy(self, param): pass def fetch_page_data(self, page, id): try: url = f'{self.dhost}/h5/mina/avlist/{page}/{id}/' data = self.fetch(url, headers=self.headers).json() return [f'{i["shortTitle"]}${i["pageUrl"]}' for i in data['data']['videoList']['videos']] except: return [] def getf(self,body): data=self.fetch(f'{self.hhost}/portal/lw/videolib/tag?channel_id={body["type_id"]}&tagAdd=&selected_tag_name=&version=13.014.21150&device={self.did}&uid=', headers=self.headers).json() ft = [] # for i in data[:-1]: for i in data: try: value_array = [{"n": value['text'], "v": self.e64(value['tag_param'])} for value in i['tags'] if value.get('tag_param')] ft.append({"key": i['group'], "name": i['group'], "value": value_array}) except: print(i) return (body['type_id'], ft) def e64(self, text): try: text_bytes = text.encode('utf-8') encoded_bytes = b64encode(text_bytes) return encoded_bytes.decode('utf-8') except Exception as e: print(f"Base64编码错误: {str(e)}") return "" def d64(self,encoded_text: str): try: encoded_bytes = encoded_text.encode('utf-8') decoded_bytes = b64decode(encoded_bytes) return decoded_bytes.decode('utf-8') except Exception as e: print(f"Base64解码错误: {str(e)}") return "" def random_str(self,length=16): hex_chars = '0123456789abcdef' return ''.join(random.choice(hex_chars) for _ in range(length))