Files
tvbox_collect/jaychouqq/yingshi/py3/wbbb1_spider.py
T
2026-06-29 03:41:14 +00:00

142 lines
7.6 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
import re, urllib.parse, json, base64
from bs4 import BeautifulSoup
from base.spider import Spider
class Spider(Spider):
def init(self, extend=""):
self.site_url = "https://wbbb1.com"
self.limit = 24
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Referer': self.site_url}
self.categories = [
{"type_id": "1", "type_name": "电影"},
{"type_id": "2", "type_name": "剧集"},
{"type_id": "3", "type_name": "动漫"},
{"type_id": "4", "type_name": "综艺"}
]
def _fetch(self, url):
try:
import requests
r = requests.get(url, headers=self.headers, timeout=15)
r.encoding = r.apparent_encoding or 'utf-8'
return r
except:
return None
def _parse_video_card(self, card):
link_elem = card.select_one('a') or card
href = link_elem.get('href', '')
match = re.search(r'/detail/(\d+)\.html', href)
if not match: return None
vod_id = match.group(1)
title_elem = card.select_one('.module-item-title') or card.select_one('.module-poster-item-title')
vod_name = title_elem.get_text(strip=True) if title_elem else ''
img_elem = card.select_one('img')
vod_pic = (img_elem.get('data-original', '') or img_elem.get('data-src', '') or img_elem.get('src', '')) if img_elem else ''
tag_elem = card.select_one('.module-item-note') or card.select_one('.module-item-text')
vod_remarks = tag_elem.get_text(strip=True) if tag_elem else ''
return {"vod_id": vod_id, "vod_name": vod_name, "vod_pic": vod_pic, "vod_remarks": vod_remarks}
def homeContent(self, filter):
url = f"{self.site_url}/"
resp = self._fetch(url)
video_list = []
if resp:
soup = BeautifulSoup(resp.text, 'html.parser')
cards = soup.select('.module-items .module-item') or soup.select('.module-items a.module-poster-item')
for card in cards[:24]:
item = self._parse_video_card(card)
if item: video_list.append(item)
return {"class": self.categories, "list": video_list, "filters": {}}
def categoryContent(self, tid, pg, filter, extend):
page = int(pg) if pg else 1
url = f"{self.site_url}/type/{tid}.html" if page == 1 else f"{self.site_url}/type/{tid}/{page}.html"
resp = self._fetch(url)
if not resp: return {"list": [], "page": page, "pagecount": 1, "limit": self.limit, "total": 0}
soup = BeautifulSoup(resp.text, 'html.parser')
video_list = []
cards = soup.select('.module-items .module-item') or soup.select('.module-items a.module-poster-item')
for card in cards:
item = self._parse_video_card(card)
if item: video_list.append(item)
pagecount = 1
for a in soup.select('.page-link') or soup.select('.pagination a'):
if a.get_text(strip=True).isdigit(): pagecount = max(pagecount, int(a.get_text(strip=True)))
return {"list": video_list, "page": page, "pagecount": pagecount, "limit": self.limit, "total": 0}
def detailContent(self, ids):
if not ids: return {"list": []}
vod_id = ids[0]
url = f"{self.site_url}/detail/{vod_id}.html"
resp = self._fetch(url)
if not resp: return {"list": []}
soup = BeautifulSoup(resp.text, 'html.parser')
vod_name = (t.get_text(strip=True) for t in [soup.select_one('.module-info-heading h1')] if t)
vod_name = next(vod_name, '')
img_elem = soup.select_one('.module-info-poster img')
vod_pic = (img_elem.get('data-original', '') or img_elem.get('src', '')) if img_elem else ''
desc_elem = soup.select_one('.module-info-introduction-content p')
vod_content = desc_elem.get_text(strip=True) if desc_elem else ''
vod_director = vod_actor = ''
for item in soup.select('.module-info-item'):
ts = item.select_one('.module-info-item-title')
cd = item.select_one('.module-info-item-content')
if not ts or not cd: continue
l = ts.get_text(strip=True)
if '导演' in l: vod_director = cd.get_text(strip=True)
if '主演' in l: vod_actor = cd.get_text(strip=True)
tab_items = soup.select('.module-tab-item')
play_containers = soup.select('.module-list.sort-list.tab-list')
play_from_list, play_url_list = [], []
if tab_items and play_containers and len(tab_items) == len(play_containers):
for idx, tab in enumerate(tab_items):
source_name = tab.get('data-dropdown-value', '') or tab.get_text(strip=True)
episodes = [f"{a.get_text(strip=True)}${a.get('href', '')}" for a in play_containers[idx].select('a.module-play-list-link') if a.get('href', '')]
if episodes: play_from_list.append(source_name); play_url_list.append('#'.join(episodes))
else:
all_items = soup.select('.module-play-list-content a.module-play-list-link')
if all_items:
episodes = [f"{a.get_text(strip=True)}${a.get('href', '')}" for a in all_items if a.get('href', '')]
if episodes: play_from_list.append('默认线路'); play_url_list.append('#'.join(episodes))
return {"list": [{"vod_id": vod_id, "vod_name": vod_name, "vod_pic": vod_pic, "vod_content": vod_content, "vod_director": vod_director, "vod_actor": vod_actor, "vod_play_from": '$$$'.join(play_from_list), "vod_play_url": '$$$'.join(play_url_list)}]}
def searchContent(self, key, quick, pg="1"):
page = int(pg) if pg else 1
url = f"{self.site_url}/search/{urllib.parse.quote(key)}-------------.html" if page == 1 else f"{self.site_url}/search/{urllib.parse.quote(key)}----------{page}---.html"
resp = self._fetch(url)
if not resp: return {"list": [], "page": page, "pagecount": 1}
soup = BeautifulSoup(resp.text, 'html.parser')
video_list = []
for card in soup.select('.module-items .module-item') or soup.select('.module-items a.module-poster-item'):
item = self._parse_video_card(card)
if item: video_list.append(item)
return {"list": video_list, "page": page, "pagecount": 1}
def playerContent(self, flag, id, vipFlags):
url = id if id.startswith('http') else self.site_url + id
resp = self._fetch(url)
if not resp: return {"parse": 1, "url": url, "header": self.headers}
html = resp.text
player_match = re.search(r'var player_aaaa=(\{.*?\})', html)
if not player_match: return {"parse": 1, "url": url, "header": self.headers}
try:
player_data = json.loads(player_match.group(1))
encrypt = player_data.get('encrypt', '0')
play_url = player_data.get('url', '')
if encrypt == '1':
play_url = urllib.parse.unquote(play_url)
elif encrypt == '2':
play_url = urllib.parse.unquote(base64.b64decode(play_url).decode('utf-8'))
# 构建解析器URL,包含next和title参数
next_url = player_data.get('link_next', '')
title = player_data.get('vod_name', '') or player_data.get('title', '')
parse_url = f"https://xn--qvr2v.850088.xyz/player/?url={play_url}&next={urllib.parse.quote(next_url)}&title={urllib.parse.quote(title)}"
return {"parse": 1, "url": parse_url, "header": self.headers}
except:
return {"parse": 1, "url": url, "header": self.headers}
def getName(self):
return "歪比巴卜"