两个BT.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # File : 两个BT.py
  4. # Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------
  5. # Author's Blog: https://blog.csdn.net/qq_32394351
  6. # Date : 2024/1/8
  7. import os.path
  8. import sys
  9. sys.path.append('..')
  10. try:
  11. # from base.spider import Spider as BaseSpider
  12. from base.spider import BaseSpider
  13. except ImportError:
  14. from t4.base.spider import BaseSpider
  15. import json
  16. import time
  17. import base64
  18. import re
  19. from pathlib import Path
  20. import io
  21. import tokenize
  22. from urllib.parse import quote
  23. from Crypto.Cipher import AES, PKCS1_v1_5 as PKCS1_cipher
  24. from Crypto.Util.Padding import unpad
  25. """
  26. 配置示例:
  27. t4的配置里ext节点会自动变成api对应query参数extend,但t4的ext字符串不支持路径格式,比如./开头或者.json结尾
  28. api里会自动含有ext参数是base64编码后的选中的筛选条件
  29. {
  30. "key":"hipy_t4_两个BT",
  31. "name":"两个BT(hipy_t4)",
  32. "type":4,
  33. "api":"http://192.168.31.49:5707/api/v1/vod/两个BT?api_ext={{host}}/txt/hipy/两个BT.json",
  34. "searchable":1,
  35. "quickSearch":0,
  36. "filterable":1,
  37. "ext":"{{host}}/files/hipy/两个BT.json"
  38. },
  39. {
  40. "key": "hipy_t3_两个BT",
  41. "name": "两个BT(hipy_t3)",
  42. "type": 3,
  43. "api": "{{host}}/txt/hipy/两个BT.py",
  44. "searchable": 1,
  45. "quickSearch": 0,
  46. "filterable": 1,
  47. "ext": "{{host}}/files/hipy/两个BT.json"
  48. },
  49. """
  50. class Spider(BaseSpider): # 元类 默认的元类 type
  51. api: str = 'https://www.bttwo.org'
  52. api_ext_file: str = api + '/movie_bt/'
  53. search_api: str = ''
  54. def getName(self):
  55. return "规则名称如:基础示例"
  56. def init_api_ext_file(self):
  57. """
  58. 这个函数用于初始化py文件对应的json文件,用于存筛选规则。
  59. 执行此函数会自动生成筛选文件
  60. @return:
  61. """
  62. ext_file = __file__.replace('.py', '.json')
  63. print(f'ext_file:{ext_file}')
  64. # 全部电影网页: https://www.bttwo.org/movie_bt/
  65. # ==================== 获取全部电影筛选条件 ======================
  66. r = self.fetch(self.api_ext_file)
  67. html = r.text
  68. html = self.html(html)
  69. filter_movie_bt = []
  70. lis = html.xpath('//*[@id="beautiful-taxonomy-filters-tax-movie_bt_cat"]/a')
  71. li_value = []
  72. for li in lis:
  73. li_value.append({
  74. 'n': ''.join(li.xpath('./text()')),
  75. 'v': ''.join(li.xpath('@cat-url')).replace(self.api, ''),
  76. })
  77. # print(li_value)
  78. filter_movie_bt.append({
  79. "key": "cat",
  80. "name": "地区",
  81. "value": li_value
  82. })
  83. lis = html.xpath('//*[@id="beautiful-taxonomy-filters-tax-movie_bt_year"]/a')
  84. li_value = []
  85. for li in lis:
  86. li_value.append({
  87. 'n': ''.join(li.xpath('./text()')),
  88. 'v': ''.join(li.xpath('@cat-url')).replace(self.api, ''),
  89. })
  90. # print(li_value)
  91. filter_movie_bt.append({
  92. "key": "year",
  93. "name": "年份",
  94. "value": li_value
  95. })
  96. lis = html.xpath('//*[@id="beautiful-taxonomy-filters-tax-movie_bt_tags"]/a')
  97. li_value = []
  98. for li in lis:
  99. li_value.append({
  100. 'n': ''.join(li.xpath('./text()')),
  101. 'v': ''.join(li.xpath('@cat-url')).replace(self.api, ''),
  102. })
  103. # print(li_value)
  104. filter_movie_bt.append({
  105. "key": "tags",
  106. "name": "影片类型",
  107. "value": li_value
  108. })
  109. print(filter_movie_bt)
  110. ext_file_dict = {
  111. "movie_bt": filter_movie_bt,
  112. }
  113. with open(ext_file, mode='w+', encoding='utf-8') as f:
  114. f.write(json.dumps(ext_file_dict, ensure_ascii=False))
  115. def init(self, extend=""):
  116. """
  117. 初始化加载extend,一般与py文件名同名的json文件作为扩展筛选
  118. @param extend:
  119. @return:
  120. """
  121. def init_file(ext_file):
  122. """
  123. 根据与py对应的json文件去扩展规则的筛选条件
  124. """
  125. ext_file = Path(ext_file).as_posix()
  126. if os.path.exists(ext_file):
  127. with open(ext_file, mode='r', encoding='utf-8') as f:
  128. try:
  129. ext_dict = json.loads(f.read())
  130. self.config['filter'].update(ext_dict)
  131. except Exception as e:
  132. print(f'更新扩展筛选条件发生错误:{e}')
  133. ext = self.extend
  134. print(f"============{extend}============")
  135. if isinstance(ext, str):
  136. if ext.startswith('./'):
  137. ext_file = os.path.join(os.path.dirname(__file__), ext)
  138. init_file(ext_file)
  139. elif ext.startswith('http'):
  140. try:
  141. r = self.fetch(ext)
  142. self.config['filter'].update(r.json())
  143. except Exception as e:
  144. print(f'更新扩展筛选条件发生错误:{e}')
  145. elif not ext.startswith('./') and not ext.startswith('http'):
  146. ext_file = os.path.join(os.path.dirname(__file__), './' + ext + '.json')
  147. init_file(ext_file)
  148. # 装载模块,这里只要一个就够了
  149. if isinstance(extend, list):
  150. for lib in extend:
  151. if '.Spider' in str(type(lib)):
  152. self.module = lib
  153. break
  154. def isVideo(self):
  155. """
  156. 返回是否为视频的匹配字符串
  157. @return: None空 reg:正则表达式 js:input js代码
  158. """
  159. # return 'js:input.includes("https://zf.13to.com/")?true:false'
  160. return 'reg:zf\.13to\.com'
  161. def isVideoFormat(self, url):
  162. pass
  163. def manualVideoCheck(self):
  164. pass
  165. def homeContent(self, filterable=False):
  166. """
  167. 获取首页分类及筛选数据
  168. @param filterable: 能否筛选,跟t3/t4配置里的filterable参数一致
  169. @return:
  170. """
  171. class_name = '影片库&最新电影&热门下载&本月热门&国产剧&美剧&日韩剧' # 静态分类名称拼接
  172. class_url = 'movie_bt&new-movie&hot&hot-month&zgjun&meiju&jpsrtv' # 静态分类标识拼接
  173. result = {}
  174. classes = []
  175. if all([class_name, class_url]):
  176. class_names = class_name.split('&')
  177. class_urls = class_url.split('&')
  178. cnt = min(len(class_urls), len(class_names))
  179. for i in range(cnt):
  180. classes.append({
  181. 'type_name': class_names[i],
  182. 'type_id': class_urls[i]
  183. })
  184. result['class'] = classes
  185. if filterable:
  186. result['filters'] = self.config['filter']
  187. return result
  188. def homeVideoContent(self):
  189. """
  190. 首页推荐列表
  191. @return:
  192. """
  193. r = self.fetch(self.api)
  194. html = r.text
  195. html = self.html(html)
  196. d = []
  197. self.search_api = "".join(html.xpath('//*[contains(@class,"w-search-form")]/@action')).strip()
  198. lis = html.xpath('//*[contains(@class,"leibox")]/ul/li')
  199. print(len(lis))
  200. for li in lis:
  201. d.append({
  202. 'vod_name': ''.join(li.xpath('h3//text()')),
  203. 'vod_id': ''.join(li.xpath('a/@href')),
  204. 'vod_pic': ''.join(li.xpath('.//img//@data-original')),
  205. 'vod_remarks': ''.join(li.xpath('.//*[contains(@class,"jidi")]//text()')),
  206. })
  207. result = {
  208. 'list': d
  209. }
  210. return result
  211. def categoryContent(self, tid, pg, filterable, extend):
  212. """
  213. 返回一级列表页数据
  214. @param tid: 分类id
  215. @param pg: 当前页数
  216. @param filterable: 能否筛选
  217. @param extend: 当前筛选数据
  218. @return:
  219. """
  220. page_count = 24 # 默认赋值一页列表24条数据
  221. if tid != 'movie_bt':
  222. url = self.api + f'/{tid}/page/{pg}'
  223. else:
  224. fls = extend.keys() # 哪些刷新数据
  225. url = self.api + f'/{tid}'
  226. if 'cat' in fls:
  227. url += extend['cat']
  228. if 'year' in fls:
  229. url += extend['year']
  230. if 'tags' in fls:
  231. url += extend['tags']
  232. url += f'/page/{pg}'
  233. print(url)
  234. r = self.fetch(url)
  235. html = r.text
  236. html = self.html(html)
  237. d = []
  238. lis = html.xpath('//*[contains(@class,"bt_img")]/ul/li')
  239. # print(len(lis))
  240. for li in lis:
  241. d.append({
  242. 'vod_name': ''.join(li.xpath('h3//text()')),
  243. 'vod_id': ''.join(li.xpath('a/@href')),
  244. 'vod_pic': ''.join(li.xpath('.//img//@data-original')),
  245. 'vod_remarks': ''.join(li.xpath('.//*[contains(@class,"hdinfo")]//text()')),
  246. })
  247. result = {
  248. 'list': d,
  249. 'page': pg,
  250. 'pagecount': 9999 if len(d) >= page_count else pg,
  251. 'limit': 90,
  252. 'total': 999999,
  253. }
  254. return result
  255. def detailContent(self, ids):
  256. """
  257. 返回二级详情页数据
  258. @param ids: 一级传过来的vod_id列表
  259. @return:
  260. """
  261. vod_id = ids[0]
  262. r = self.fetch(vod_id)
  263. html = r.text
  264. html = self.html(html)
  265. lis = html.xpath('//*[contains(@class,"dytext")]/ul/li')
  266. plis = html.xpath('//*[contains(@class,"paly_list_btn")]/a')
  267. vod = {"vod_id": vod_id,
  268. "vod_name": ''.join(html.xpath('//*[contains(@class,"dytext")]//h1//text()')),
  269. "vod_pic": ''.join(html.xpath('//*[contains(@class,"dyimg")]/img/@src')),
  270. "type_name": ''.join(lis[0].xpath('.//text()')) if len(lis) > 0 else '',
  271. "vod_year": ''.join(lis[2].xpath('.//text()')) if len(lis) > 2 else '',
  272. "vod_area": ''.join(lis[1].xpath('.//text()')) if len(lis) > 1 else '',
  273. "vod_remarks": ''.join(lis[4].xpath('.//text()')) if len(lis) > 4 else '',
  274. "vod_actor": ''.join(lis[7].xpath('.//text()')) if len(lis) > 7 else '',
  275. "vod_director": ''.join(lis[5].xpath('.//text()')) if len(lis) > 5 else '',
  276. "vod_content": ''.join(html.xpath('//*[contains(@class,"yp_context")]/p//text()')),
  277. "vod_play_from": '在线播放',
  278. "vod_play_url": '选集播放1$1.mp4#选集播放2$2.mp4$$$选集播放3$3.mp4#选集播放4$4.mp4'}
  279. vod_play_urls = []
  280. for pli in plis:
  281. vname = ''.join(pli.xpath('./text()'))
  282. vurl = ''.join(pli.xpath('./@href'))
  283. vod_play_urls.append(vname + '$' + vurl)
  284. vod['vod_play_url'] = '#'.join(vod_play_urls)
  285. result = {
  286. 'list': [vod]
  287. }
  288. return result
  289. def searchContent(self, wd, quick=False, pg=1):
  290. """
  291. 返回搜索列表
  292. @param wd: 搜索关键词
  293. @param quick: 是否来自快速搜索。t3/t4配置里启用了快速搜索,在快速搜索在执行才会是True
  294. @return:
  295. """
  296. headers = {
  297. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36",
  298. "Host": "www.bttwo.net",
  299. "Referer": self.api
  300. }
  301. self.log(f'self.search_api:{self.search_api}')
  302. search_api = self.search_api or f'{self.api}/xsssearch'
  303. url = f'{search_api}?q={quote(wd)}'
  304. print(url)
  305. r = self.fetch(url, headers=headers)
  306. cookies = ['myannoun=1']
  307. for key, value in r.headers.items():
  308. if str(key).lower() == 'set-cookie':
  309. cookies.append(value.split(';')[0])
  310. new_headers = {
  311. 'Cookie': ';'.join(cookies),
  312. # 'Pragma': 'no-cache',
  313. # 'Origin': 'https://www.bttwo.org',
  314. # 'Referer': url,
  315. # 'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
  316. # 'Sec-Ch-Ua-Mobile': '?0',
  317. # 'Sec-Ch-Ua-Platform': '"Windows"',
  318. # 'Sec-Fetch-Dest': 'document',
  319. # 'Sec-Fetch-Mode': 'navigate',
  320. # 'Sec-Fetch-Site': 'same-origin',
  321. # 'Sec-Fetch-User': '?1',
  322. # 'Upgrade-Insecure-Requests': '1',
  323. }
  324. headers.update(new_headers)
  325. # print(headers)
  326. html = self.html(r.text)
  327. captcha = ''.join(html.xpath('//*[@class="erphp-search-captcha"]/form/text()')).strip()
  328. # print('验证码:', captcha)
  329. answer = self.eval_computer(captcha)
  330. # print('回答:', captcha, answer)
  331. data = {'result': str(answer)}
  332. # print('待post数据:', data)
  333. self.post(url, data=data, headers=headers, cookies=None)
  334. r = self.fetch(url, headers=headers)
  335. # print(r.text)
  336. html = self.html(r.text)
  337. lis = html.xpath('//*[contains(@class,"search_list")]/ul/li')
  338. print('搜索结果数:', len(lis))
  339. d = []
  340. if len(lis) < 1:
  341. d.append({
  342. 'vod_name': wd,
  343. 'vod_id': 'index.html',
  344. 'vod_pic': 'https://gitee.com/CherishRx/imagewarehouse/raw/master/image/13096725fe56ce9cf643a0e4cd0c159c.gif',
  345. 'vod_remarks': '测试搜索',
  346. })
  347. else:
  348. for li in lis:
  349. d.append({
  350. 'vod_name': ''.join(li.xpath('h3//text()')),
  351. 'vod_id': ''.join(li.xpath('a/@href')),
  352. 'vod_pic': ''.join(li.xpath('a/img/@data-original')),
  353. 'vod_remarks': ''.join(li.xpath('p//text()')),
  354. })
  355. result = {
  356. 'list': d
  357. }
  358. # print(result)
  359. return result
  360. def playerContent(self, flag, id, vipFlags):
  361. """
  362. 解析播放,返回json。壳子视情况播放直链或进行嗅探
  363. @param flag: vod_play_from 播放来源线路
  364. @param id: vod_play_url 播放的链接
  365. @param vipFlags: vip标识
  366. @return:
  367. """
  368. headers = {
  369. 'User-Agent': 'Mozilla/5.0 (Linux;; Android 11;; M2007J3SC Build/RKQ1.200826.002;; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.48 Mobile Safari/537.36',
  370. 'Referer': id,
  371. }
  372. # return {
  373. # 'parse': 1, # 1=嗅探,0=播放
  374. # 'playUrl': '', # 解析链接
  375. # 'url': id, # 直链或待嗅探地址
  376. # 'header': headers, # 播放UA
  377. # }
  378. r = self.fetch(id)
  379. html = r.text
  380. text = html.split('window.wp_nonce=')[1].split('eval')[0]
  381. # print(text)
  382. code = self.regStr(text, 'var .*?=.*?"(.*?)"')
  383. key = self.regStr(text, 'var .*?=md5.enc.Utf8.parse\\("(.*?)"')
  384. iv = self.regStr(text, 'var iv=.*?\\((\\d+)')
  385. text = self.aes_cbs_decode(code, key, iv)
  386. # print(code)
  387. # print(key,iv)
  388. # print(text)
  389. url = self.regStr(text, 'url: "(.*?)"')
  390. # print(url)
  391. parse = 0
  392. headers = {
  393. 'User-Agent': 'Mozilla/5.0 (Linux;; Android 11;; M2007J3SC Build/RKQ1.200826.002;; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.48 Mobile Safari/537.36',
  394. 'Referer': url,
  395. }
  396. result = {
  397. 'parse': parse, # 1=嗅探,0=播放
  398. 'playUrl': '', # 解析链接
  399. 'url': url, # 直链或待嗅探地址
  400. 'header': headers, # 播放UA
  401. }
  402. print(result)
  403. return result
  404. config = {
  405. "player": {},
  406. "filter": {}
  407. }
  408. header = {
  409. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36",
  410. "Host": "www.bttwo.net",
  411. "Referer": "https://www.bttwo.org/"
  412. }
  413. def localProxy(self, params):
  414. return [200, "video/MP2T", ""]
  415. # -----------------------------------------------自定义函数-----------------------------------------------
  416. def eval_computer(self, text):
  417. """
  418. 自定义的字符串安全计算器
  419. @param text:字符串的加减乘除
  420. @return:计算后得到的值
  421. """
  422. localdict = {}
  423. self.safe_eval(f'ret={text.replace("=", "")}', localdict)
  424. ret = localdict.get('ret') or None
  425. return ret
  426. def safe_eval(self, code: str = '', localdict: dict = None):
  427. code = code.strip()
  428. if not code:
  429. return {}
  430. if localdict is None:
  431. localdict = {}
  432. builtins = __builtins__
  433. if not isinstance(builtins, dict):
  434. builtins = builtins.__dict__.copy()
  435. else:
  436. builtins = builtins.copy()
  437. for key in ['__import__', 'eval', 'exec', 'globals', 'dir', 'copyright', 'open', 'quit']:
  438. del builtins[key] # 删除不安全的关键字
  439. # print(builtins)
  440. global_dict = {'__builtins__': builtins,
  441. 'json': json, 'print': print,
  442. 're': re, 'time': time, 'base64': base64
  443. } # 禁用内置函数,不允许导入包
  444. try:
  445. self.check_unsafe_attributes(code)
  446. exec(code, global_dict, localdict)
  447. return localdict
  448. except Exception as e:
  449. return {'error': f'执行报错:{e}'}
  450. # ==================== 静态函数 ======================
  451. @staticmethod
  452. def aes_cbs_decode(ciphertext, key, iv):
  453. # 将密文转换成byte数组
  454. ciphertext = base64.b64decode(ciphertext)
  455. # 构建AES解密器
  456. decrypter = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
  457. # 解密
  458. plaintext = decrypter.decrypt(ciphertext)
  459. # 去除填充
  460. plaintext = unpad(plaintext, AES.block_size)
  461. # 输出明文
  462. # print(plaintext.decode('utf-8'))
  463. return plaintext.decode('utf-8')
  464. @staticmethod
  465. def check_unsafe_attributes(string):
  466. """
  467. 安全检测需要exec执行的python代码
  468. :param string:
  469. :return:
  470. """
  471. g = tokenize.tokenize(io.BytesIO(string.encode('utf-8')).readline)
  472. pre_op = ''
  473. for toktype, tokval, _, _, _ in g:
  474. if toktype == tokenize.NAME and pre_op == '.' and tokval.startswith('_'):
  475. attr = tokval
  476. msg = "access to attribute '{0}' is unsafe.".format(attr)
  477. raise AttributeError(msg)
  478. elif toktype == tokenize.OP:
  479. pre_op = tokval
  480. if __name__ == '__main__':
  481. from t4.core.loader import t4_spider_init
  482. spider = Spider()
  483. t4_spider_init(spider)
  484. # spider.init_api_ext_file() # 生成筛选对应的json文件
  485. print(spider.homeVideoContent())
  486. # print(spider.categoryContent('movie_bt', 1, True, {}))
  487. print(spider.searchContent('斗罗大陆'))
  488. # print(spider.detailContent(['https://www.bttwo.org/movie/20107.html']))
  489. # print(spider.playerContent('在线播放', spider.decodeStr('https%3A%2F%2Fwww.bttwo.net%2Fv_play%2FbXZfMzY4Nzgtbm1fMQ%3D%3D.html','utf-8'), None))
  490. # print(spider.playerContent('在线播放', spider.decodeStr('https://www.bttwo.org/v_play/bXZfMTMyNjkwLW5tXzE=.html','utf-8'), None))
  491. # print(spider.playerContent('在线播放', 'https://www.bttwo.org/v_play/bXZfMTMyNjA2LW5tXzE=.html', None))
  492. # ciphertext = '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'
  493. # key = 'ae05c73de8a193cf'
  494. # iv = '1234567890983456'
  495. # print(spider.aes_cbs_decode(ciphertext, key, iv))