def get_detail(self, detail_page_url: str) -> AnimeDetailInfo: detail_api = self._base_url + detail_page_url resp = self.get(detail_api) if resp.status_code != 200: return AnimeDetailInfo() anime_detail = AnimeDetailInfo() detail = self.xpath(resp.text, "//div[@class='stui-pannel-box']")[0] cover_url = detail.xpath("div/a/img/@data-original")[0] if not cover_url.startswith("http"): cover_url = self._base_url + cover_url anime_detail.cover_url = cover_url anime_detail.title = detail.xpath("div/a/@title")[0] anime_detail.desc = detail.xpath( ".//span[@class='detail-content']/text()")[0] anime_detail.category = detail.xpath( ".//span[contains(text(), '类型')]/parent::p/a[1]/text()")[0] play_list_blocks = self.xpath( resp.text, "//div[@class='stui-pannel-box b playlist mb']") # 播放列表所在的区域 for block in play_list_blocks: vc = VideoCollection() vc.name = block.xpath("div/div/h3/font/text()")[0].strip() for video_block in block.xpath('.//li'): video = Video() video.name = video_block.xpath("a/text()")[0] video.raw_url = self._base_url + video_block.xpath( "a/@href")[0] video.handler = "K1080VideoHandler" # 绑定视频处理器 vc.append(video) if vc.num != 0: anime_detail.append(vc) return anime_detail
def get_detail(self, detail_page_url: str): detail_api = self._base_url + detail_page_url resp = self.get(detail_api) if resp.status_code != 200: return AnimeDetailInfo() body = self.xpath(resp.text, '//div[@id="container"]')[0] # 详细信息所在的区域 anime_detail = AnimeDetailInfo() anime_detail.title = body.xpath(".//h4/text()")[0] anime_detail.cover_url = "https:" + body.xpath( './/img[@class="poster"]/@src')[0] anime_detail.desc = "".join( body.xpath( './/div[@class="detail_imform_desc_pre"]//text()')).replace( "\r\n", "").strip() anime_detail.category = body.xpath( './/li[@class="detail_imform_kv"][9]/span[2]/text()')[0] play_list_blocks = body.xpath( './/div[@class="movurl"]') # 播放列表所在的区域, 可能有多个播放列表 for i, block in enumerate(play_list_blocks, 1): vc = VideoCollection() vc.name = "播放列表 " + str(i) for video_block in block.xpath('.//li'): video = Video() video.name = video_block.xpath("a/@title")[0] video.raw_url = video_block.xpath("a/@href")[ 0] # /play/20170172?playid=1_1 video.handler = "AgeFansVideoHandler" # 绑定视频处理器 vc.append(video) if vc.num != 0: # 可能有空的播放列表 anime_detail.append(vc) return anime_detail
def get_detail(self, detail_page_url: str): url = self._base_url + detail_page_url logger.info(f"Parsing detail page: {url}") resp = self.get(url) if resp.status_code != 200: logger.warning(f"Response error: {resp.status_code} {url}") return AnimeDetailInfo() body = self.xpath(resp.text, '//div[@class="fire l"]')[0] anime_detail = AnimeDetailInfo() anime_detail.title = body.xpath("./div/h1/text()")[0] anime_detail.category = " ".join( body.xpath('.//div[@class="sinfo"]/span[3]/a/text()')) anime_detail.desc = body.xpath( './/div[@class="info"]/text()')[0].replace("\r\n", "").strip() anime_detail.cover_url = body.xpath( './/div[@class="thumb l"]/img/@src')[0] vc = VideoCollection() vc.name = "播放列表" video_blocks = body.xpath('.//div[@class="movurl"]//li') for block in video_blocks: video = Video() video.name = block.xpath("./a/text()")[0] video.raw_url = block.xpath("./a/@href")[0] # '/v/3849-162.html' video.handler = "YHDMVideoHandler" vc.append(video) anime_detail.append(vc) return anime_detail
def get_detail(self, detail_id: str) -> AnimeDetailInfo: detail = AnimeDetailInfo() payload = { "service": "App.Vod.Video", "id": detail_id, "versionCode": 60 } payload.update(self.encrypt()) resp = self.post(self._api, data=payload) if resp.status_code != 200: return detail data = resp.json() data = list(filter(lambda x: x["type"] == "player", data["data"])) info = data[0]["player_vod"] detail.title = info["vod_name"] detail.desc = self.desc_format(info["vod_content"]) detail.cover_url = info["vod_pic"] for playlist in info["vod_play"]: vc = VideoCollection() vc.name = playlist["player_name_zh"] + playlist["title"] for video in playlist["players"]: url = video["url"].split("=")[-1] vc.append(Video( name=video["title"], raw_url=url )) detail.append(vc) return detail
def _get_detail(self, detail_page_url: str) -> AnimeDetailInfo: """引擎管理器负责调用, 捕获异常""" try: return self.get_detail(detail_page_url) except Exception as e: logger.exception(e) return AnimeDetailInfo()
def get_detail(self, anime_id: str): resp = self.get(self._detail_api, params={"id": anime_id}, headers=self._headers) if resp.status_code != 200: logger.warning(f"Response error: {resp.status_code} {self._search_api}") return AnimeDetailInfo() detail = resp.json().get("data") # 视频详情信息 anime_detail = AnimeDetailInfo() anime_detail.title = detail["name"] anime_detail.cover_url = detail["pic"] anime_detail.desc = detail["content"] # 完整的简介 anime_detail.category = detail["type"] for play_list in detail["parts"]: vc = VideoCollection() # 番剧的视频列表 vc.name = play_list["play_zh"] # 列表名, 线路 I, 线路 II for name in play_list["part"]: video_params = f"?id={anime_id}&play={play_list['play']}&part={name}" vc.append(Video(name, video_params, "BimibimiVideoHandler")) anime_detail.append(vc) return anime_detail
def get_detail(self, detail_page_url: str): resp = self.get(self._detail_api, params={"vid": detail_page_url}) if resp.status_code != 200 or resp.json()["code"] != 1: logger.warning( f"Response error: {resp.status_code} {self._search_api}") return AnimeDetailInfo() detail = resp.json().get("data") # 视频详情信息 anime_detail = AnimeDetailInfo() anime_detail.title = detail["name"] anime_detail.cover_url = detail["pic"] anime_detail.desc = detail["label"] anime_detail.category = detail["type"] vc = VideoCollection() vc.name = "视频列表" video_set = dict(detail["playUrl"]) for name, url in video_set.items(): vc.append(Video(name, url)) anime_detail.append(vc) return anime_detail
def get_anime_detail(self, meta: AnimeMetaInfo) -> AnimeDetailInfo: """解析一部番剧的详情页,返回包含视频列表的详细信息""" if not meta: logger.error(f"Invalid request") return AnimeDetailInfo() target_engine = self._engines.get(meta.engine) if target_engine is not None: return target_engine()._get_detail(meta.detail_page_url) # 如果引擎没加载, 临时加载一次 logger.info(f"Engine not found: {meta.engine}, it will be loaded temporarily.") self._load_engine(meta.engine) target_engine = self._engines.pop(meta.engine) logger.info(f"Unloading engine: {target_engine}") return target_engine()._get_detail(meta.detail_page_url)
def get_detail(self, detail_page_url: str): resp = self.get(self._detail_api, params={ "userid": "", "videoId": detail_page_url }) if resp.status_code != 200: logger.warning( f"Response error: {resp.status_code} {self._search_api}") return AnimeDetailInfo() detail = resp.json().get("data") # 视频详情信息 anime_detail = AnimeDetailInfo() anime_detail.title = detail["videoName"] anime_detail.cover_url = detail["videoImg"] anime_detail.desc = detail["videoDoc"].replace("\r\n", "") # 完整的简介 anime_detail.category = detail["videoClass"] for play_list in detail["videoSets"]: vc = VideoCollection() # 番剧的视频列表 vc.name = play_list["load"] # 列表名, 线路 I, 线路 II for video in play_list["list"]: vc.append( Video(video["ji"], video["playid"], "ZZFunVideoHandler")) anime_detail.append(vc) return anime_detail