code:
<?php
/*
 * Copyright (c) <2008> Justin Poliey <jdp34@njit.edu>
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * Twitterlibphp is a PHP implementation of the Twitter API, allowing you
 * to take advantage of it from within your PHP applications.
 *
 * @author Justin Poliey <jdp34@njit.edu>
 * @package twitterlibphp
 */

/**
 * Twitter API abstract class
 * @package twitterlibphp
 */
abstract class TwitterBase {

	/**
	 * the last HTTP status code returned
	 * @access private
	 * @var integer
	 */
	private $http_status;

	/**
	 * the whole URL of the last API call
	 * @access private
	 * @var string
	 */
	private $last_api_call;

	/**
	 * the application calling the API
	 * @access private
	 * @var string
	 */
	private $application_source;

	/**
	 * Returns the 20 most recent statuses from non-protected users who have set a custom user icon.
	 * @param string $format Return format
	 * @return string
	 */
	function getPublicTimeline($format = 'xml') {
		return $this->apiCall('statuses/public_timeline', 'get', $format, array(), false);
	}

	/**
	 * Returns the 20 most recent statuses posted by the authenticating user and that user's friends.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getFriendsTimeline($options = array(), $format = 'xml') {
		return $this->apiCall('statuses/friends_timeline', 'get', $format, $options);
	}

	/**
	 * Returns the 20 most recent statuses posted from the authenticating user.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getUserTimeline($options = array(), $format = 'xml') {
		return $this->apiCall('statuses/user_timeline', 'get', $format, $options, true);
	}

  /**
   * Returns the 20 most recent mentions (status containing @username) for the authenticating user.
   * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
  function getMentions($options = array(), $format = 'xml') {
    return $this->apiCall("statuses/mentions", 'get', $format, $options);
  }

  /**
	 * Returns the 20 most recent @replies (status updates prefixed with @username) for the authenticating user.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
   * @deprecated
	 */
	function getReplies($options = array(), $format = 'xml') {
		return $this->apiCall('statuses/replies', 'get', $format, $options);
	}

	/**
	 * Returns a single status, specified by the $id parameter.
	 * @param string|integer $id The numerical ID of the status to retrieve
	 * @param string $format Return format
	 * @return string
	 */
	function getStatus($id, $format = 'xml') {
		return $this->apiCall("statuses/show/{$id}", 'get', $format, array(), false);
	}

	/**
	 * Updates the authenticated user's status.
	 * @param string $status Text of the status, no URL encoding necessary
	 * @param string|integer $reply_to ID of the status to reply to. Optional
	 * @param string $format Return format
	 * @return string
	 */
	function updateStatus($status, $reply_to = null, $format = 'xml') {
		$options = array('status' => $status);
		if ($reply_to) {
			$options['in_reply_to_status_id'] = $reply_to;
		}
    	return $this->apiCall('statuses/update', 'post', $format, $options);
	}

	/**
	 * Destroys the status specified by the required ID parameter. The authenticating user must be the author of the specified status.
	 * @param integer|string $id ID of the status to destroy
	 * @param string $format Return format
	 * @return string
	 */
	function destroyStatus($id, $format = 'xml') {
    	return $this->apiCall("statuses/destroy/{$id}", 'post', $format, $options);
	}

	/**
	 * Returns the authenticating user's friends, each with current status inline.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getFriends($options = array(), $format = 'xml') {
		return $this->apiCall('statuses/friends', 'get', $format, $options, false);
	}

	/**
	 * Returns the authenticating user's followers, each with current status inline.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getFollowers($options = array(), $format = 'xml') {
		return $this->apiCall('statuses/followers', 'get', $format, $options);
	}

	/**
	 * Returns extended information of a given user.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function showUser($options = array(), $format = 'xml') {
		if (!array_key_exists('id', $options) && !array_key_exists('user_id', $options) && !array_key_exists('screen_name', $options)) {
			$options['id'] = substr($this->credentials, 0, strpos($this->credentials, ':'));
		}
		return $this->apiCall('users/show', 'get', $format, $options, false);
	}

	/**
	 * Returns a list of the 20 most recent direct messages sent to the authenticating user.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getMessages($options = array(), $format = 'xml') {
		return $this->apiCall('direct_messages', 'get', $format, $options);
	}

	/**
	 * Returns a list of the 20 most recent direct messages sent by the authenticating user.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getSentMessages($options = array(), $format = 'xml') {
		return $this->apiCall('direct_messages/sent', 'get', $format, $options);
	}

	/**
	 * Sends a new direct message to the specified user from the authenticating user.
	 * @param string $user The ID or screen name of a recipient
	 * @param string $text The message to send
	 * @param string $format Return format
	 * @return string
	 */
	function newMessage($user, $text, $format = 'xml') {
		$options = array(
			'user' => $user,
			'text' => $text
		);
		return $this->apiCall('direct_messages/new', 'post', $format, $options);
	}

	/**
	 * Destroys the direct message specified in the required $id parameter.
	 * @param integer|string $id The ID of the direct message to destroy
	 * @param string $format Return format
	 * @return string
	 */
	function destroyMessage($id, $format = 'xml') {
		return $this->apiCall("direct_messages/destroy/{$id}", 'post', $format, $options);
	}

	/**
	 * Befriends the user specified in the ID parameter as the authenticating user.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function createFriendship($options = array(), $format = 'xml') {
		if (!array_key_exists('follow', $options)) {
      $options['follow'] = 'true';
    }
		return $this->apiCall('friendships/create', 'post', $format, $options);
	}

	/**
	 * Discontinues friendship with the user specified in the ID parameter as the authenticating user.
	 * @param integer|string $id The ID or screen name of the user to unfriend
	 * @param string $format Return format
	 * @return string
	 */
	function destroyFriendship($id, $format = 'xml') {
		$options = array('id' => $id);
		return $this->apiCall('friendships/destroy', 'post', $format, $options);
	}

	/**
	 * Tests if a friendship exists between two users.
	 * @param integer|string $user_a The ID or screen name of the first user
	 * @param integer|string $user_b The ID or screen name of the second user
	 * @param string $format Return format
	 * @return string
	 */
	function friendshipExists($user_a, $user_b, $format = 'xml') {
		$options = array(
			'user_a' => $user_a,
			'user_b' => $user_b
		);
		return $this->apiCall('friendships/exists', 'get', $format, $options);
	}

	/**
	 * Returns an array of numeric IDs for every user the specified user is followed by.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getFriendIDs($options = array(), $format = 'xml') {
		return $this->apiCall('friends/ids', 'get', $format, $options);
	}

	/**
	 * Returns an array of numeric IDs for every user the specified user is following.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getFollowerIDs($options = array(), $format = 'xml') {
		return $this->apiCall('followers/ids', 'get', $format, $options);
	}

	/**
	 * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; returns a 401 status code and an error message if not.
	 * @param string $format Return format
	 * @return string
	 */
	function verifyCredentials($format = 'xml') {
		return $this->apiCall('account/verify_credentials', 'get', $format, array());
	}

  /**
	 * Returns the remaining number of API requests available to the requesting user before the API limit is reached for the current hour.
	 * @param boolean $authenticate Authenticate before calling method
   * @param string $format Return format
	 * @return string
	 */
	function rateLimitStatus($authenticate = false, $format = 'xml') {
		return $this->apiCall('account/rate_limit_status', 'get', $format, array(), $authenticate);
	}

	/**
	 * Ends the session of the authenticating user, returning a null cookie.
	 * @param string $format Return format
	 * @return string
	 */
	function endSession($format = 'xml') {
		return $this->apiCall('account/end_session', 'post', $format, array());
	}

	/**
	 * Sets which device Twitter delivers updates to for the authenticating user.
	 * @param string $device The delivery device used. Must be sms, im, or none
	 * @return string
	 */
	function updateDeliveryDevice($device, $format = 'xml') {
		$options = array('device' => $device);
		return $this->apiCall('account/update_delivery_device', 'post', $format, $options);
	}

	/**
	 * Sets one or more hex values that control the color scheme of the authenticating user's profile page on twitter.com.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function updateProfileColors($options, $format = 'xml') {
		return $this->apiCall('account/update_profile_colors', 'post', $format, $options);
	}

	/**
	 * Sets values that users are able to set under the "Account" tab of their settings page.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function updateProfile($options, $format = 'xml') {
		return $this->apiCall('account/update_profile', 'post', $format, array());
	}

	/**
	 * Returns the 20 most recent favorite statuses for the authenticating user or user specified by the ID parameter in the requested format.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getFavorites($options = array(), $format = 'xml') {
		return $this->apiCall('favorites', 'get', $format, $options);
	}

	/**
	 * Favorites the status specified in the ID parameter as the authenticating user.
	 * @param integer|string $id The ID of the status to favorite
	 * @param string $format Return format
	 * @return string
	 */
	function createFavorite($id, $format = 'xml') {
		return $this->apiCall("favorites/create/{$id}", 'post', $format, array());
	}

	/**
	 * Un-favorites the status specified in the ID parameter as the authenticating user.
	 * @param integer|string $id The ID of the status to un-favorite
	 * @param string $format Return format
	 * @return string
	 */
	function destroyFavorite($id, $format = 'xml') {
		return $this->apiCall("favorites/destroy/{$id}", 'post', $format, array());
	}

	/**
	 * Enables notifications for updates from the specified user to the authenticating user.
	 * @param integer|string $id The ID or screen name of the user to follow
	 * @param string $format Return format
	 * @return string
	 */
	function follow($id, $format = 'xml') {
		$options = array('id' => $id);
		return $this->apiCall('notifications/follow', 'post', $format, $options);
	}

	/**
	 * Disables notifications for updates from the specified user to the authenticating user.
	 * @param integer|string $id The ID or screen name of the user to leave
	 * @param string $format Return format
	 * @return string
	 */
	function leave($id, $format = 'xml') {
		$options = array('id' => $id);
		return $this->apiCall('notifications/leave', 'post', $format, $options);
	}

	/**
	 * Blocks the user specified in the ID parameter as the authenticating user.
	 * @param integer|string $id The ID or screen name of the user to block
	 * @param string $format Return format
	 * @return string
	 */
	function createBlock($id, $format = 'xml') {
		$options = array('id' => $id);
		return $this->apiCall('blocks/create', 'post', $format, $options);
	}

	/**
	 * Unblocks the user specified in the ID parameter as the authenticating user.
	 * @param integer|string $id The ID or screen name of the user to unblock
	 * @param string $format Return format
	 * @return string
	 */
	function destroyBlock($id, $format = 'xml') {
		$options = array('id' => $id);
		return $this->apiCall('blocks/destroy', 'post', $format, $options);
	}

  /**
	 * Returns if the authenticating user is blocking a target user.
	 * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function blockExists($options, $format = 'xml') {
		return $this->apiCall('blocks/exists', 'get', $format, $options);
	}

  /**
	 * Returns an array of user objects that the authenticating user is blocking.
   * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getBlocking($options, $format = 'xml') {
		return $this->apiCall('blocks/blocking', 'get', $format, $options);
	}

  /**
	 * Returns an array of numeric user ids the authenticating user is blocking.
   * @param array $options Options to pass to the method
	 * @param string $format Return format
	 * @return string
	 */
	function getBlockingIDs($format = 'xml') {
		return $this->apiCall('blocks/blocking/ids', 'get', $format, array());
	}

	/**
	 * Returns the string "ok" in the requested format with a 200 OK HTTP status code.
	 * @param string $format Return format
	 * @return string
	 */
	function test($format = 'xml') {
		return $this->apiCall('help/test', 'get', $format, array(), false);
	}

	/**
	 * Returns the last HTTP status code
	 * @return integer
	 */
	function lastStatusCode() {
		return $this->http_status;
	}

	/**
	 * Returns the URL of the last API call
	 * @return string
	 */
	function lastApiCall() {
		return $this->last_api_call;
	}
}

/**
 * Access to the Twitter API through HTTP auth
 * @package twitterlibphp
 */
class Twitter extends TwitterBase {

	/**
	 * the Twitter credentials in HTTP format, username:password
	 * @access private
	 * @var string
	 */
	var $credentials;

	/**
	 * Fills in the credentials {@link $credentials} and the application source {@link $application_source}.
	 * @param string $username Twitter username
	 * @param string $password Twitter password
	 * @param $source string Optional. Name of the application using the API
	 */
	function __construct($username, $password, $source = null) {
		$this->credentials = sprintf("%s:%s", $username, $password);
		$this->application_source = $source;
	}

	/**
	 * Executes an API call
	 * @param string $twitter_method The Twitter method to call
   * @param string $http_method The HTTP method to use
   * @param string $format Return format
   * @param array $options Options to pass to the Twitter method
	 * @param boolean $require_credentials Whether or not credentials are required
	 * @return string
	 */
	protected function apiCall($twitter_method, $http_method, $format, $options, $require_credentials = true) {
		$curl_handle = curl_init();
    $api_url = sprintf('http://twitter.com/%s.%s', $twitter_method, $format);
    if (($http_method == 'get') && (count($options) > 0)) {
      $api_url .= '?' . http_build_query($options);
    }
    //echo $api_url . "\n";
		curl_setopt($curl_handle, CURLOPT_URL, $api_url);
		if ($require_credentials) {
			curl_setopt($curl_handle, CURLOPT_USERPWD, $this->credentials);
		}
		if ($http_method == 'post') {
			curl_setopt($curl_handle, CURLOPT_POST, true);
      curl_setopt($curl_handle, CURLOPT_POSTFIELDS, http_build_query($options));
		}
		curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);
		curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array('Expect:'));
		$twitter_data = curl_exec($curl_handle);
		$this->http_status = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);
		$this->last_api_call = $api_url;
		curl_close($curl_handle);
		return $twitter_data;
	}

}

/**
 * TODO: Add TwitterOAuth class
 */
?>


code:
# profile

Profile repository

repo_name: mizhac/profile

license: mit


皮皮泡影视

houzhui: .html

jiequqian: 空

jiequhou: 空

tupianqian: original="

biaotiqian: title="

fubiaotiqian: class="pic-text text-right">

fubiaotihou: </span>

lianjieqian: href="

sousuohouzhui: /vod/

jspic: pic

jsname: name

jsid: id

ssjiequqian: 空

ssjiequhou: 空

ssjiequshuzuqian: 空

ssjiequshuzuhou: 空

sstupianqian: 空

sstupianhou: 空

ssbiaotiqian: 空

ssbiaotihou: 空

sslianjieqian: 空

sslianjiehou: 空

线路名截取数组前: class="more

线路名截取数组后: </div>

bfjiequqian: 空

bfjiequhou: 空

zhuangtaiqian: class="pic-text text-right">

zhuangtaihou: </span>

daoyanqian: class="text-muted">导演：

zhuyanqian: class="text-muted">主演：

juqingqian: <p class="col-pd">

bfyjiequqian: 空

bfyjiequhou: 空

bfyjiequshuzuqian: <a

bflianjieqian: href="

瓜皮TV

jiequqian: class="module-items

jiequhou: class="fixedGroup

jiequshuzuqian: <a

jiequshuzuhou: alt="

tupianqian: data-original="

fubiaotiqian: class="module-item-note">

fubiaotihou: </div>

线路名截取前: 空

线路名截取后: 空

线路名截取数组前: tab-item"

线路名标题前: <span>

线路名标题后: </span>

bfjiequshuzuqian: <div class="module-play-list-content

bfjiequshuzuhou: </div>

zhuangtaiqian: 更新：</span>

zhuangtaihou: </div>

daoyanqian: 导演：</span>

daoyanhou: </div>

zhuyanqian: 主演：</span>

zhuyanhou: </div>

juqingqian: introduction-content"><p>

bfbiaotiqian: span>

bfbiaotihou: </span

Auete影视

jiequshuzuhou: class="lazy

tupianqian: src="

lianjieqian: <a href="

jspic: 空

jsname: 空

jsid: 空

ssjiequshuzuqian: break-all">

ssbiaotiqian: text-danger">

ssbiaotihou: </span

sslianjieqian: href="

LIBVIO

ua: Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1


code:
muban.首图2.二级.tabs = '.nav-tabs.dpplay&&li';
var rule = Object.assign(muban.首图2,{
    title:'007影视',
    host:'https://www.007ts.me',
    url:'/channel/fyclass-fypage.html',
    searchUrl:'/search/**----------fypage---.html',
});

license: unknown


code:
var rule = Object.assign(muban.mxpro,{
title:'1080P',
host:'https://1080p.tv',
url:'/vodshow/fyclass--------fypage---/',
searchUrl:'/vodsearch/**----------fypage---/',
class_parse:'.navbar-items li:gt(1):lt(7);a&&Text;a&&href;.*/(.*?)/',
});


code:
var rule = Object.assign(muban.mxpro,{
title:'555影视',
// host:'https://www.555dy.app',
host:'https://www.555yy2.com/',
headers:{//网站的请求头,完整支持所有的,常带ua和cookies
    'User-Agent':'MOBILE_UA',
    "Cookie": "searchneed=ok"
},
});


code:
muban.海螺3.二级.desc = '.hl-text-conch&&Text';
var rule = Object.assign(muban.海螺3,{
    title:'AnFuns动漫',
    host:'https://www.anfuns.cc',
    cate_exclude: '最新|排行',
    url:'/type/fyclass-fypage.html',
    searchUrl:'/search/page/fypage/wd/**.html',
});


code:
var rule = Object.assign(muban.首图2,{
title:'LIBVIO',
// host:'https://www.libvio.me',
host:'https://www.libvio.fun',
url:'/type/fyclass-fypage.html',
class_parse:'.stui-header__menu li:gt(0):lt(7);a&&Text;a&&href;/(\\d+).html',
searchUrl:'/search/**----------fypage---.html',
});


code:
var rule = Object.assign(muban.mxpro,{
title:'cokemv',
host:'https://cokemv.me',
class_parse:'.navbar-items li:gt(1):lt(7);a&&Text;a&&href;/(\\d+).html',
});


code:
// drT.js
// 2022/09/30 write by hjdhnx
// Licensed under the MIT license.

(function () {
    "use strict";

    var drT = {
        name: "drT",
        version: "1.0.0",
        templateSettings: {
            evaluate:    /\{\{([\s\S]+?(\}?)+)\}\}/g,
            interpolate: /\{\{([\s\S]+?)\}\}/g, // 变量渲染
            encode:      /\{\{@([\s\S]+?)\}\}/g, // 变量自动url编码
            use:         /\{\{#([\s\S]+?)\}\}/g,
            useParams:   /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
            define:      /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
            defineParams:/^\s*([\w$]+):([\s\S]+)/,
            conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g, // ? if ?? else if ?? else
            iterate:     /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
            varname:	"fl",
            strip:		true,
            append:		true,
            selfcontained: false,
            doNotSkipEncoded: false
        },
        template: undefined, //fn, compile template
        compile:  undefined, //fn, for express
        log: true
    }, _globals;

    drT.encodeHTMLSource = function(doNotSkipEncoded) {
        var encodeHTMLRules = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'", "/": "/" },
            matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|<|>|"|'|\//g;
        return function(code) {
            return code ? code.toString().replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : "";
        };
    };

    _globals = (function(){ return this || (0,eval)("this"); }());

    /* istanbul ignore else */
    if (typeof module !== "undefined" && module.exports) {
        module.exports = drT;
    } else if (typeof define === "function" && define.amd) {
        define(function(){return drT;});
    } else {
        _globals.drT = drT;
    }

    var startend = {
        append: { start: "'+(",      end: ")+'",      startencode: "'+encodeHTML(" },
        split:  { start: "';out+=(", end: ");out+='", startencode: "';out+=encodeHTML(" }
    }, skip = /$^/;

    function resolveDefs(c, block, def) {
        return ((typeof block === "string") ? block : block.toString())
            .replace(c.define || skip, function(m, code, assign, value) {
                if (code.indexOf("def.") === 0) {
                    code = code.substring(4);
                }
                if (!(code in def)) {
                    if (assign === ":") {
                        if (c.defineParams) value.replace(c.defineParams, function(m, param, v) {
                            def[code] = {arg: param, text: v};
                        });
                        if (!(code in def)) def[code]= value;
                    } else {
                        new Function("def", "def['"+code+"']=" + value)(def);
                    }
                }
                return "";
            })
            .replace(c.use || skip, function(m, code) {
                if (c.useParams) code = code.replace(c.useParams, function(m, s, d, param) {
                    if (def[d] && def[d].arg && param) {
                        var rw = (d+":"+param).replace(/'|\\/g, "_");
                        def.__exp = def.__exp || {};
                        def.__exp[rw] = def[d].text.replace(new RegExp("(^|[^\\w$])" + def[d].arg + "([^\\w$])", "g"), "$1" + param + "$2");
                        return s + "def.__exp['"+rw+"']";
                    }
                });
                var v = new Function("def", "return " + code)(def);
                return v ? resolveDefs(c, v, def) : v;
            });
    }

    function unescape(code) {
        return code.replace(/\\('|\\)/g, "$1").replace(/[\r\t\n]/g, " ");
    }

    drT.template = function(tmpl, c, def) {
        c = c || drT.templateSettings;
        var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv,
            str  = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;

        // console.log(str);
        let beforeCode = '';
        if(str.match(c.interpolate || skip)){
            let inter_codes = str.match(c.interpolate || skip);
            let inter_dict = {};
            inter_codes.forEach(item=>{
                item.replace(c.interpolate || skip,function (m,code) {
                    let varname = code.split('.')[0];
                    if(!inter_dict.hasOwnProperty(varname)){
                        let beginCode = `if(typeof(${varname})==='undefined'){${varname}={}}`;
                        inter_dict[varname] = beginCode;
                    }if(!inter_dict.hasOwnProperty(code)){
                        let beginCode = `if(typeof(${code})==='undefined'){${code}=''};`;
                        inter_dict[code] = beginCode;
                    }
                });
            });
            let beginCode = Object.values(inter_dict).join('\n');
            // console.log(beginCode);
            beforeCode += beginCode;
        }
        str = beforeCode+("var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ")
                .replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""): str)
                .replace(/'|\\/g, "\\$&")
                .replace(c.encode || skip, function(m, code) {
                    needhtmlencode = true;
                    return cse.startencode + unescape(code) + cse.end;
                })
                .replace(c.interpolate || skip, function(m, code) {
                    let varname = code.split('.')[0];
                    // console.log(varname === code);
                    // console.log(`varname:${varname},code:${code}`);
                    if(varname === code){
                        let res = cse.start + `JSON.stringify(${unescape(code)})` + cse.end;
                        // console.log(res);
                        return res
                    }
                    return cse.start + unescape(code) + cse.end;
                })
                .replace(c.conditional || skip, function(m, elsecase, code) {
                    return elsecase ?
                        (code ? "';}else if(" + unescape(code) + "){out+='" : "';}else{out+='") :
                        (code ? "';if(" + unescape(code) + "){out+='" : "';}out+='");
                })
                .replace(c.iterate || skip, function(m, iterate, vname, iname) {
                    if (!iterate) return "';} } out+='";
                    sid+=1; indv=iname || "i"+sid; iterate=unescape(iterate);
                    return "';var arr"+sid+"="+iterate+";if(arr"+sid+"){var "+vname+","+indv+"=-1,l"+sid+"=arr"+sid+".length-1;while("+indv+"<l"+sid+"){"
                        +vname+"=arr"+sid+"["+indv+"+=1];out+='";
                })
                .replace(c.evaluate || skip, function(m, code) {
                    return "';" + unescape(code) + "out+='";
                })
            + "';return out;")
            .replace(/\n/g, "\\n").replace(/\t/g, '\\t').replace(/\r/g, "\\r")
            .replace(/(\s|;|\}|^|\{)out\+='';/g, '$1').replace(/\+''/g, "");
        //.replace(/(\s|;|\}|^|\{)out\+=''\+/g,'$1out+=');

        if (needhtmlencode) {
            // console.log('需要编码');
            // console.log(c.doNotSkipEncoded);
            if (!c.selfcontained && _globals && !_globals._encodeHTML) _globals._encodeHTML = drT.encodeHTMLSource(c.doNotSkipEncoded);
            str = "var encodeHTML = typeof _encodeHTML !== 'undefined' ? _encodeHTML : ("
                + drT.encodeHTMLSource.toString() + "(" + (c.doNotSkipEncoded || '') + "));"
                + str;
            // console.log(str);
        }else{
            // console.log('不需要编码');
        }
        // console.log(c.varname);
        // console.log(str);
        try {
            return new Function(c.varname, str);
        } catch (e) {
            /* istanbul ignore else */
            // console.log(e.message);
            if (typeof console !== "undefined") console.log("Could not create a template function: " + str);
            throw e;
        }
    };

    drT.compile = function(tmpl, def) {
        return drT.template(tmpl, null, def);
    };
    drT.renderText = function (tmpl,dict,varname){
        varname = varname||'';
        if(varname){
            drT.templateSettings.varname = varname;
        }
        dict = dict||{};
        return drT.compile(tmpl)(dict);
    };
}());


group: redirect

rule: play.videomiao.vip/API.php time= key= path=

解析聚合

url: Demo

Json并发

url: Parallel

Json轮询

url: Sequence

flags: youku qq iqiyi qiyi letv sohu tudou pptv mgtv wasu

group: 软解码

fflags

value: fastseek

group: 硬解码


code:
muban.海螺2.二级.content = '.play-m-box&&Text';
muban.海螺2.二级.desc = '.play-news&&Text';
muban.海螺2.二级.img = '';
var rule = Object.assign(muban.海螺2,{
    title:'l0l',
    host:'https://www.l0l.tv',
    class_parse:'.index-tag&&li;a&&.title&&Text;a&&href;.*/(.*?).html',
    searchUrl:'/index.php/vod/search/page/fypage/wd/**.html',
    搜索:'.searchlilst&&li;a&&title;.lazy&&data-original;.list-remarks&&Text;a&&href',
});


code:
var rule = Object.assign(muban.vfed,{
title:'VIP影院',
host:'http://360yy.cn',
url:'/index.php/vod/show/id/fyclass/page/fypage.html',
searchUrl:'/index.php/vod/search/page/fypage/wd/**.html',
});


code:
var rule = Object.assign(muban.首图,{
title:'万能影视',
host:'https://wnvod.net',
});


code:
muban.首图2.二级.tabs = '.stui-pannel__head h3';
var rule = Object.assign(muban.首图2,{
    title:'人人影视',
    host:'https://www.rttks.com',
    url:'/rrtop/fyclass/page/fypage.html',
    searchUrl:'/rrso**/page/fypage.html',
    class_parse:'.stui-header__menu li;a&&Text;a&&href;.*/(.*?).html',
    // cate_exclude:'解说',
    play_parse:true,
    lazy:'',
});


code:
var rule = {
    title:'兔小贝',
    host:'https://www.tuxiaobei.com',
    homeUrl:'',
    url:'/list/mip-data?typeId=fyclass&page=fypage&callback=',
    detailUrl:'/play/fyid',
    searchUrl:'/search/index?key=**',
    searchable:2,
    headers:{
        'User-Agent':'MOBILE_UA'
    },
    timeout:5000,
    class_url:'2&3&4&25',
    class_name:'儿歌&故事&国学&启蒙',
    //class_name:'#page-viewport&&ul&&li;.text&&Text;a&&href;/(.*)',
    cate_exclude:'应用',
    推荐:'.pic-list.list-box;.items;.text&&Text;mip-img&&src;.all&&Text;a&&href',
    double:true,
    limit:5,
    play_parse:true,
    lazy:'js:fetch_params.headers["user-agent"] = IOS_UA;let html=fetch(input,fetch_params);let src = jsp.pdfh(html,"body&&#videoWrap&&video-src");input=src;',
    // 一级:'json:data.items;name;image;collect_num;category_id+video_id',
    一级:'json:data.items;name;image;duration_string;video_id',
    二级:'*',
    搜索:'.list-con&&.items;.text&&Text;mip-img&&src;.time&&Text;a&&href',
}


code:
var  rule={
    title:'凌云影视',
    host:'https://www.lingyun.in',
    // searchUrl:'/v_search/**----------fypage---.html',
    url:'/play/fyclass-fypage.html',
    headers:{
        'User-Agent':'MOBILE_UA'
    },
    timeout:5000,
    class_parse:'.over-auto li;a&&Text;a&&href;.*/(.*?).html',
    cate_exclude:'解析',
    limit:40,
    play_parse:true,
    lazy:'',
    推荐:'ul.pic-list.pic-list-nth;li;a&&title;img&&data-src;.s1&&Text;a&&href',
    double:true,
    一级:'ul.pic-list.clearfix&&li;a&&title;img&&data-src;.s1&&Text;a&&href',
    二级:{"title":".content-rt&&h1&&Text;.content-rt&&p:eq(0)&&Text","img":".img&&img&&data-src","desc":".content-rt&&p:eq(2)&&Text;.content-rt&&p:eq(3)&&Text","content":".movie-introduce&&.sqjj_a&&Text","tabs":".py-tabs&&option","lists":"ul.player:eq(#id)&&li"},
    // 搜索:'.hl-list-item;a&&title;a&&data-original;.remarks&&Text;a&&href',
    searchable:1,//是否启用全局搜索,
};


code:
var rule = Object.assign(muban.首图2,{
title:'剧白白',
host:'https://jubaibai.cc',
url:'/vodshow/id/fyclass/page/fypage.html',
searchUrl:'/vodsearch**/page/fypage.html',
class_parse:'.stui-header__menu li:gt(0):lt(6);a&&Text;a&&href;/(.*?).html',
});


code:
var rule = {
    title:'喵喵',
    host:'https://www.2345ka.com',
    // homeUrl:'/',
    url:'/t/fyclass/fypage.html',
    searchUrl:'/s/**/fypage.html',
    searchable:2,
    quickSearch:0,
    headers:{
        'User-Agent':'UC_UA'
    },
    timeout:5000,
    class_parse:'.bm-item-list a:gt(0):lt(7);a&&Text;a&&href;/(\\d+).html',
    play_parse:true,
    lazy:'',
    limit:5,
    推荐:'.movie-list-body;.movie-list-item;.movie-title&&Text;.movie-post-lazyload&&data-original;.movie-rating&&Text;a&&href',
    double:true, // 推荐内容是否双层定位
    一级:'.movie-list-body .movie-list-item;.movie-title&&Text;.Lazy&&data-original;.movie-rating&&Text;a&&href',
    二级:{"title":"h1.movie-title&&Text;.data:eq(1)&&Text","img":".poster img&&src","desc":".cr3.starLink&&Text","content":".detailsTxt&&Text","tabs":".play_source_tab a","lists":".content_playlist:eq(#id) a"},
    搜索:'.vod-search-list;.movie-title&&Text;.Lazy&&data-original;.getop&&Text;a&&href;.getop:eq(-1)&&Text',
}


code:
var rule = Object.assign(muban.首图2,{
title:'在线之家',
host:'https://zxzj.vip',
});


code:
var rule = Object.assign(muban.mxpro,{
title:'夜空',
host:'https://www.yekong.cc',
url:'/pianku-fyclass--------fypage---/',
searchUrl:'/search-**----------fypage---/',
class_parse:'.navbar-items li:gt(1):lt(7);a&&Text;a&&href;.*v/(.*?)/',
});


code:
muban.mxpro.二级.img = '.lazyload&&src';
var rule = Object.assign(muban.mxpro,{
title:'大米星球',
host:'https://www.dmxq.fun',
url:'/vodshow/fyclass--------fypage---/pjax/YES.html',
searchUrl:'/vodsearch/**----------fypage---/pjax/NO.html',
class_parse:'li.swiper-slide.navbar-item;span&&Text;a&&href;/(\\d+).html',
 一级:'a.module-poster-item.module-item;a&&title;.lazyload&&src;.module-item-note&&Text;a&&href',
 推荐:'.tab-list.active;a.module-poster-item.module-item;.module-poster-item-title&&Text;.lazyload&&src;.module-item-note&&Text;a&&href',
});


code:
muban.首图2.二级.title = '.stui-content__detail&&h1&&Text;.stui-content__detail&&p:eq(0)&&Text';
muban.首图2.二级.tabs = '.stui-pannel__head a';
muban.首图2.二级.lists = '.stui-content__playlist:eq(#id) li';
muban.首图2.二级.desc = '.stui-content__detail&&p:eq(1)&&Text;.stui-content__detail&&p:eq(2)&&Text;.stui-content__detail&&p:eq(3)&&Text';
muban.首图2.二级.content = '.stui-pannel_bd:eq(1)&&Text';
var rule = Object.assign(muban.首图2,{
    title:'奇优影院',
    host:'https://www.gdjilong.com',
    url:'/list/fyclass_fypage.html',
    searchUrl:'/search.php;**',
    搜索:'js:let url=input.split(";")[0];let d=[];let body={searchword:input.split(";")[1]};fetch_params.body=body;let html=post(url,fetch_params);let pdfa=jsp.pdfa;let pdfh=jsp.pdfh;let pd=jsp.pd;let lists=pdfa(html,"ul.stui-vodlist__media&&li");lists.forEach(function(it){d.push({title:pdfh(it,".title&&Text"),url:pd(it,"a&&href"),desc:pdfh(html,".pic-text&&Text"),pic_url:pd(html,".lazyload&&data-original")})});setResult(d);',
//搜索:'li.stui-vodlist__item;a&&title;a&&data-original;.pic-text&&Text;a&&href'
});


code:
muban.首图2.二级.content = '.stui-content__desc&&Text';
muban.首图2.二级.title = '.stui-content__detail&&h3&&Text;.stui-content__detail&&p:eq(1)&&Text;';
muban.首图2.二级.重定向='js:let url = jsp.pd(html,".playbtn&&a&&href");log(url);html = request(url)';
muban.首图2.二级.tabs='.t-ul&&li';
muban.首图2.二级.lists='.stui-content__playlist:eq(#id)&&li';

var rule = Object.assign(muban.首图2,{
title:'小强迷',
host:'http://xqmi.top',
url:'/index.php/vod/show/id/fyclass/page/fypage.html',
searchUrl:'/index.php/vod/search/page/fypage/wd/**.html',
});


code:
muban.海螺3.二级.content = '.hl-infos-content&&Text';
var rule = Object.assign(muban.海螺3,{
    title:'小猫咪',
    host:'https://cj.banyung.xyz',
});


code:
var rule = {
    title:'干饭影视',
    host:'https://www.gfysys.com/',
    // homeUrl:'/',
    url:'/vodtype/fyclass-fypage.html',
    headers:{
        'User-Agent':'MOBILE_UA',
        "Cookie": "searchneed=ok"
    },
    searchUrl:'/vodsearch/**----------fypage---.html',
    searchable:2,
    // class_name:'电影&网剧&剧集&动漫&综艺&记录',
    // class_url:'20&1&2&3&4&23',
    class_parse:'.stui-header__menu li:gt(0):lt(5);a&&Text;a&&href;/(\\d+).html',
    play_parse:true,
    // lazy:'干饭',
    // lazy:'@js:cacheUrl = d.getParse(input);print(cacheUrl);input=cacheUrl',
    // lazy:'js:cacheUrl = d.getParse(input);print(cacheUrl);input=cacheUrl',
    // lazy:'js:cacheUrl=d.getParse(input);if(cacheUrl){input=cacheUrl}else{try{let html=fetch(input,{headers:d.headers,timeout:d.timeout,encoding:d.encoding});let ret=html.match(/var player_(.*?)=(.*?)</)[2];let url=JSON.parse(ret).url;if(url.length>10){real_url="https://player.buyaotou.xyz/?url="+url;d.saveParse(input,real_url);input=real_url}}catch(e){print("网络请求发生错误:"+e.message)}}',
    lazy:'js:cacheUrl=getParse(input);if(cacheUrl){input=cacheUrl}else{try{let html=fetch(input,fetch_params);let ret=html.match(/var player_(.*?)=(.*?)</)[2];let url=JSON.parse(ret).url;if(url.length>10){real_url="https://player.buyaotou.xyz/?url="+url;saveParse(input,real_url);input=real_url}}catch(e){print("网络请求发生错误:"+e.message)}}',
    limit:5,
    推荐:'ul.stui-vodlist.clearfix;li;a&&title;.lazyload&&data-original;;a&&href',
    double:true, // 推荐内容是否双层定位
    一级:'body .stui-vodlist__box;a&&title;.lazyload&&data-original;;a&&href',
    二级:{"title":"h1.title&&Text;.stui-content__detail p:eq(1)&&Text","img":".lazyload&&data-original","desc":".stui-content__detail p:eq(-3)&&Text;.stui-content__detail p:eq(-2)&&Text","content":".stui-content__detail p.detail&&Text","tabs":".stui-pannel__head ul li","lists":".stui-content__playlist:eq(#id) li"},
    // 搜索:'body .module-item;.module-card-item-title&&Text;.lazyload&&data-original;.module-item-note&&Text;a&&href;.module-info-item-content&&Text',
}


code:
var rule = Object.assign(muban.首图2,{
title:'库马伊',
host:'http://www.kmy5.com',
url:'/tv/fyclass-fypage.html',
searchUrl:'/search/**----------fypage---.html',
class_parse:'.stui-header__menu li:gt(0):lt(5);a&&Text;a&&href;.*/(.*?).html',
搜索:'li.stui-vodlist__item;a&&title;.lazyload&&data-original;.pic-text&&Text;a&&href',
二级:{"title":".stui-content__detail .title&&Text;.stui-content__detail p:eq(-2)&&Text","img":".stui-content__thumb .lazyload&&data-original","desc":".stui-content__detail p:eq(0)&&Text;.stui-content__detail p:eq(1)&&Text;.stui-content__detail p:eq(2)&&Text","content":".stui-content__desc&&Text","tabs":".stui-pannel__head h3","lists":".stui-content__playlist:eq(#id) li"},
});


code:
var rule = Object.assign(muban.首图,{
title:'影视工厂',
host:'https://www.ysgc.cc',
});


code:
if (typeof Object.assign != 'function') {
    Object.assign = function () {
	var target = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i];
        for (var key in source) {
            if (Object.prototype.hasOwnProperty.call(source, key)) {
                target[key] = source[key];
            }
        }
    }
    return target;
};
}

var mubanDict = { // 模板字典
 mxpro:{
    title:'',
    host:'',
    // homeUrl:'/',
    url:'/vodshow/fyclass--------fypage---.html',
    searchUrl:'/vodsearch/**----------fypage---.html',
    searchable:2,//是否启用全局搜索,
    quickSearch:0,//是否启用快速搜索,
    filterable:0,//是否启用分类筛选,
    headers:{//网站的请求头,完整支持所有的,常带ua和cookies
        'User-Agent':'MOBILE_UA',
        // "Cookie": "searchneed=ok"
    },
    class_parse:'.navbar-items li:gt(2):lt(8);a&&Text;a&&href;/(\\d+).html',
    play_parse:true,
    lazy:'',
    limit:6,
    推荐:'.tab-list.active;a.module-poster-item.module-item;.module-poster-item-title&&Text;.lazyload&&data-original;.module-item-note&&Text;a&&href',
    double:true, // 推荐内容是否双层定位
    一级:'body a.module-poster-item.module-item;a&&title;.lazyload&&data-original;.module-item-note&&Text;a&&href',
    二级:{"title":"h1&&Text;.module-info-tag&&Text","img":".lazyload&&data-original","desc":".module-info-item:eq(1)&&Text;.module-info-item:eq(2)&&Text;.module-info-item:eq(3)&&Text","content":".module-info-introduction&&Text","tabs":".module-tab-item","lists":".module-play-list:eq(#id) a"},
    搜索:'body .module-item;.module-card-item-title&&Text;.lazyload&&data-original;.module-item-note&&Text;a&&href;.module-info-item-content&&Text',
},
首图:{
    title:'',
    host:'',
    url:'/vodshow/fyclass--------fypage---/',
    searchUrl:'/vodsearch/**----------fypage---.html',
    searchable:2,//是否启用全局搜索,
    quickSearch:0,//是否启用快速搜索,
    filterable:0,//是否启用分类筛选,
    headers:{//网站的请求头,完整支持所有的,常带ua和cookies
        'User-Agent':'MOBILE_UA',
        // "Cookie": "searchneed=ok"
    },
    class_parse:'.myui-header__menu li.hidden-sm:gt(0):lt(5);a&&Text;a&&href;/(\\d+).html',
    play_parse:true,
    lazy:'',
    limit:6,
    推荐:'ul.myui-vodlist.clearfix;li;a&&title;a&&data-original;.pic-text&&Text;a&&href',
    double:true, // 推荐内容是否双层定位
    一级:'.myui-vodlist li;a&&title;a&&data-original;.pic-text&&Text;a&&href',
    二级:{"title":".myui-content__detail .title&&Text;.myui-content__detail p:eq(-2)&&Text","img":".myui-content__thumb .lazyload&&data-original","desc":".myui-content__detail p:eq(0)&&Text;.myui-content__detail p:eq(1)&&Text;.myui-content__detail p:eq(2)&&Text","content":".content&&Text","tabs":".nav-tabs:eq(0) li","lists":".myui-content__list:eq(#id) li"},
    搜索:'#searchList li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text',
},
首图2:{
    title:'',
    host:'',
    url:'/list/fyclass-fypage.html',
    searchUrl:'/vodsearch/**----------fypage---.html',
    searchable:2,//是否启用全局搜索,
    quickSearch:0,//是否启用快速搜索,
    filterable:0,//是否启用分类筛选,
    headers:{
        'User-Agent':'UC_UA',
        // "Cookie": ""
    },
    // class_parse:'.stui-header__menu li:gt(0):lt(7);a&&Text;a&&href;/(\\d+).html',
    class_parse:'.stui-header__menu li:gt(0):lt(7);a&&Text;a&&href;.*/(.*?).html',
    play_parse:true,
    lazy:'',
    limit:6,
    推荐:'ul.stui-vodlist.clearfix;li;a&&title;.lazyload&&data-original;.pic-text&&Text;a&&href',
    double:true, // 推荐内容是否双层定位
    一级:'.stui-vodlist li;a&&title;a&&data-original;.pic-text&&Text;a&&href',
    二级:{"title":".stui-content__detail .title&&Text;.stui-content__detail p:eq(-2)&&Text","img":".stui-content__thumb .lazyload&&data-original","desc":".stui-content__detail p:eq(0)&&Text;.stui-content__detail p:eq(1)&&Text;.stui-content__detail p:eq(2)&&Text","content":".detail&&Text","tabs":".stui-vodlist__head h3","lists":".stui-content__playlist:eq(#id) li"},
    搜索:'ul.stui-vodlist__media:eq(0) li,ul.stui-vodlist:eq(0) li,#searchList li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text',
    搜索1:'ul.stui-vodlist&&li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text',
    搜索2:'ul.stui-vodlist__media&&li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text',
},
vfed:{
    title:'',
    host:'',
    url:'/index.php/vod/show/id/fyclass/page/fypage.html',
    searchUrl:'/index.php/vod/search/page/fypage/wd/**.html',
    searchable:2,//是否启用全局搜索,
    quickSearch:0,//是否启用快速搜索,
    filterable:0,//是否启用分类筛选,
    headers:{
        'User-Agent':'UC_UA',
    },
    // class_parse:'.fed-pops-navbar&&ul.fed-part-rows&&a.fed-part-eone:gt(0):lt(5);a&&Text;a&&href;.*/(.*?).html',
    class_parse:'.fed-pops-navbar&&ul.fed-part-rows&&a;a&&Text;a&&href;.*/(.*?).html',
    play_parse:true,
    lazy:'',
    limit:6,
    推荐:'ul.fed-list-info.fed-part-rows;li;a.fed-list-title&&Text;a&&data-original;.fed-list-remarks&&Text;a&&href',
    double:true, // 推荐内容是否双层定位
    一级:'.fed-list-info&&li;a.fed-list-title&&Text;a&&data-original;.fed-list-remarks&&Text;a&&href',
    二级:{"title":"h1.fed-part-eone&&Text;.fed-deta-content&&.fed-part-rows&&li&&Text","img":".fed-list-info&&a&&data-original","desc":".fed-deta-content&&.fed-part-rows&&li:eq(1)&&Text;.fed-deta-content&&.fed-part-rows&&li:eq(2)&&Text;.fed-deta-content&&.fed-part-rows&&li:eq(3)&&Text","content":".fed-part-esan&&Text","tabs":".fed-drop-boxs&&.fed-part-rows&&li","lists":".fed-play-item:eq(#id)&&ul:eq(1)&&li"},
    搜索:'.fed-deta-info;h1&&Text;.lazyload&&data-original;.fed-list-remarks&&Text;a&&href;.fed-deta-content&&Text',
},
海螺3:{
    title:'',
    host:'',
    searchUrl:'/v_search/**----------fypage---.html',
    url:'/vod_____show/fyclass--------fypage---.html',
    headers:{
        'User-Agent':'MOBILE_UA'
    },
    timeout:5000,
    class_parse:'body&&.hl-nav li:gt(0);a&&Text;a&&href;.*/(.*?).html',
    cate_exclude:'明星|专题|最新|排行',
    limit:40,
    play_parse:true,
    lazy:'',
    推荐:'.hl-vod-list;li;a&&title;a&&data-original;.remarks&&Text;a&&href',
    double:true,
    一级:'.hl-vod-list&&.hl-list-item;a&&title;a&&data-original;.remarks&&Text;a&&href',
    二级:{"title":".hl-infos-title&&Text;.hl-text-conch&&Text","img":".hl-lazy&&data-original","desc":".hl-infos-content&&.hl-text-conch&&Text","content":".hl-content-text&&Text","tabs":".hl-tabs&&a","lists":".hl-plays-list:eq(#id)&&li"},
    搜索:'.hl-list-item;a&&title;a&&data-original;.remarks&&Text;a&&href',
    searchable:2,//是否启用全局搜索,
    quickSearch:0,//是否启用快速搜索,
    filterable:0,//是否启用分类筛选,
},
海螺2:{
    title:'',
    host:'',
    searchUrl:'/index.php/vod/search/page/fypage/wd/**/',
    url:'/index.php/vod/show/id/fyclass/page/fypage/',
    headers:{
        'User-Agent':'MOBILE_UA'
    },
    timeout:5000,
    class_parse:'#nav-bar li;a&&Text;a&&href;id/(.*?)/',
    limit:40,
    play_parse:true,
    lazy:'',
    推荐:'.list-a.size;li;a&&title;.lazy&&data-original;.bt&&Text;a&&href',
    double:true,
    一级:'.list-a&&li;a&&title;.lazy&&data-original;.list-remarks&&Text;a&&href',
    二级:{"title":"h2&&Text;.deployment&&Text","img":".lazy&&data-original","desc":".deployment&&Text","content":".ec-show&&Text","tabs":"#tag&&a","lists":".play_list_box:eq(#id)&&li"},
    搜索:'.search-list;a&&title;.lazy&&data-original;.deployment&&Text;a&&href',
    searchable:2,//是否启用全局搜索,
    quickSearch:0,//是否启用快速搜索,
    filterable:0,//是否启用分类筛选,
},

};
var muban = JSON.parse(JSON.stringify(mubanDict));
export default muban;


code:
muban.首图2.二级.tabs = '.stui-pannel__head h3';
muban.首图2.二级.content = '.stui-content__desc&&Text';
var rule = Object.assign(muban.首图2,{
    title:'牛马TV',
    host:'https://www.niumatv.cc',
    url:'/type/fyclass-fypage.html',
    searchUrl:'/vodsearch**/page/fypage.html',
    class_parse:'.stui-header__menu&&li;a&&Text;a&&href;.*/(.*?).html',
});


code:
var rule = {
    title:'猫了个咪',
    host:'http://119.28.59.69:8089',
    homeUrl:'/latest/',
    url:'/api/video/index#class=fyclass&page=fypage',
    searchUrl:'/api/special/video?params=#keyword=**&page=fypage',
    headers:{
        'User-Agent':'MOBILE_UA'
    },
    // searchable:2,
    quickSearch:0,
    timeout:5000,
    class_name:'全部&国产专区&欧美精品&动漫&中文字幕&人气女忧&不雅视频&韩三级&热剧大人版&抖音妹合集&猫咪自拍',
    class_url:'0&32&16&31&34&35&37&39&40&41&42',
    limit:5,
    play_parse:true,
    lazy:'js:log(input);',
    lazy:'js:let VID=input.split(";")[1];let VURL=input.split(";")[0];var fn=rc("maomi_aes.js");let url=VURL+"?params="+fn.En(\'{"id":"\'+VID+\'"}\');input=JSON.parse(fn.De(request(url))).data.video_item[0].file;',
    一级:'',
    一级:'js:let d=[];let bodys={access_token:"",cate_id:MY_CATE,identifier:"ffffffff-c67a-899b-ffff-ffffef05ac4a",page:MY_PAGE,region:0,type_id:0,vip:0,year:""};var fn=rc("maomi_aes.js");bodys=fn.En(stringify(bodys));let obj={headers:{"Content-Type":"application/x-www-form-urlencoded"},method:"POST",body:"params="+bodys+"&version=26&sign="+md5("QEBBQADSwrXIXaNqBmMofjfRY/8Sxaxgparams"+bodys+"version26QEBBQADSwrXIXaNqBmMofjfRY/8Sxaxg")};let api=input.split("#")[0];let html=JSON.parse(fn.De(request(api,obj)));html.data.data.forEach(function(it){d.push({title:it.name,img:it.image,desc:it.rate,url:api.replace("index","detail")+";"+it.id})});setResult(d);',
    二级:'*',
    搜索:'',
    // 搜索:'js:let bodys={keyword:KEY,page:MY_PAGE};var fn=rc("maomi_aes.js");bodys=fn.En(stringify(bodys));let url=input.split("#")[0];print(url);var html=JSON.parse(fn.De(request(url+bodys)));let d=html.data.data.map(function(data){return{title:data.video_name,img:data.image,desc:data.rate,url:"http://119.28.59.69:8089/api/video/detail?params=;"+fn.En(\'{"id":"\'+data.video_id+\'"}\')}});setResult(d);',

}


code:
muban.首图2.二级.tabs = '.dropdown-menu li';
muban.首图2.二级.重定向='js:let url = jsp.pd(html,"a.btn-primary&&href");log(url);html = request(url)';
var rule = Object.assign(muban.首图2,{
    title:'玄天',
    host:'https://m.7caa.com',
    url:'/list/fyclass-fypage.html',
    searchUrl:'/search/**----------fypage---.html',
    lazy:'通用免嗅'
});


code:
var rule = Object.assign(muban.mxpro,{
title:'瓜皮TV',
host:'https://guapitv.xyz',
class_parse:'.navbar-items li:gt(1):lt(8);a&&Text;a&&href;.*-(.*?).html',
});


code:
var rule = Object.assign(muban.海螺3,{
title:'番茄影视',
host:'https://www.tjomet.com',
url:'/vodshow/fyclass--------fypage---.html',
searchUrl:'/vodsearch/**----------fypage---.html',
});


code:
var rule = Object.assign(muban.mxpro,{
title:'看视界',
host:'https://www.1080kan.cc',
url:'/show/fyclass--------fypage---.html',
searchUrl:'/search/**----------fypage---.html',
searchable:2,
class_parse:'.navbar-items li:gt(1):lt(6);a&&Text;a&&href;.*/(.*?).html',
});


code:
muban.首图2.二级.tabs = '.stui-pannel__head.bottom-line.active.clearfix h3';
var rule = Object.assign(muban.首图2,{
title:'真不卡',
host:'https://www.zbkk.net',
url:'/vodshow/fyclass--------fypage---.html',
class_parse:'.stui-header__menu .dropdown li:gt(0):lt(5);a&&Text;a&&href;.*/(.*?).html',
// searchUrl:'/vodsearch/**----------fypage---.html',
});


code:
var rule = Object.assign(muban.mxpro,{
title:'莫扎兔',
host:'https://www.mozhatu.com',
url:'/index.php/vod/show/id/fyclass/page/fypage.html',
searchUrl:'/index.php/vod/search/page/fypage/wd/**.html',
class_parse:'.navbar-items li:gt(2):lt(8);a&&Text;a&&href;.*/(.*?).html',
});


code:
var rule = Object.assign(muban.mxpro,{
title:'蓝光影院',
host:'https://lgyy.cc',
url:'/vodshow/fyclass--------fypage---.html',
searchUrl:'/vodsearch/**-------------.html',
class_parse:'.navbar-items li:gt(1):lt(6);a&&Text;a&&href;.*/(.*?).html',
});


code:
// muban.海螺2.二级.content = '.hl-infos-content&&Text';
var rule = Object.assign(muban.海螺2,{
    title:'追剧喵',
    host:'https://zjmiao.com',
    搜索:'.search-list;a&&Text;.lazy&&data-original;.deployment&&Text;a&&href',
});


code:
var rule = Object.assign(muban.mxpro,{
title:'鸭奈飞',
host:'https://yanetflix.com',
url:'/vodshow/fyclass--------fypage---.html',
class_parse:'.navbar-items li:gt(1):lt(6);a&&Text;a&&href;.*/(.*?).html',
});


code:
# coding=utf-8
# !/usr/bin/python
import sys

sys.path.append('..')
from base.spider import Spider
import json
from requests import session, utils
import os
import time
import base64

class Spider(Spider):  # 元类 默认的元类 type
    def getName(self):
        return "哔哩影视"

    def init(self, extend=""):
        print("============{0}============".format(extend))
        pass

    def isVideoFormat(self, url):
        pass

    def manualVideoCheck(self):
        pass

    def homeContent(self, filter):
        result = {}
        cateManual = {
            "番剧": "1",
            "国创": "4",
            "电影": "2",
            "电视剧": "5",
            "纪录片": "3",
            "综艺": "7",
            "全部": "全部",
            "追番": "追番",
            "追剧": "追剧",
            "时间表": "时间表",

        }
        classes = []
        for k in cateManual:
            classes.append({
                'type_name': k,
                'type_id': cateManual[k]
            })
        result['class'] = classes
        if (filter):
            result['filters'] = self.config['filter']
        return result

    cookies = ''
    userid = ''

    def getCookie(self):
        # --------↓↓↓↓↓↓↓------在下方cookies_str后的双引号内填写-------↓↓↓↓↓↓↓--------
        cookies_str = "_uuid=5E4B2B98-1014A-84D8-FA33-EC210C5BEC10DA82367infoc; buvid3=E9D0A426-85E9-E6C7-C75E-206A3E1BEB4D81910infoc; b_nut=1666168082; buvid4=4FC87B9C-3540-2275-688C-8612D3EA719B81910-022101916-ZLe640jXRAMHySuaCe9aUw==; rpdid=|(k|u)YYm)uY0J'uYYYuY)uuu; i-wanna-go-back=-1; fingerprint=9c214a6da0197a48e576ccf22e9f0ac7; buvid_fp_plain=undefined; nostalgia_conf=-1; DedeUserID=3493076028885079; DedeUserID__ckMd5=60a8757a1f4d6ae9; buvid_fp=9c214a6da0197a48e576ccf22e9f0ac7; CURRENT_QUALITY=80; b_ut=5; PVID=2; bp_video_offset_3493076028885079=undefined; bsource=search_google; SESSDATA=42b8ada6,1683277266,4bd05*b2; bili_jct=2dbe39aea02b41324395630a24d4775f; sid=89gnel66; innersign=0; b_lsid=9EF63922_1844D55A286; CURRENT_FNVAL=4048",
        if cookies_str:
            cookies = dict([co.strip().split('=', 1) for co in cookies_str.split(';')])
            bili_jct = cookies['bili_jct']
            SESSDATA = cookies['SESSDATA']
            DedeUserID = cookies['DedeUserID']
            cookies_jar = {"bili_jct": bili_jct,
                           'SESSDATA': SESSDATA,
                           'DedeUserID': DedeUserID
                           }
            rsp = session()
            rsp.cookies = cookies_jar
            content = self.fetch("https://api.bilibili.com/x/web-interface/nav", cookies=rsp.cookies)
            res = json.loads(content.text)
            if res["code"] == 0:
                self.cookies = rsp.cookies
                self.userid = res["data"].get('mid')
                return rsp.cookies
        rsp = self.fetch("https://www.bilibili.com/")
        self.cookies = rsp.cookies
        return rsp.cookies

    # 将超过10000的数字换成成以万和亿为单位
    def zh(self, num):
        if int(num) >= 100000000:
            p = round(float(num) / float(100000000), 1)
            p = str(p) + '亿'
        else:
            if int(num) >= 10000:
                p = round(float(num) / float(10000), 1)
                p = str(p) + '万'
            else:
                p = str(num)
        return p

    def homeVideoContent(self):
        result = {}
        videos = self.get_rank(1)['list'][0:5]
        for i in [4, 2, 5, 3, 7]:
            videos += self.get_rank2(i)['list'][0:5]
        result['list'] = videos
        return result

    def get_rank(self, tid):
        result = {}
        url = 'https://api.bilibili.com/pgc/web/rank/list?season_type={0}&day=3'.format(tid)
        rsp = self.fetch(url, cookies=self.cookies)
        content = rsp.text
        jo = json.loads(content)
        if jo['code'] == 0:
            videos = []
            vodList = jo['result']['list']
            for vod in vodList:
                aid = str(vod['season_id']).strip()
                title = vod['title'].strip()
                img = vod['cover'].strip()
                remark = vod['new_ep']['index_show']
                videos.append({
                    "vod_id": aid,
                    "vod_name": title,
                    "vod_pic": img,
                    "vod_remarks": remark
                })
            result['list'] = videos
            result['page'] = 1
            result['pagecount'] = 1
            result['limit'] = 90
            result['total'] = 999999
        return result

    def get_rank2(self, tid):
        result = {}
        url = 'https://api.bilibili.com/pgc/season/rank/web/list?season_type={0}&day=3'.format(tid)
        rsp = self.fetch(url, cookies=self.cookies)
        content = rsp.text
        jo = json.loads(content)
        if jo['code'] == 0:
            videos = []
            vodList = jo['data']['list']
            for vod in vodList:
                aid = str(vod['season_id']).strip()
                title = vod['title'].strip()
                img = vod['cover'].strip()
                remark = vod['new_ep']['index_show']
                videos.append({
                    "vod_id": aid,
                    "vod_name": title,
                    "vod_pic": img,
                    "vod_remarks": remark
                })
            result['list'] = videos
            result['page'] = 1
            result['pagecount'] = 1
            result['limit'] = 90
            result['total'] = 999999
        return result

    def get_zhui(self, pg, mode):
        result = {}
        if len(self.cookies) <= 0:
            self.getCookie()
        url = 'https://api.bilibili.com/x/space/bangumi/follow/list?type={2}&follow_status=0&pn={1}&ps=10&vmid={0}'.format(self.userid, pg, mode)
        rsp = self.fetch(url, cookies=self.cookies)
        content = rsp.text
        jo = json.loads(content)
        videos = []
        vodList = jo['data']['list']
        for vod in vodList:
            aid = str(vod['season_id']).strip()
            title = vod['title']
            img = vod['cover'].strip()
            remark = vod['new_ep']['index_show'].strip()
            videos.append({
                "vod_id": aid,
                "vod_name": title,
                "vod_pic": img,
                "vod_remarks": remark
            })
        result['list'] = videos
        result['page'] = pg
        result['pagecount'] = 9999
        result['limit'] = 90
        result['total'] = 999999
        return result

    def get_all(self, tid, pg, order, season_status, extend):
        result = {}
        if len(self.cookies) <= 0:
            self.getCookie()
        url = 'https://api.bilibili.com/pgc/season/index/result?order={2}&pagesize=20&type=1&season_type={0}&page={1}&season_status={3}'.format(tid, pg, order, season_status)
        rsp = self.fetch(url, cookies=self.cookies)
        content = rsp.text
        jo = json.loads(content)
        videos = []
        vodList = jo['data']['list']
        for vod in vodList:
            aid = str(vod['season_id']).strip()
            title = vod['title']
            img = vod['cover'].strip()
            remark = vod['index_show'].strip()
            videos.append({
                "vod_id": aid,
                "vod_name": title,
                "vod_pic": img,
                "vod_remarks": remark
            })
        result['list'] = videos
        result['page'] = pg
        result['pagecount'] = 9999
        result['limit'] = 90
        result['total'] = 999999
        return result

    def get_timeline(self, tid, pg):
        result = {}
        url = 'https://api.bilibili.com/pgc/web/timeline/v2?season_type={0}&day_before=2&day_after=4'.format(tid)
        rsp = self.fetch(url, cookies=self.cookies)
        content = rsp.text
        jo = json.loads(content)
        if jo['code'] == 0:
            videos1 = []
            vodList = jo['result']['latest']
            for vod in vodList:
                aid = str(vod['season_id']).strip()
                title = vod['title'].strip()
                img = vod['cover'].strip()
                remark = vod['pub_index'] + '　' + vod['follows'].replace('系列', '')
                videos1.append({
                    "vod_id": aid,
                    "vod_name": title,
                    "vod_pic": img,
                    "vod_remarks": remark
                })
            videos2 = []
            for i in range(0, 7):
                vodList = jo['result']['timeline'][i]['episodes']
                for vod in vodList:
                    if str(vod['published']) == "0":
                        aid = str(vod['season_id']).strip()
                        title = str(vod['title']).strip()
                        img = str(vod['cover']).strip()
                        date = str(time.strftime("%m-%d %H:%M", time.localtime(vod['pub_ts'])))
                        remark = date + "   " + vod['pub_index']
                        videos2.append({
                            "vod_id": aid,
                            "vod_name": title,
                            "vod_pic": img,
                            "vod_remarks": remark
                        })
            result['list'] = videos2 + videos1
            result['page'] = 1
            result['pagecount'] = 1
            result['limit'] = 90
            result['total'] = 999999
        return result

    def categoryContent(self, tid, pg, filter, extend):
        result = {}
        if len(self.cookies) <= 0:
            self.getCookie()
        if tid == "1":
            return self.get_rank(tid=tid)
        elif tid in {"2", "3", "4", "5", "7"}:
            return self.get_rank2(tid=tid)
        elif tid == "全部":
            tid = '1'    # 全部界面默认展示最多播放的番剧
            order = '2'
            season_status = '-1'
            if 'tid' in extend:
                tid = extend['tid']
            if 'order' in extend:
                order = extend['order']
            if 'season_status' in extend:
                season_status = extend['season_status']
            return self.get_all(tid, pg, order, season_status, extend)
        elif tid == "追番":
            return self.get_zhui(pg, 1)
        elif tid == "追剧":
            return self.get_zhui(pg, 2)
        elif tid == "时间表":
            tid = 1
            if 'tid' in extend:
                tid = extend['tid']
            return self.get_timeline(tid, pg)
        else:
            result = self.searchContent(key=tid,  quick="false")
        return result

    def cleanSpace(self, str):
        return str.replace('\n', '').replace('\t', '').replace('\r', '').replace(' ', '')

    def detailContent(self, array):
        aid = array[0]
        url = "https://api.bilibili.com/pgc/view/web/season?season_id={0}".format(aid)
        rsp = self.fetch(url, headers=self.header)
        jRoot = json.loads(rsp.text)
        jo = jRoot['result']
        id = jo['season_id']
        title = jo['title']
        pic = jo['cover']
        # areas = jo['areas']['name']  改bilidanmu显示弹幕
        typeName = jo['share_sub_title']
        date = jo['publish']['pub_time'][0:4]
        dec = jo['evaluate']
        remark = jo['new_ep']['desc']
        stat = jo['stat']
        # 演员和导演框展示视频状态，包括以下内容：
        status = "弹幕: " + self.zh(stat['danmakus']) + "　点赞: " + self.zh(stat['likes']) + "　投币: " + self.zh(
            stat['coins']) + "　追番追剧: " + self.zh(stat['favorites'])
        if 'rating' in jo:
            score = "评分: " + str(jo['rating']['score']) + '　' + jo['subtitle']
        else:
            score = "暂无评分" + '　' + jo['subtitle']
        vod = {
            "vod_id": id,
            "vod_name": title,
            "vod_pic": pic,
            "type_name": typeName,
            "vod_year": date,
            "vod_area": "bilidanmu",
            "vod_remarks": remark,
            "vod_actor": status,
            "vod_director": score,
            "vod_content": dec
        }
        ja = jo['episodes']
        playUrl = ''
        for tmpJo in ja:
            eid = tmpJo['id']
            cid = tmpJo['cid']
            part = tmpJo['title'].replace("#", "-")
            playUrl = playUrl + '{0}${1}_{2}#'.format(part, eid, cid)

        vod['vod_play_from'] = 'B站'
        vod['vod_play_url'] = playUrl

        result = {
            'list': [
                vod
            ]
        }
        return result

    def searchContent(self, key, quick):
        if len(self.cookies) <= 0:
            self.getCookie()
        url1 = 'https://api.bilibili.com/x/web-interface/search/type?search_type=media_bangumi&keyword={0}'.format(
            key)  # 番剧搜索
        rsp1 = self.fetch(url1, cookies=self.cookies)
        content1 = rsp1.text
        jo1 = json.loads(content1)
        rs1 = jo1['data']
        url2 = 'https://api.bilibili.com/x/web-interface/search/type?search_type=media_ft&keyword={0}'.format(
            key)  # 影视搜索
        rsp2 = self.fetch(url2, cookies=self.cookies)
        content2 = rsp2.text
        jo2 = json.loads(content2)
        rs2 = jo2['data']
        videos = []
        if rs1['numResults'] == 0:
            vodList = jo2['data']['result']
        elif rs2['numResults'] == 0:
            vodList = jo1['data']['result']
        else:
            vodList = jo1['data']['result'] + jo2['data']['result']
        for vod in vodList:
            aid = str(vod['season_id']).strip()
            title = key + '➢' + vod['title'].strip().replace("", "").replace("", "")
            img = vod['cover'].strip()  # vod['eps'][0]['cover'].strip()原来的错误写法
            remark = vod['index_show']
            videos.append({
                "vod_id": aid,
                "vod_name": title,
                "vod_pic": img,
                "vod_remarks": remark
            })
        result = {
            'list': videos
        }
        return result

    def playerContent(self, flag, id, vipFlags):
        result = {}
        ids = id.split("_")
        header = {
            "Referer": "https://www.bilibili.com",
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
        }
        url = 'https://api.bilibili.com/pgc/player/web/playurl?qn=116&ep_id={0}&cid={1}'.format(ids[0], ids[1])
        if len(self.cookies) <= 0:
            self.getCookie()
        rsp = self.fetch(url, cookies=self.cookies, headers=header)
        jRoot = json.loads(rsp.text)
        if jRoot['message'] != 'success':
            print("需要大会员权限才能观看")
            return {}
        jo = jRoot['result']
        ja = jo['durl']
        maxSize = -1
        position = -1
        for i in range(len(ja)):
            tmpJo = ja[i]
            if maxSize < int(tmpJo['size']):
                maxSize = int(tmpJo['size'])
                position = i

        url = ''
        if len(ja) > 0:
            if position == -1:
                position = 0
            url = ja[position]['url']

        result["parse"] = 0
        result["playUrl"] = ''
        result["url"] = url
        result["header"] = {
            "Referer": "https://www.bilibili.com",
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
        }
        result["contentType"] = 'video/x-flv'
        return result

    config = {
        "player": {},
        "filter": {
            "全部": [
                {
                    "key": "tid",
                    "name": "分类",
                    "value": [{
                        "n": "番剧",
                        "v": "1"
                    },
                        {
                            "n": "国创",
                            "v": "4"
                        },

                        {
                            "n": "电影",
                            "v": "2"
                        },
                        {
                            "n": "电视剧",
                            "v": "5"
                        },
                        {
                            "n": "记录片",
                            "v": "3"
                        },
                        {
                            "n": "综艺",
                            "v": "7"
                        }

                    ]
                },
                {
                    "key": "order",
                    "name": "排序",
                    "value": [

                        {
                            "n": "播放数量",
                            "v": "2"
                        },

                        {
                            "n": "更新时间",
                            "v": "0"
                        },

                        {
                            "n": "最高评分",
                            "v": "4"
                        },
                        {
                            "n": "弹幕数量",
                            "v": "1"
                        },
                        {
                            "n": "追看人数",
                            "v": "3"
                        },

                        {
                            "n": "开播时间",
                            "v": "5"
                        },
                        {
                            "n": "上映时间",
                            "v": "6"
                        },

                    ]
                },
                {
                    "key": "season_status",
                    "name": "付费",
                    "value": [
                        {
                            "n": "全部",
                            "v": "-1"
                        },
                        {
                            "n": "免费",
                            "v": "1"
                        },

                        {
                            "n": "付费",
                            "v": "2%2C6"
                        },

                        {
                            "n": "大会员",
                            "v": "4%2C6"
                        },

                    ]
                },
            ],

            "时间表": [{
                "key": "tid",
                "name": "分类",
                "value": [

                    {
                        "n": "番剧",
                        "v": "1"
                    },

                    {
                        "n": "国创",
                        "v": "4"
                    },

                ]
            },
            ],
        }
    }

    header = {
        "Referer": "https://www.bilibili.com",
        "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
    }

    def localProxy(self, param):
        return [200, "video/MP2T", action, ""]


code:
# coding=utf-8
# !/usr/bin/python
import sys
sys.path.append('..')
from base.spider import Spider
import json
import re
import urllib
import difflib

class Spider(Spider):  # 元类 默认的元类 type
    def getName(self):
        return "Alist"

    def init(self, extend=""):
        print("============{0}============".format(extend))
        pass

    def isVideoFormat(self, url):
        pass

    def manualVideoCheck(self):
        pass

    def homeContent(self, filter):
        result = {}
        cateManual = {
            "七米蓝": "https://al.chirmyram.com",
            "杜比": "https://dubi.tk",
            "神器云": "https://al.chirmyram.com",
            "甜蜜2": "https://alist3.kebedd69.repl.co",
            "xiaoya2": "http://myalist.site",
            "xiaoya3": "http://alist.xiaoya.pro",
            "甜蜜": "https://alist.kebedd69.repl.co",
            "梅花盘": "https://pan.142856.xyz/OneDrive",
            "触光云盘": "https://pan.ichuguang.com",
            "小孟资源": "https://8023.haohanba.cn/小孟丨资源大合集/无损音乐",
            "资源小站": "https://960303.xyz/ali",
            "轻弹浅唱": "https://g.xiang.lol",
            "小兵组网盘视频": "https://6vv.app"
        }
        classes = []
        for k in cateManual:
            classes.append({
                'type_name': k,
				"type_flag": "1",
                'type_id': cateManual[k]
            })
        result['class'] = classes
        if (filter):
            filters = {}
            for lk in cateManual:
                link = cateManual[lk]
                filters.update({
                    link: [{"key": "nm", "name": "名        称", "value": [{"n": "复位", "v": ""},{"n": "正序", "v": "False"},{"n": "反序", "v": "True"}]},{"key": "sz", "name": "大        小", "value": [{"n": "复位", "v": ""},{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]},{"key": "tp", "name": "类        型", "value": [{"n": "复位", "v": ""},{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]},{"key": "tm", "name": "修改时间", "value": [{"n": "复位", "v": ""},{"n": "升序", "v": "False"},{"n": "降序", "v": "True"}]}]
                })
            result['filters'] = filters
        return result

    def homeVideoContent(self):
        result = {
            'list': []
        }
        return result

    ver = ''
    baseurl = ''
    def getVersion(self, gtid):
        param = {
            "path": '/'
        }
        if gtid.count('/') == 2:
            gtid = gtid + '/'
        baseurl = re.findall(r"http.*://.*?/", gtid)[0]
        ver = self.fetch(baseurl + 'api/public/settings', param)
        vjo = json.loads(ver.text)['data']
        if type(vjo) is dict:
            ver = 3
        else:
            ver = 2
        self.ver = ver
        self.baseurl = baseurl

    def categoryContent(self, tid, pg, filter, extend):
        result = {}
        if tid.count('/') == 2:
            tid = tid + '/'
        nurl = re.findall(r"http.*://.*?/", tid)[0]
        if self.ver == '' or self.baseurl != nurl:
            self.getVersion(tid)
        ver = self.ver
        baseurl = self.baseurl
        if tid.count('/') == 2:
            tid = tid + '/'
        pat = tid.replace(baseurl,"")
        param = {
            "path": '/' + pat
        }
        if ver == 2:
            rsp = self.postJson(baseurl + 'api/public/path', param)
            jo = json.loads(rsp.text)
            vodList = jo['data']['files']
        elif ver == 3:
            rsp = self.postJson(baseurl + 'api/fs/list', param)
            jo = json.loads(rsp.text)
            vodList = jo['data']['content']
        ovodList = vodList
        if len(extend) != 0:
            if 'tp' in extend and extend['tp'] != '':
                fl = 'type'
                if extend['tp'] == "True":
                    key = True
                if extend['tp'] == "False":
                    key = False
                vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
            elif 'sz' in extend and extend['sz'] != '':
                fl = 'size'
                if extend['sz'] == "True":
                    key = True
                if extend['sz'] == "False":
                    key = False
                vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
            elif 'nm' in extend and extend['nm'] != '':
                fl = 'name'
                if extend['nm'] == "True":
                    key = True
                if extend['nm'] == "False":
                    key = False
                vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
            elif 'tm' in extend and extend['tm'] != '':
                if ver == 2:
                    fl = 'updated_at'
                elif ver == 3:
                    fl = 'modified'
                if extend['tm'] == "True":
                    key = True
                if extend['tm'] == "False":
                    key = False
                vodList.sort(key=lambda x: (x['{0}'.format(fl)]), reverse=key)
            else:
                vodList = ovodList
        else:
            vodList = ovodList
        videos = []
        cid = ''
        purl = ''
        svodList = str(vodList)
        lenvodList = len(vodList)
        nameList = re.findall(r"\'name\': \'(.*?)\'", svodList)
        substr = str(nameList)
        foldernum = svodList.count('\'type\': 1')
        filenum = lenvodList - foldernum
        for vod in vodList:
            if ver == 2:
                img = vod['thumbnail']
            elif ver == 3:
                img = vod['thumb']
            if len(img) == 0:
                if vod['type'] == 1:
                    img = "http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png"
            if pat != '':
                aid = pat + '/'
            else:
                aid = pat
            if vod['type'] == 1:
                tag = "folder"
                remark = "文件夹"
                cid = baseurl + aid + vod['name']
            #计算文件大小
            else:
                size = vod['size']
                if size > 1024 * 1024 * 1024 * 1024.0:
                    fs = "TB"
                    sz = round(size / (1024 * 1024 * 1024 * 1024.0), 2)
                elif size > 1024 * 1024 * 1024.0:
                    fs = "GB"
                    sz = round(size / (1024 * 1024 * 1024.0), 2)
                elif size > 1024 * 1024.0:
                    fs = "MB"
                    sz = round(size / (1024 * 1024.0), 2)
                elif size > 1024.0:
                    fs = "KB"
                    sz = round(size / (1024.0), 2)
                else:
                    fs = "KB"
                    sz = round(size / (1024.0), 2)
                tag = "file"
                remark = str(sz) + fs
                cid = baseurl + aid + vod['name']
                # 开始爬视频与字幕
                if filenum < 150:
                    if vod['name'].endswith('.mp4') or vod['name'].endswith('.mkv') or vod['name'].endswith('.ts') or vod['name'].endswith('.TS') or vod['name'].endswith('.avi') or vod['name'].endswith('.flv') or vod['name'].endswith('.rmvb') or vod['name'].endswith('.mp3') or vod['name'].endswith('.flac') or vod['name'].endswith('.wav') or vod['name'].endswith('.wma') or vod['name'].endswith('.dff'):
                        vodurl = vod['name']
                        # 开始爬字幕
                        cid = '###'
                        subname = re.findall(r"(.*)\.", vod['name'])[0]
                        if filenum == 2:
                            if '.ass' in substr:
                                sub = difflib.get_close_matches('.ass', nameList, 1, cutoff=0.1)
                                if len(sub) != 0:
                                    sub = sub[0]
                                else:
                                    sub = ''
                                if sub.endswith('.ass'):
                                    subt = '@@@' + sub
                            if '.srt' in substr:
                                sub = difflib.get_close_matches('.srt', nameList, 1, cutoff=0.1)
                                if len(sub) != 0:
                                    sub = sub[0]
                                else:
                                    sub = ''
                                if sub.endswith('.srt'):
                                    subt = '@@@' + sub
                        else:
                            if '.ass' in substr:
                                sub = difflib.get_close_matches('{0}.ass'.format(subname), nameList, 1, cutoff=0.1)
                                if len(sub) != 0:
                                    sub = sub[0]
                                else:
                                    sub = ''
                                if subname in sub and sub.endswith('.ass'):
                                    subt = '@@@' + sub
                            elif '.srt' in substr:
                                sub = difflib.get_close_matches('{0}.srt'.format(subname), nameList, 1, cutoff=0.1)
                                if len(sub) != 0:
                                    sub = sub[0]
                                else:
                                    sub = ''
                                if subname in sub and sub.endswith('.srt'):
                                    subt = '@@@' + sub
                        # 合并链接
                        if 'subt' in locals().keys():
                            purl = purl + '{0}{1}##'.format(vodurl, subt)
                        else:
                            purl = purl + '{0}##'.format(vodurl)
                else:
                    subname = re.findall(r"(.*)\.", vod['name'])[0]
                    if '.ass' in substr:
                        sub = difflib.get_close_matches('{0}.ass'.format(subname), nameList, 1, cutoff=0.1)
                        if len(sub) != 0:
                            sub = sub[0]
                        else:
                            sub = ''
                        if subname in sub and sub.endswith('.ass'):
                            subt = '@@@' + sub
                            cid = cid + subt
                    elif '.srt' in substr:
                        sub = difflib.get_close_matches('{0}.srt'.format(subname), nameList, 1, cutoff=0.1)
                        if len(sub) != 0:
                            sub = sub[0]
                        else:
                            sub = ''
                        if subname in sub and sub.endswith('.srt'):
                            subt = '@@@' + sub
                            cid = cid + subt
            videos.append({
                "vod_id":  cid,
                "vod_name": vod['name'],
                "vod_pic": img,
                "vod_tag": tag,
                "vod_remarks": remark
            })
        if 'purl' in locals().keys():
            purl = baseurl + aid + '+++' + purl
            for i in range(foldernum, lenvodList):
                if videos[i]['vod_id'] == '###':
                    videos[i]['vod_id'] = purl
        result['list'] = videos
        result['page'] = 1
        result['pagecount'] = 1
        result['limit'] = lenvodList
        result['total'] = lenvodList
        return result

    def detailContent(self, array):
        id = array[0]
        if '+++' in id:
            ids = id.split('+++')
            durl = ids[0]
            vsList = ids[1].strip('##').split('##')
            vsurl = ''
            for vs in vsList:
                if '@@@' in vs:
                    dvs = vs.split('@@@')
                    vname = dvs[0].replace('#','-')
                    vurl = durl + dvs[0].replace('#','---')
                    surl = durl + dvs[1].replace('#','---')
                    vsurl = vsurl + '{0}${1}@@@{2}#'.format(vname, vurl, surl)
                else:
                    vurl = durl + vs.replace('#','---')
                    vsurl = vsurl + '{0}${1}#'.format(vs.replace('#','-'), vurl)
            url = vsurl
        else:
            durl = id.replace('#','-')
        if self.ver == '' or self.baseurl == '':
            self.getVersion(durl)
        baseurl = self.baseurl
        if '+++' in id:
            vid = durl.replace(baseurl, "").strip('/')
        else:
            vid = durl.replace(re.findall(r".*/", durl)[0], "")
            url = vid + '$' + id.replace('#','---')
        vod = {
            "vod_id": vid,
            "vod_name": vid,
            "vod_pic": '',
            "vod_tag": '',
            "vod_play_from": "播放",
            "vod_play_url": url
        }
        result = {
            'list': [
                vod
            ]
        }
        return result

    def searchContent(self, key, quick):
        result = {
            'list': []
        }
        return result

    def playerContent(self, flag, id, vipFlags):
        result = {}
        url = ''
        subturl = ''
        id = id.replace('---','#')
        ifsub = '@@@' in id
        if ifsub is True:
            ids = id.split('@@@')
            if self.ver == '' or self.baseurl == '':
                self.getVersion(ids[1])
            ver = self.ver
            baseurl = self.baseurl
            fileName = ids[1].replace(baseurl, "")
            vfileName = ids[0].replace(baseurl, "")
            param = {
                "path": '/' + fileName,
                "password": "",
                "page_num": 1,
                "page_size": 100
            }
            vparam = {
                "path": '/' + vfileName,
                "password": "",
                "page_num": 1,
                "page_size": 100
            }
            if ver == 2:
                rsp = self.postJson(baseurl + 'api/public/path', param)
                jo = json.loads(rsp.text)
                vodList = jo['data']['files'][0]
                subturl = vodList['url']
                vrsp = self.postJson(baseurl + 'api/public/path', vparam)
                vjo = json.loads(vrsp.text)
                vList = vjo['data']['files'][0]
                url = vList['url']
            elif ver == 3:
                rsp = self.postJson(baseurl + 'api/fs/get', param)
                jo = json.loads(rsp.text)
                vodList = jo['data']
                subturl = vodList['raw_url']
                vrsp = self.postJson(baseurl + 'api/fs/get', vparam)
                vjo = json.loads(vrsp.text)
                vList = vjo['data']
                url = vList['raw_url']
            if subturl.startswith('http') is False:
                head = re.findall(r"h.*?:", baseurl)[0]
                subturl = head + subturl
            if url.startswith('http') is False:
                head = re.findall(r"h.*?:", baseurl)[0]
                url = head + url
            urlfileName = urllib.parse.quote(fileName)
            subturl = subturl.replace(fileName, urlfileName)
            urlvfileName = urllib.parse.quote(vfileName)
            url = url.replace(vfileName, urlvfileName)
            result['subt'] = subturl
        else:
            if self.ver == '' or self.baseurl == '':
                self.getVersion(id)
            ver = self.ver
            baseurl = self.baseurl
            vfileName = id.replace(baseurl, "")
            vparam = {
                "path": '/' + vfileName,
                "password": "",
                "page_num": 1,
                "page_size": 100
            }
            if ver == 2:
                vrsp = self.postJson(baseurl + 'api/public/path', vparam)
                vjo = json.loads(vrsp.text)
                vList = vjo['data']['files'][0]
                driver = vList['driver']
                url = vList['url']
            elif ver == 3:
                vrsp = self.postJson(baseurl + 'api/fs/get', vparam)
                vjo = json.loads(vrsp.text)
                vList = vjo['data']
                url = vList['raw_url']
                driver = vList['provider']
            if url.startswith('http') is False:
                head = re.findall(r"h.*?:", baseurl)[0]
                url = head + url
            urlvfileName = urllib.parse.quote(vfileName)
            url = url.replace(vfileName, urlvfileName)
            if driver == 'Baidu.Disk':
                result["header"] = {"User-Agent": "pan.baidu.com"}

        result["parse"] = 0
        result["playUrl"] = ''
        result["url"] = url

        return result

    flurl = ''
    config = {
        "player": {},
        "filter": {}
    }
    header = {}

    def localProxy(self, param):
        return [200, "video/MP2T", action, ""]


code:
# coding=utf-8
# !/usr/bin/python
import sys
import re
sys.path.append('..')
from base.spider import Spider
import urllib.parse

class Spider(Spider):  # 元类 默认的元类 type
    def getName(self):
        return "555影视"

    def init(self, extend=""):
        print("============{0}============".format(extend))
        pass

    def homeContent(self, filter):
        result = {}
        cateManual = {
			"电影": "1",
			"剧集": "2",
			"综艺": "3",
			"动漫": "4"
        }
        classes = []
        for k in cateManual:
            classes.append({
                'type_name': k,
                'type_id': cateManual[k]
            })

        result['class'] = classes
        if (filter):
            result['filters'] = self.config['filter']
        return result

    def homeVideoContent(self):
        result = {
            'list': []
        }
        return result

    def categoryContent(self, tid, pg, filter, extend):
        result = {}
        header = {"User-Agent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36"}
        url = 'https://555dy1.com/vodtype/{0}-{1}.html'.format(tid, pg)
        rsp = self.fetch(url,headers=header)
        root = self.html(self.cleanText(rsp.text))
        aList = root.xpath("//div[@class='module-items module-poster-items-base ']/a"")
        videos = []
        for a in aList:
            name = a.xpath('./@title')[0]
            pic = a.xpath('.//div[@class='module-item-pic']/img/@data-original"')[0]
            mark = a.xpath(".//div[@class='module-item-note']/text()")[0]
            sid = a.xpath("./@href")[0].replace("/", "").replace("voddetail", "").replace(".html", "")
            videos.append({
                "vod_id": sid,
                "vod_name": name,
                "vod_pic": pic,
                "vod_remarks": mark
            })
        result['list'] = videos
        result['page'] = pg
        result['pagecount'] = 999
        result['limit'] = 5
        result['total'] = 9999
        return result

    def detailContent(self, array):
        tid = array[0]
        url = 'https://555dy1.com/vodtype/{0}.html'.format(tid)
        header = {"User-Agent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36"}
        rsp = self.fetch(url,headers=header)
        root = self.html(self.cleanText(rsp.text))
        divContent = root.xpath("//div[@class='col-lg-wide-75 col-md-wide-7 col-xs-1 padding-0']")[0]
        title = divContent.xpath(".//div[@class='myui-content__detail']/h1/text()")[0]
        pic = divContent.xpath(".//div[@class='myui-content__thumb']/a/img/@data-original")[0]
        det = divContent.xpath(".//div[@class='col-pd text-collapse content']/span[@class='data']")[0]
        if det.text is None:
            detail = det.xpath(".//p/text()")[0]
        else:
            detail = det.text
        vod = {
            "vod_id": tid,
            "vod_name": title,
            "vod_pic": pic,
            "type_name": "",
            "vod_year": "",
            "vod_area": "",
            "vod_remarks": "",
            "vod_actor": "",
            "vod_director": "",
            "vod_content": detail
        }
        infoArray = divContent.xpath(".//div[@class='myui-content__detail']/p[contains(@class,'data')]")
        for info in infoArray:
            content = info.xpath('string(.)')
            flag = "分类" in content
            if flag == True:
                infon = content.replace("\t","").replace("\n","").strip().split('\r')
                for inf in infon:
                    if inf.startswith('分类'):
                        vod['type_name'] = inf.replace("分类：", "")
                    if inf.startswith('地区'):
                        vod['vod_area'] = inf.replace("地区：", "")
                    if inf.startswith('年份'):
                        vod['vod_year'] = inf.replace("年份：", "")
            if content.startswith('主演'):
                vod['vod_actor'] = content.replace("\xa0", "/").replace("主演：", "").strip('/')
            if content.startswith('更新'):
                vod['vod_remarks'] = content.replace("更新：", "")
            if content.startswith('导演'):
                vod['vod_director'] = content.replace("\xa0", "").replace("导演：", "").strip('/')

        vod_play_from = '$$$'
        playFrom = []
        vodHeader = divContent.xpath(".//div[@class='myui-panel_hd']/div/ul/li/a[contains(@href,'playlist')]/text()")
        for v in vodHeader:
            playFrom.append(v.replace(" ", ""))
        vod_play_from = vod_play_from.join(playFrom)

        vod_play_url = '$$$'
        playList = []
        vodList = divContent.xpath(".//div[contains(@id,'playlist')]")
        for vl in vodList:
            vodItems = []
            aList = vl.xpath('./ul/li/a')
            if len(aList) <= 0:
                name = '无法找到播放源'
                tId = '00000'
                vodItems.append(name + "$" + tId)
            else:
                for tA in aList:
                    href = tA.xpath('./@href')[0]
                    name = tA.xpath("./text()")[0].replace(" ", "")
                    tId = self.regStr(href, '/vodplay/(\\S+).html')
                    vodItems.append(name + "$" + tId)
            joinStr = '#'
            joinStr = joinStr.join(vodItems)
            playList.append(joinStr)
        vod_play_url = vod_play_url.join(playList)

        vod['vod_play_from'] = vod_play_from
        vod['vod_play_url'] = vod_play_url
        result = {
            'list': [
                vod
            ]
        }
        return result

    def searchContent(self, key, quick):
        url = 'https://www.30dian.cn/vodsearch/-------------.html?wd={0}'.format(key)
        header = {
            "User-Agent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36"}
        rsp = self.fetch(url, headers=header)
        root = self.html(self.cleanText(rsp.text))
        aList = root.xpath("//ul[contains(@class,'myui-vodlist__media clearfix')]/li")
        videos = []
        for a in aList:
            name = a.xpath(".//div[@class='detail']/h4/a/text()")[0]
            pic = a.xpath(".//a[contains(@class,'myui-vodlist__thumb')]//@data-original")[0]
            mark = a.xpath(".//span[@class='tag']/text()")[0]
            sid = a.xpath(".//div[@class='detail']/h4/a/@href")[0]
            sid = self.regStr(sid,'/voddetail/(\\S+).html')
            videos.append({
                "vod_id": sid,
                "vod_name": name,
                "vod_pic": pic,
                "vod_remarks": mark
            })
        result = {
            'list': videos
        }
        return result

    def playerContent(self, flag, id, vipFlags):
        result = {}
        header = {
            "User-Agent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36"}
        if id == '00000':
            return {}
        url = 'https://www.30dian.cn/vodplay/{0}.html'.format(id)
        rsp = self.fetch(url,headers=header)
        root = self.html(self.cleanText(rsp.text))
        scripts = root.xpath("//div[@class='embed-responsive clearfix']/script[@type='text/javascript']/text()")[0]
        ukey = re.findall(r"url(.*)url_next", scripts)[0].replace('"', "").replace(',', "").replace(':', "")
        purl = urllib.parse.unquote(ukey)
        result["parse"] = 0
        result["playUrl"] = ''
        result["url"] =purl
        result["header"] = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"}
        return result

    config = {
        "player": {},
        "filter": {}
    }
    header = {}

    def isVideoFormat(self, url):
        pass

    def manualVideoCheck(self):
        pass

    def localProxy(self, param):
        action = {
            'url': '',
            'header': '',
            'param': '',
            'type': 'string',
            'after': ''
        }
        return [200, "video/MP2T", action, ""]


code:
#coding=utf-8
#!/usr/bin/python
import sys
sys.path.append('..')
from base.spider import Spider
import json
import time
import base64

class Spider(Spider):  # 元类 默认的元类 type
	def getName(self):
		return "哔哩"
	def init(self,extend=""):
		print("============{0}============".format(extend))
		pass
	def isVideoFormat(self,url):
		pass
	def manualVideoCheck(self):
		pass
	def homeContent(self,filter):
		result = {}
		cateManual = {
			"Zard": "Zard",
			"玩具汽车": "玩具汽车",
			"儿童": "儿童",
			"幼儿": "幼儿",
			"儿童玩具": "儿童玩具",
			"昆虫": "昆虫",
			"动物世界": "动物世界",
			"纪录片": "纪录片",
			"相声小品": "相声小品",
			"搞笑": "搞笑",
			"假窗-白噪音": "窗+白噪音",
			"演唱会": "演唱会"
		}
		classes = []
		for k in cateManual:
			classes.append({
				'type_name':k,
				'type_id':cateManual[k]
			})
		result['class'] = classes
		if(filter):
			result['filters'] = self.config['filter']
		return result
	def homeVideoContent(self):
		result = {
			'list':[]
		}
		return result
	cookies = ''
	def getCookie(self):
		rsp = self.fetch("https://www.bilibili.com/")
		self.cookies = rsp.cookies
		return rsp.cookies
	def categoryContent(self,tid,pg,filter,extend):
		result = {}
		url = 'https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword={0}&duration=4&page={1}'.format(tid,pg)
		if len(self.cookies) <= 0:
			self.getCookie()
		rsp = self.fetch(url,cookies=self.cookies)
		content = rsp.text
		jo = json.loads(content)
		if jo['code'] != 0:
			rspRetry = self.fetch(url,cookies=self.getCookie())
			content = rspRetry.text
		jo = json.loads(content)
		videos = []
		vodList = jo['data']['result']
		for vod in vodList:
			aid = str(vod['aid']).strip()
			title = vod['title'].strip().replace("","").replace("","")
			img = 'https:' + vod['pic'].strip()
			remark = str(vod['duration']).strip()
			videos.append({
				"vod_id":aid,
				"vod_name":title,
				"vod_pic":img,
				"vod_remarks":remark
			})
		result['list'] = videos
		result['page'] = pg
		result['pagecount'] = 9999
		result['limit'] = 90
		result['total'] = 999999
		return result
	def cleanSpace(self,str):
		return str.replace('\n','').replace('\t','').replace('\r','').replace(' ','')
	def detailContent(self,array):
		aid = array[0]
		url = "https://api.bilibili.com/x/web-interface/view?aid={0}".format(aid)

		rsp = self.fetch(url,headers=self.header)
		jRoot = json.loads(rsp.text)
		jo = jRoot['data']
		title = jo['title'].replace("","").replace("","")
		pic = jo['pic']
		desc = jo['desc']
		typeName = jo['tname']
		vod = {
			"vod_id":aid,
			"vod_name":title,
			"vod_pic":pic,
			"type_name":typeName,
			"vod_year":"",
			"vod_area":"",
			"vod_remarks":"",
			"vod_actor":"",
			"vod_director":"",
			"vod_content":desc
		}
		ja = jo['pages']
		playUrl = ''
		for tmpJo in ja:
			cid = tmpJo['cid']
			part = tmpJo['part']
			playUrl = playUrl + '{0}${1}_{2}#'.format(part,aid,cid)

		vod['vod_play_from'] = 'B站'
		vod['vod_play_url'] = playUrl

		result = {
			'list':[
				vod
			]
		}
		return result
	def searchContent(self,key,quick):
		result = {
			'list':[]
		}
		return result
	def playerContent(self,flag,id,vipFlags):
		# https://www.555dianying.cc/vodplay/static/js/playerconfig.js
		result = {}

		ids = id.split("_")
		url = 'https://api.bilibili.com:443/x/player/playurl?avid={0}&cid=%20%20{1}&qn=112'.format(ids[0],ids[1])
		rsp = self.fetch(url)
		jRoot = json.loads(rsp.text)
		jo = jRoot['data']
		ja = jo['durl']

		maxSize = -1
		position = -1
		for i in range(len(ja)):
			tmpJo = ja[i]
			if maxSize < int(tmpJo['size']):
				maxSize = int(tmpJo['size'])
				position = i

		url = ''
		if len(ja) > 0:
			if position == -1:
				position = 0
			url = ja[position]['url']

		result["parse"] = 0
		result["playUrl"] = ''
		result["url"] = url
		result["header"] = {
			"Referer":"https://www.bilibili.com",
			"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
		}
		result["contentType"] = 'video/x-flv'
		return result

	config = {
		"player": {},
		"filter": {}
	}
	header = {}

	def localProxy(self,param):
		return [200, "video/MP2T", action, ""]