From f9a273debd38dbc23fee76cb1ef6069ca456a2eb Mon Sep 17 00:00:00 2001 From: Harold <8866033@gmail.com> Date: Mon, 20 Apr 2026 13:04:16 +0800 Subject: [PATCH] feat: add categoryContent with area merge support Co-Authored-By: Claude Opus 4.7 --- py/tests/test_鲸鱼APP.py | 39 ++++++++++++++++++++++++++++ py/鲸鱼APP.py | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/py/tests/test_鲸鱼APP.py b/py/tests/test_鲸鱼APP.py index d7c5eed..4b40d61 100644 --- a/py/tests/test_鲸鱼APP.py +++ b/py/tests/test_鲸鱼APP.py @@ -91,3 +91,42 @@ class TestJingyuSpider(unittest.TestCase): area_values = [v["v"] for v in filters["1"][1]["value"]] self.assertIn("大陆", area_values) self.assertNotIn("中国大陆", area_values) + + def test_category_content_posts_filter_payload(self): + encrypted_empty = self.spider._aes_encrypt(json.dumps({"recommend_list": []})) + + class FakeRsp: + status_code = 200 + encoding = "utf-8" + def json(self): + return {"data": encrypted_empty} + + self.spider.post = lambda url, **kwargs: FakeRsp() + self.spider.host = "http://test.com" + self.spider.init_data = {} + result = self.spider.categoryContent("1", "2", False, {"area": "美国", "year": "2025"}) + self.assertEqual(result["page"], 2) + self.assertNotIn("pagecount", result) + self.assertEqual(result["list"], []) + + def test_category_content_merges_area_when_mainland_selected(self): + items_a = [{"vod_id": "1", "vod_name": "A", "vod_pic": "", "vod_remarks": ""}] + items_b = [{"vod_id": "2", "vod_name": "B", "vod_pic": "", "vod_remarks": ""}, + {"vod_id": "1", "vod_name": "A", "vod_pic": "", "vod_remarks": ""}] + + call_idx = {"n": 0} + + def fake_api_post(endpoint, payload=None): + call_idx["n"] += 1 + if call_idx["n"] == 1: + return {"recommend_list": items_a} + return {"recommend_list": items_b} + + self.spider._api_post = fake_api_post + self.spider.host = "http://test.com" + self.spider.init_data = {} + result = self.spider.categoryContent("1", "1", False, {"area": "大陆"}) + ids = [v["vod_id"] for v in result["list"]] + self.assertEqual(len(ids), 2) + self.assertIn("1", ids) + self.assertIn("2", ids) diff --git a/py/鲸鱼APP.py b/py/鲸鱼APP.py index b0868ef..9b77b66 100644 --- a/py/鲸鱼APP.py +++ b/py/鲸鱼APP.py @@ -164,3 +164,59 @@ class Spider(BaseSpider): "vod_remarks": item.get("vod_remarks", ""), }) return {"list": videos} + + def _merge_area_search(self, type_id, page, base_filters): + all_results = [] + seen = set() + for area_val in self.AREA_MERGE_LIST: + try: + payload = {"type_id": type_id, "page": page, "area": area_val} + payload.update(base_filters) + res = self._api_post("typeFilterVodList", payload) + for item in (res or {}).get("recommend_list", []): + vid = str(item.get("vod_id", "")) + if vid not in seen: + seen.add(vid) + all_results.append({ + "vod_id": vid, + "vod_name": item.get("vod_name", ""), + "vod_pic": item.get("vod_pic", ""), + "vod_remarks": item.get("vod_remarks", ""), + }) + except Exception as e: + self.log(f"聚合搜索地区[{area_val}]失败: {e}") + return all_results + + def categoryContent(self, tid, pg, filter, extend): + self.init() + page = int(pg) + ext = extend or {} + + if ext.get("area") == self.AREA_MERGE_DISPLAY: + base = {k: v for k, v in ext.items() if k != "area"} + base.setdefault("year", "全部") + base.setdefault("sort", "最新") + base.setdefault("lang", "全部") + base.setdefault("class", "全部") + merged = self._merge_area_search(tid, page, base) + return {"list": merged, "page": page, "limit": 90, "total": 999999} + + payload = { + "type_id": tid, + "page": page, + "area": ext.get("area", "全部"), + "year": ext.get("year", "全部"), + "sort": ext.get("by", ext.get("sort", "最新")), + "lang": ext.get("lang", "全部"), + "class": ext.get("class", "全部"), + } + res = self._api_post("typeFilterVodList", payload) + items = [] + for item in (res or {}).get("recommend_list", []): + items.append({ + "vod_id": str(item.get("vod_id", "")), + "vod_name": item.get("vod_name", ""), + "vod_pic": item.get("vod_pic", ""), + "vod_remarks": item.get("vod_remarks", ""), + }) + return {"list": items, "page": page, "limit": 90, "total": 999999}