diff --git a/py/tests/test_腾讯视频.py b/py/tests/test_腾讯视频.py index 9d9b85c..e7671c4 100644 --- a/py/tests/test_腾讯视频.py +++ b/py/tests/test_腾讯视频.py @@ -120,6 +120,42 @@ class TestTencentSpider(unittest.TestCase): result = self.spider._get_batch_video_info(["vid001"]) self.assertEqual(result, [{"vid": "vid001", "title": "第1集", "type": "正片"}]) + @patch.object(Spider, "_get_batch_video_info") + @patch.object(Spider, "fetch") + def test_detail_content_merges_main_and_trailer_into_single_line(self, mock_fetch, mock_get_batch_video_info): + mock_fetch.return_value = SimpleNamespace( + json=lambda: { + "c": { + "title": "斗罗大陆", + "year": "2024", + "description": "热血冒险", + "pic": "/cover.jpg", + "video_ids": ["vid001", "vid002"], + }, + "typ": ["热血", "冒险"], + "nam": ["配音甲", "配音乙"], + "rec": "更新中", + } + ) + mock_get_batch_video_info.return_value = [ + {"vid": "vid001", "title": "1", "type": "正片"}, + {"vid": "vid002", "title": "终极预告", "type": "预告"}, + ] + + result = self.spider.detailContent(["tv$cid001"]) + vod = result["list"][0] + + self.assertEqual(vod["vod_id"], "tv$cid001") + self.assertEqual(vod["vod_name"], "斗罗大陆") + self.assertEqual(vod["type_name"], "热血,冒险") + self.assertEqual(vod["vod_actor"], "配音甲,配音乙") + self.assertEqual(vod["vod_pic"], "https://v.qq.com/cover.jpg") + self.assertEqual(vod["vod_play_from"], "腾讯视频") + self.assertEqual( + vod["vod_play_url"], + "第1集$https://v.qq.com/x/cover/cid001/vid001.html#终极预告$https://v.qq.com/x/cover/cid001/vid002.html", + ) + if __name__ == "__main__": unittest.main() diff --git a/py/腾讯视频.py b/py/腾讯视频.py index b0a981d..0fb23ca 100644 --- a/py/腾讯视频.py +++ b/py/腾讯视频.py @@ -146,3 +146,41 @@ class Spider(BaseSpider): "limit": 21, "total": 999999, } + + def detailContent(self, ids): + result = {"list": []} + for raw_id in ids or []: + parts = str(raw_id).split("$", 1) + target_cid = parts[1] if len(parts) > 1 else parts[0] + url = f"https://node.video.qq.com/x/api/float_vinfo2?cid={target_cid}" + try: + payload = self.fetch(url, headers=self._headers()).json() + except Exception: + continue + cover = ((payload.get("c") or {}).get("pic") or "") + vod = { + "vod_id": raw_id, + "vod_name": ((payload.get("c") or {}).get("title") or ""), + "type_name": ",".join(payload.get("typ", []) or []), + "vod_actor": ",".join(payload.get("nam", []) or []), + "vod_year": ((payload.get("c") or {}).get("year") or ""), + "vod_content": ((payload.get("c") or {}).get("description") or ""), + "vod_remarks": payload.get("rec", "") or "", + "vod_pic": cover if cover.startswith("http") else self.base_host + cover, + "vod_play_from": "", + "vod_play_url": "", + } + video_ids = ((payload.get("c") or {}).get("video_ids") or []) + if video_ids: + detail_map = {item.get("vid"): item for item in self._get_batch_video_info(video_ids)} + play_items = [] + for vid in video_ids: + item = detail_map.get(vid, {"title": "", "type": ""}) + display_title = (item.get("title") or "选集").strip() + if re.fullmatch(r"\d+", display_title): + display_title = f"第{display_title}集" + play_items.append(f"{display_title}${self.base_host}/x/cover/{target_cid}/{vid}.html") + vod["vod_play_from"] = "腾讯视频" + vod["vod_play_url"] = "#".join(play_items) + result["list"].append(vod) + return result