""" czzyv.com - 厂长资源 """ import re import json import time from urllib.parse import urljoin, quote, unquote, urlparse, parse_qs import requests from base.spider import Spider class Spider(Spider): def __init__(self): self.host = "https://czzyv.com" self.timeout = 20 self._hosts = [ "https://czzyv.com", "https://www.czzy.site", "https://www.cz4k.com", "https://cz01.vip", "https://cz01.tv", ] self.headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36", "Referer": "https://czzyv.com/", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.9", } self.session = None self._text_cache = {} self._text_cache_ttl = 300 self._api_base = "" self._use_api = False self._ua_fallback = "Dalvik/2.1.0 (Linux; U; Android 10)" self._class_map = [ ("最新电影", "zuixindianying", "/zuixindianying"), ("豆瓣Top250", "dbtop250", "/dbtop250"), ("国产剧", "gcj", "/gcj"), ("美剧", "meijutt", "/meijutt"), ("韩剧", "hanjutv", "/hanjutv"), ("日剧", "riju", "/riju"), ("番剧", "fanju", "/fanju"), ("剧场版", "dongmanjuchangban", "/dongmanjuchangban"), ("海外剧", "haiwaijuqita", "/haiwaijuqita"), ] self._tid_map = {} for n, tid, p in self._class_map: self._tid_map[tid] = p self._tid_map[n] = p self._tid_map[p] = p self._tid_map[p.lstrip("/")] = p def getName(self): return "厂长资源" def init(self, extend=""): if isinstance(extend, dict): host = (extend.get("host") or extend.get("site") or "").strip() if host: self.host = host.rstrip("/") elif isinstance(extend, str) and extend.strip(): ext_str = extend.strip() if (ext_str.startswith("{") and ext_str.endswith("}")) or (ext_str.startswith("[") and ext_str.endswith("]")): try: ext_obj = json.loads(ext_str) if isinstance(ext_obj, dict): host = (ext_obj.get("host") or ext_obj.get("site") or "").strip() if host: self.host = host.rstrip("/") except Exception: pass elif ext_str.startswith("http"): self.host = ext_str.rstrip("/") self.headers["Referer"] = self.host + "/" self.headers["Origin"] = self.host self.session = requests.Session() self.session.headers.update(self.headers) self._choose_host() self._detect_api() self._warmup() def isVideoFormat(self, url): pass def manualVideoCheck(self): pass def destroy(self): pass def _choose_host(self): if not self.session: return candidates = [] if self.host: candidates.append(self.host.rstrip("/")) for h in self._hosts: h = (h or "").rstrip("/") if h and h not in candidates: candidates.append(h) for h in candidates: try: r = self.session.get(h + "/", timeout=self.timeout, allow_redirects=True, verify=False) if not r or r.status_code != 200: continue r.encoding = "utf-8" text = r.text or "" if "访问已被拦截" in text or "已被拦截" in text: continue self.host = h self.headers["Referer"] = self.host + "/" self.headers["Origin"] = self.host self.session.headers.update(self.headers) self._text_cache.clear() return except Exception: continue def _detect_api(self): candidates = [ "/api.php/provide/vod?ac=list", "/api.php/provide/vod/?ac=list", "/index.php/api/vod?ac=list", ] for p in candidates: url = urljoin(self.host + "/", p.lstrip("/")) try: r = self.session.get(url, timeout=self.timeout, allow_redirects=True, verify=False) ct = (r.headers.get("Content-Type") or "").lower() if r.status_code == 200 and (("json" in ct) or ("xml" in ct) or r.text.strip().startswith(("{", "<"))): self._api_base = url.split("?", 1)[0] self._use_api = True return except Exception: continue self._api_base = "" self._use_api = False def _warmup(self): try: self.session.get(self.host + "/", timeout=self.timeout, allow_redirects=True, verify=False) except Exception: pass def _fetch_text(self, url): now = time.time() cached = self._text_cache.get(url) if cached and cached[0] > now: return cached[1] try: r = None for _ in range(3): try: r = self.session.get(url, timeout=self.timeout, allow_redirects=True, verify=False) break except Exception: time.sleep(1) if not r or r.status_code != 200: if r and r.status_code in (403, 406, 412): self.session.headers["User-Agent"] = self._ua_fallback try: r = self.session.get(url, timeout=self.timeout, allow_redirects=True, verify=False) except Exception: r = None if not r or r.status_code != 200: return "" r.encoding = "utf-8" text = r.text or "" if "访问已被拦截" in text or "已被拦截" in text: self.session.headers["User-Agent"] = self._ua_fallback try: r2 = self.session.get(url, timeout=self.timeout, allow_redirects=True, verify=False) if r2 and r2.status_code == 200: r2.encoding = "utf-8" text = r2.text or "" except Exception: pass if text: self._text_cache[url] = (now + self._text_cache_ttl, text) return text except Exception: return "" def _abs(self, href): return urljoin(self.host + "/", href or "") def _parse_pagecount(self, html, current_pg): m = re.findall(r"/page/(\d+)", html or "") nums = [int(x) for x in m if x.isdigit()] if nums: return max(max(nums), current_pg) return 999 def _parse_vod_list(self, html): html = html or "" vods = [] blocks = re.findall(r"(?is)