From cef2a4b345855a664324ec5d0bb989d6b11c3376 Mon Sep 17 00:00:00 2001 From: Harold <8866033@gmail.com> Date: Sun, 19 Apr 2026 18:22:52 +0800 Subject: [PATCH] feat: scaffold dida spider --- py/tests/test_滴答影视.py | 45 +++++++++++++++ py/滴答影视.py | 114 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 py/tests/test_滴答影视.py create mode 100644 py/滴答影视.py diff --git a/py/tests/test_滴答影视.py b/py/tests/test_滴答影视.py new file mode 100644 index 0000000..f532268 --- /dev/null +++ b/py/tests/test_滴答影视.py @@ -0,0 +1,45 @@ +import unittest +from importlib.machinery import SourceFileLoader +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +MODULE = SourceFileLoader("dida_spider", str(ROOT / "滴答影视.py")).load_module() +Spider = MODULE.Spider + + +class TestDidaSpider(unittest.TestCase): + def setUp(self): + Spider._instance = None + self.spider = Spider() + self.spider.init() + + def test_home_content_exposes_expected_classes_and_filters(self): + content = self.spider.homeContent(False) + self.assertEqual( + [item["type_id"] for item in content["class"]], + ["1", "2", "5", "4", "3"], + ) + self.assertEqual( + [item["key"] for item in content["filters"]["1"]], + ["class", "area", "year", "lang", "sort"], + ) + + def test_home_video_content_returns_empty_list(self): + self.assertEqual(self.spider.homeVideoContent(), {"list": []}) + + def test_build_category_url_applies_default_and_selected_filters(self): + url = self.spider._build_category_url( + "1", + "2", + {"area": "香港", "sort": "score", "class": "动作", "lang": "粤语", "year": "2025"}, + ) + self.assertEqual(url, "https://www.didahd.pro/show/1-香港-score-动作-粤语----2---2025") + + def test_build_category_url_for_first_page_keeps_page_segment(self): + url = self.spider._build_category_url("2", "1", {}) + self.assertEqual(url, "https://www.didahd.pro/show/2--time------1---") + + +if __name__ == "__main__": + unittest.main() diff --git a/py/滴答影视.py b/py/滴答影视.py new file mode 100644 index 0000000..09c5150 --- /dev/null +++ b/py/滴答影视.py @@ -0,0 +1,114 @@ +# coding=utf-8 +import json +import sys + +from base.spider import Spider as BaseSpider + +sys.path.append("..") + + +class Spider(BaseSpider): + def __init__(self): + self.name = "滴答影视" + self.host = "https://www.didahd.pro" + self.headers = { + "User-Agent": ( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/120.0.0.0 Safari/537.36" + ), + "Referer": self.host + "/", + } + self.classes = [ + {"type_id": "1", "type_name": "电影"}, + {"type_id": "2", "type_name": "电视剧"}, + {"type_id": "5", "type_name": "综艺"}, + {"type_id": "4", "type_name": "动漫"}, + {"type_id": "3", "type_name": "纪录片"}, + ] + self.filter_def = { + "1": {"cateId": "1", "area": "", "sort": "time", "class": "", "lang": "", "letter": "", "year": ""}, + "2": {"cateId": "2", "area": "", "sort": "time", "class": "", "lang": "", "letter": "", "year": ""}, + "3": {"cateId": "3", "area": "", "sort": "time", "class": "", "lang": "", "letter": "", "year": ""}, + "4": {"cateId": "4", "area": "", "sort": "time", "class": "", "lang": "", "letter": "", "year": ""}, + "5": {"cateId": "5", "area": "", "sort": "time", "class": "", "lang": "", "letter": "", "year": ""}, + } + self.filters = { + "1": [ + {"key": "class", "name": "按剧情", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "area", "name": "按地区", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "year", "name": "按年份", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "lang", "name": "按语言", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "sort", "name": "按排序", "init": "time", "value": [{"n": "时间", "v": "time"}]}, + ], + "2": [ + {"key": "class", "name": "按剧情", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "area", "name": "按地区", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "year", "name": "按年份", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "lang", "name": "按语言", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "sort", "name": "按排序", "init": "time", "value": [{"n": "时间", "v": "time"}]}, + ], + "3": [ + {"key": "year", "name": "按年份", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "lang", "name": "按语言", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "sort", "name": "按排序", "init": "time", "value": [{"n": "时间", "v": "time"}]}, + ], + "4": [ + {"key": "year", "name": "按年份", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "lang", "name": "按语言", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "sort", "name": "按排序", "init": "time", "value": [{"n": "时间", "v": "time"}]}, + ], + "5": [ + {"key": "class", "name": "按剧情", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "year", "name": "按年份", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "lang", "name": "按语言", "init": "", "value": [{"n": "全部", "v": ""}]}, + {"key": "sort", "name": "按排序", "init": "time", "value": [{"n": "时间", "v": "time"}]}, + ], + } + + def init(self, extend=""): + return None + + def getName(self): + return self.name + + def homeContent(self, filter): + return {"class": self.classes, "filters": self.filters} + + def homeVideoContent(self): + return {"list": []} + + def _stringify(self, value): + return "" if value is None else str(value) + + def _normalize_ext(self, extend): + if isinstance(extend, dict): + return extend + if not extend: + return {} + try: + return json.loads(str(extend)) + except Exception: + return {} + + def _build_url(self, path): + raw = self._stringify(path).strip() + if not raw: + return "" + if raw.startswith(("http://", "https://")): + return raw + if raw.startswith("//"): + return "https:" + raw + if raw.startswith("/"): + return self.host + raw + return self.host + "/" + raw + + def _build_category_url(self, tid, pg, extend): + values = dict(self.filter_def.get(str(tid), {"cateId": str(tid), "sort": "time"})) + values.update(self._normalize_ext(extend)) + path = ( + f"show/{values.get('cateId', tid)}-{values.get('area', '')}-{values.get('sort', 'time')}-" + f"{values.get('class', '')}-{values.get('lang', '')}-{values.get('letter', '')}---{int(pg)}---" + f"{values.get('year', '')}" + ) + return self._build_url(path)