Bye
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
name: Spider Jar Gen CI
|
||||||
|
|
||||||
|
on: workflow_dispatch
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: set up JDK 11
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '11'
|
||||||
|
distribution: 'adopt'
|
||||||
|
cache: gradle
|
||||||
|
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./buildAndGenJar.bat ec
|
||||||
|
|
||||||
|
- name: Update spider jar
|
||||||
|
uses: EndBug/add-and-commit@v7
|
||||||
|
with:
|
||||||
|
default_author: github_actions
|
||||||
|
message: 'update spider jar'
|
||||||
|
add: "['./jar/custom_spider.jar', './jar/custom_spider.jar.md5']"
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
|
/app/proguardMapping.txt
|
||||||
|
/LTDecodeSpace
|
||||||
|
/adb.exe
|
||||||
|
/LTDecodeNew3.exe
|
||||||
Generated
+3
@@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
Generated
+1
@@ -0,0 +1 @@
|
|||||||
|
CatVodSpider
|
||||||
Generated
+123
@@ -0,0 +1,123 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="XML">
|
||||||
|
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
<arrangement>
|
||||||
|
<rules>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>style</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
</rules>
|
||||||
|
</arrangement>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
Generated
+5
@@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="11" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+20
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="testRunner" value="GRADLE" />
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="JDK" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+55
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RemoteRepositoriesConfiguration">
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Maven Central repository" />
|
||||||
|
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="jboss.community" />
|
||||||
|
<option name="name" value="JBoss Community repository" />
|
||||||
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="MavenRepo" />
|
||||||
|
<option name="name" value="MavenRepo" />
|
||||||
|
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="BintrayJCenter" />
|
||||||
|
<option name="name" value="BintrayJCenter" />
|
||||||
|
<option name="url" value="https://jcenter.bintray.com/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="Google" />
|
||||||
|
<option name="name" value="Google" />
|
||||||
|
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven3" />
|
||||||
|
<option name="name" value="maven3" />
|
||||||
|
<option name="url" value="https://maven.aliyun.com/repository/public" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven" />
|
||||||
|
<option name="name" value="maven" />
|
||||||
|
<option name="url" value="https://maven.aliyun.com/repository/google" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven2" />
|
||||||
|
<option name="name" value="maven2" />
|
||||||
|
<option name="url" value="https://maven.aliyun.com/repository/central" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven5" />
|
||||||
|
<option name="name" value="maven5" />
|
||||||
|
<option name="url" value="https://jitpack.io" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven4" />
|
||||||
|
<option name="name" value="maven4" />
|
||||||
|
<option name="url" value="https://maven.aliyun.com/repository/gradle-plugin" />
|
||||||
|
</remote-repository>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
# 猫影视TV客户端爬虫自定义接口工程
|
||||||
|
|
||||||
|
```
|
||||||
|
思维没有边界 一切皆有可能
|
||||||
|
```
|
||||||
|
:rocket:[**TG交流群**](https://t.me/catvodtv_offical)
|
||||||
|
|
||||||
|
本工程最终食用需配合 猫影视TV新版(一下简称为软件) **v2.0.0**及以上版本。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 欢迎各路大佬踊跃提PR,分享爬虫代码。
|
||||||
|
|
||||||
|
### 这里是用户分享的爬虫代码打包的共享包,可以配合自定义配置,直接食用 [custom_spider.jar](/jar/)
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
----
|
||||||
|
本工程是一个完整的AndroidStudio工程,请你用AS打开编辑。
|
||||||
|
|
||||||
|
工程调试完毕后要需要导出生成jar文件配合软件使用,执行根目录下的 `buildAndGenJar.bat` 会在`jar`目录生成一个名为`custom_spider.jar`的jar文件,这个文件就是我们最终要是用的代码包。
|
||||||
|
|
||||||
|
### 代码包食用方式
|
||||||
|
----
|
||||||
|
本地加载:将`custom_spider.jar`放入设备sd卡根目录即可。 **注意,如需本地加载,请手动赋予App存储空间读写权限,App默认不申请存储空间读写权限**
|
||||||
|
|
||||||
|
远程加载:将`custom_spider.jar`上传到你的网络空间,获取对应的文件下载地址,在软件自定义配置的json文件中加入下面格式的键值对。
|
||||||
|
```json
|
||||||
|
"spider": "http://xxx.xxx.xxx/custom_spider.jar"
|
||||||
|
```
|
||||||
|
支持jar文件本地缓存(需v2.0.5及以上版本)
|
||||||
|
```json
|
||||||
|
"spider": "http://xxx.xxx.xxx/custom_spider.jar;md5;jar文件md5"
|
||||||
|
// 例如
|
||||||
|
"spider": "https://github.com/catvod/CatVodTVSpider/blob/master/jar/custom_spider.jar?raw=true;md5;c6ed6bc8285f0aca90e7cb3abf7f9caa",
|
||||||
|
```
|
||||||
|
|
||||||
|
### 如何在自定义配置中调用我们代码包中的Spider
|
||||||
|
----
|
||||||
|
同样在自定义json中加入相应的播放源即可,**type=3, api对应你代码工程中自定义的爬虫类名(api必须是`csp_`开头),例如实例工程中的`Aidi`**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"key": "csp_Aidi",
|
||||||
|
"name": "爱迪",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Aidi",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
**Json解析扩展(需v2.0.2及以上版本)**
|
||||||
|
|
||||||
|
通过jar包可以实现json解析并发、轮询等相关功能,**参与并发和轮询的json解析地址,默认为解析地址列表中的所有json解析(即type=1)**。
|
||||||
|
|
||||||
|
在自定义json中的`parse`里加入相应的解析配置(type=2)即可启用。**调用扩展类的名称配置在`parse`的`url`字段里,例如扩展类`JsonParallel`的json配置`url`字段值为`Parallel`**。如下:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Json并发",
|
||||||
|
"type": 2,
|
||||||
|
"url": "Parallel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Json轮询",
|
||||||
|
"type": 2,
|
||||||
|
"url": "Sequence"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**XPath规则套娃(需v2.0.4及以上版本)**
|
||||||
|
套娃规则祥见[XPath.md](/XPath.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**M浏览器中APP影视规则支持**(2022.01.17 by 小黄瓜)支持筛选。
|
||||||
|
|
||||||
|
因<a href="https://inmemory.coding.net/p/InMemory/d/MBrowser/git/raw/master/AppFile/APP%E5%BD%B1%E8%A7%86%E5%88%97%E8%A1%A8" target="_blank">App影视接口收集地址</a>停止维护,代码里不再读取相关json地址。
|
||||||
|
|
||||||
|
如果你有对应影视Api地址请在ext字段中直接配置Api地址。
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>配置代码示例 点我展开</summary>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"key":"csp_appysv2_追剧达人", "name":"追剧推荐(M2)", "type":3,"api":"csp_AppYsV2", "searchable":1, "quickSearch":0, "filterable":1, "ext":"https://vipmv.co/xgapp.php/v1/"},
|
||||||
|
{"key":"csp_appysv2_天空影视", "name":"天空推荐(M2)", "type":3,"api":"csp_AppYsV2", "searchable":1, "quickSearch":0, "filterable":1, "ext":"https://tkys.tv/xgapp.php/v1/"},
|
||||||
|
{"key":"csp_appys_HG影视", "name":"HG影视(M)", "type":3, "api":"csp_AppYs", "searchable":1, "quickSearch":0, "filterable":1, "ext":"http://hgyx.vip/api.php/v1.vod"},
|
||||||
|
{"key":"csp_appys_瑞丰资源", "name":"瑞丰资源(M)", "type":3, "api":"csp_AppYs", "searchable":1, "quickSearch":0, "filterable":1, "ext":"https://ts.yjhan.com:4433/ruifenglb_api.php/v1.vod"},
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**部分内置代理接口使用(需v2.0.9及以上版本)**
|
||||||
|
|
||||||
|
入口 [Proxy](/app/src/main/java/com/github/catvod/spider/Proxy.java)
|
||||||
|
|
||||||
|
图片代理,示例参考[Nekk](/app/src/main/java/com/github/catvod/spider/Nekk.java#L449)
|
||||||
|
|
||||||
|
直播配置重定向代理,示例参考[TxtSubscribe](/app/src/main/java/com/github/catvod/live/TxtSubscribe.java)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**推送功能扩展(需v2.1.0.Beta6及以上版本)**
|
||||||
|
|
||||||
|
入口 [PushAgent](/app/src/main/java/com/github/catvod/spider/PushAgent.java)
|
||||||
|
|
||||||
|
需要在配置文件中,加入key为`push_agent`的站点,数据返回格式和普通爬虫一致
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"key": "push_agent",
|
||||||
|
"name": "推送",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_PushAgent",
|
||||||
|
"searchable": 0,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## 基础类
|
||||||
|
----
|
||||||
|
|
||||||
|
> com.github.catvod.crawler.Spider 爬虫基类
|
||||||
|
|
||||||
|
> com.github.catvod.crawler.SpiderReq 用于发起网络请求 获取网络数据,请使用[OkHttpUtil](/app/src/main/java/com/github/catvod/utils/okhttp/OkHttpUtil.java)类,SpiderReq后续将删除
|
||||||
|
|
||||||
|
> com.github.catvod.crawler.SpiderReqResult 网络请求结果
|
||||||
|
|
||||||
|
> com.github.catvod.crawler.SpiderUrl 用于定义一个网络请求
|
||||||
|
|
||||||
|
|
||||||
|
## 示例
|
||||||
|
----
|
||||||
|
|
||||||
|
请查看 仓库中的爱迪影视 相关实现 ,调试可参考 `com.github.catvod.demo.MainActivity` ,直接调用对应爬虫相关接口
|
||||||
|
|
||||||
|
> com.github.catvod.spider.Aidi
|
||||||
|
|
||||||
|
## 注意事项!!
|
||||||
|
----
|
||||||
|
1. 除了`com.github.catvod.spider`包以外的代码,最终都会被软件本身内置的代码代替掉,所以,建议你不要修改除`com.github.catvod.spider`包以外的代码。
|
||||||
|
|
||||||
|
2. 不要在`Spider`中使用`Gson`
|
||||||
|
|
||||||
|
3. 待补充
|
||||||
|
|
||||||
|
## 爬虫类返回的相关Json字符串格式说明
|
||||||
|
----
|
||||||
|
### homeContent
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"class": [{ // 分类
|
||||||
|
"type_id": "dianying", // 分类id
|
||||||
|
"type_name": "电影" // 分类名
|
||||||
|
}, {
|
||||||
|
"type_id": "lianxuju",
|
||||||
|
"type_name": "连续剧"
|
||||||
|
}],
|
||||||
|
"filters": { // 筛选
|
||||||
|
"dianying": [{ // 分类id 就是上面class中的分类id
|
||||||
|
"key": "0", // 筛选key
|
||||||
|
"name": "分类", // 筛选名称
|
||||||
|
"value": [{ // 筛选选项
|
||||||
|
"n": "全部", // 选项展示的名称
|
||||||
|
"v": "dianying" // 选项最终在url中的展现
|
||||||
|
}, {
|
||||||
|
"n": "动作片",
|
||||||
|
"v": "dongzuopian"
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"lianxuju": [{
|
||||||
|
"key": 0,
|
||||||
|
"name": "分类",
|
||||||
|
"value": [{
|
||||||
|
"n": "全部",
|
||||||
|
"v": "lianxuju"
|
||||||
|
}, {
|
||||||
|
"n": "国产剧",
|
||||||
|
"v": "guochanju"
|
||||||
|
}, {
|
||||||
|
"n": "港台剧",
|
||||||
|
"v": "gangtaiju"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"list": [{ // 首页最近更新视频列表
|
||||||
|
"vod_id": "1901", // 视频id
|
||||||
|
"vod_name": "判决", // 视频名
|
||||||
|
"vod_pic": "https:\/\/pic.imgdb.cn\/item\/614631e62ab3f51d918e9201.jpg", // 展示图片
|
||||||
|
"vod_remarks": "6.8" // 视频信息 展示在 视频名上方
|
||||||
|
}, {
|
||||||
|
"vod_id": "1908",
|
||||||
|
"vod_name": "移山的父亲",
|
||||||
|
"vod_pic": "https:\/\/pic.imgdb.cn\/item\/6146fab82ab3f51d91c01af1.jpg",
|
||||||
|
"vod_remarks": "6.7"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### categoryContent
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"page": 1, // 当前页
|
||||||
|
"pagecount": 2, // 总共几页
|
||||||
|
"limit": 60, // 每页几条数据
|
||||||
|
"total": 120, // 总共多少调数据
|
||||||
|
"list": [{ // 视频列表 下面的视频结构 同上面homeContent中的
|
||||||
|
"vod_id": "1897",
|
||||||
|
"vod_name": "北区侦缉队",
|
||||||
|
"vod_pic": "https:\/\/pic.imgdb.cn\/item\/6145d4b22ab3f51d91bd98b6.jpg",
|
||||||
|
"vod_remarks": "7.3"
|
||||||
|
}, {
|
||||||
|
"vod_id": "1879",
|
||||||
|
"vod_name": "浪客剑心 最终章 人诛篇",
|
||||||
|
"vod_pic": "https:\/\/pic.imgdb.cn\/item\/60e3f37e5132923bf82ef95e.jpg",
|
||||||
|
"vod_remarks": "8.0"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### detailContent
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"list": [{
|
||||||
|
"vod_id": "1902",
|
||||||
|
"vod_name": "海岸村恰恰恰",
|
||||||
|
"vod_pic": "https:\/\/pic.imgdb.cn\/item\/61463fd12ab3f51d91a0f44d.jpg",
|
||||||
|
"type_name": "剧情",
|
||||||
|
"vod_year": "2021",
|
||||||
|
"vod_area": "韩国",
|
||||||
|
"vod_remarks": "更新至第8集",
|
||||||
|
"vod_actor": "申敏儿,金宣虎,李相二,孔敏晶,徐尚沅,禹美华,朴艺荣,李世亨,边胜泰,金贤佑,金英玉",
|
||||||
|
"vod_director": "柳济元",
|
||||||
|
"vod_content": "海岸村恰恰恰剧情: 韩剧海岸村恰恰恰 갯마을 차차차改编自2004年的电影《我的百事通男友洪班长》,海岸村恰恰恰 갯마을 차차차讲述来自大都市的牙医(申敏儿 饰)到充满人情味的海岸村开设牙医诊所,那里住着一位各方面都",
|
||||||
|
// 播放源 多个用$$$分隔
|
||||||
|
"vod_play_from": "qiepian$$$yun3edu",
|
||||||
|
// 播放列表 注意分隔符 分别是 多个源$$$分隔,源中的剧集用#分隔,剧集的名称和地址用$分隔
|
||||||
|
"vod_play_url": "第1集$1902-1-1#第2集$1902-1-2#第3集$1902-1-3#第4集$1902-1-4#第5集$1902-1-5#第6集$1902-1-6#第7集$1902-1-7#第8集$1902-1-8$$$第1集$1902-2-1#第2集$1902-2-2#第3集$1902-2-3#第4集$1902-2-4#第5集$1902-2-5#第6集$1902-2-6#第7集$1902-2-7#第8集$1902-2-8"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### searchContent
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"list": [{ // 视频列表 下面的视频结构 同上面homeContent中的
|
||||||
|
"vod_id": "1606",
|
||||||
|
"vod_name": "陪你一起长大",
|
||||||
|
"vod_pic": "https:\/\/img.aidi.tv\/img\/upload\/vod\/20210417-1\/e27d4eb86f7cde375171dd324b2c19ae.jpg",
|
||||||
|
"vod_remarks": "更新至第37集"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
### XPath规则套娃(需v2.0.4及以上版本)
|
||||||
|
----
|
||||||
|
套娃依赖自定义爬虫jar,同样需要在自定义json中加入相应的配置,**type=3, api为csp_XPath**,套娃相关规则配置在`ext`字段中,注意:ext字段值**只能是字符串**
|
||||||
|
|
||||||
|
为控制配置文件容量,同时支持在ext字段中直接配置规则和拉取规则的网址。 2021.10.21 by 小黄瓜
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_94sm",
|
||||||
|
"name": "94神马(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/94sm.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_jpys",
|
||||||
|
"name": "极品影视(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/jpys.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_age",
|
||||||
|
"name": "AGE动漫(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/agefans.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_jpyszl",
|
||||||
|
"name": "极品直链(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathMac",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/jpys.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_cjt",
|
||||||
|
"name": "CJT影视(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathMac",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/cjtys.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_tvci",
|
||||||
|
"name": "大师兄(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/tvci.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_saohuotv",
|
||||||
|
"name": "骚火电影(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/saohuotv2.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_dm84",
|
||||||
|
"name": "动漫巴士(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/dm84.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_egg",
|
||||||
|
"name": "蛋蛋影院(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathEgg",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/egg.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_555",
|
||||||
|
"name": "555电影(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/555.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_4kyu",
|
||||||
|
"name": "一只鱼4K(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/4kyu.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_miniku",
|
||||||
|
"name": "Miniku(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/miniku.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_pianba",
|
||||||
|
"name": "Pianba(XPath)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/pianba.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_xpath_Ole",
|
||||||
|
"name": "Ole(EXO)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPath",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/olevod.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "唐人街",
|
||||||
|
"name": "唐人街(P)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathMacFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Renjie.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Gimy",
|
||||||
|
"name": "Gimy(P)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathMacFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Gimy.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Jumi",
|
||||||
|
"name": "Jumi(P)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathMacFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Jumi.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Djx",
|
||||||
|
"name": "瓜皮TV(P)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Djx.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "独播库",
|
||||||
|
"name": "独播库(P)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathMacFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Duboku.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Sky4k",
|
||||||
|
"name": "Sky4k(P)[en]",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathMacFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Sky4k.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Nfuxs",
|
||||||
|
"name": "南府(P)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Nfuxs.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Aixixi",
|
||||||
|
"name": "爱西西(P)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_XPathFilter",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": "https://cdn.jsdelivr.net/gh/catvod/CatVodTVSpider@master/xpath/Aixixi.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 套娃规则
|
||||||
|
|
||||||
|
demo配置写的比较细,不一定所有字段都要有,具体还是自己多试一试
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ua": "",
|
||||||
|
// 首页地址 用于获取 分类和首页推荐
|
||||||
|
"homeUrl": "http://www.9rmb.com",
|
||||||
|
// 分类节点
|
||||||
|
"cateNode": "//ul[contains(@class,'navbar-nav')]/li/a[contains(@href, '.html') and not(contains(@href, '6'))]",
|
||||||
|
// 分类名
|
||||||
|
"cateName": "/text()",
|
||||||
|
// 分类id
|
||||||
|
"cateId": "/@href",
|
||||||
|
// 分类id二次处理正则
|
||||||
|
"cateIdR": "/type/(\\d+).html",
|
||||||
|
// 手动设置分类,如果手动设置了分类则不使用上面的分类xpath获取分类 例如 "cateManual": {"电影": "1", "电视剧": "2"},
|
||||||
|
"cateManual": {},
|
||||||
|
// 首页推荐视频的节点
|
||||||
|
"homeVodNode": "//div[@class='col-md-12 movie-item-out']//a[not(contains(@href, '6'))]/parent::*/parent::*/parent::*/div[contains(@class, 'movie-item-out') and position()<10]/div[@class='movie-item']/a",
|
||||||
|
// 首页推荐视频的名称
|
||||||
|
"homeVodName": "/@title",
|
||||||
|
// 二次处理正则
|
||||||
|
"homeVodNameR": "",
|
||||||
|
// 首页推荐视频的id
|
||||||
|
"homeVodId": "/@href",
|
||||||
|
// 二次处理正则
|
||||||
|
"homeVodIdR": "/show/(\\w+).html",
|
||||||
|
// 首页推荐视频的图片
|
||||||
|
"homeVodImg": "/img/@src",
|
||||||
|
// 二次处理正则
|
||||||
|
"homeVodImgR": "",
|
||||||
|
// 首页推荐视频的简介
|
||||||
|
"homeVodMark": "/button/text()",
|
||||||
|
// 二次处理正则
|
||||||
|
"homeVodMarkR": "",
|
||||||
|
// 分类页地址 {cateId} 分类id {catePg} 当前页
|
||||||
|
"cateUrl": "http://www.9rmb.com/type/{cateId}/{catePg}.html",
|
||||||
|
// 同上面的homeVod字段 分类列表中的视频信息
|
||||||
|
"cateVodNode": "//div[@class='movie-item']/a",
|
||||||
|
"cateVodName": "/@title",
|
||||||
|
"cateVodId": "/@href",
|
||||||
|
"cateVodIdR": "/show/(\\w+).html",
|
||||||
|
"cateVodImg": "/img/@src",
|
||||||
|
"cateVodMark": "/button/text()",
|
||||||
|
// 详情页地址 用于获取详情页信息 及 播放列表和地址
|
||||||
|
"dtUrl": "http://www.9rmb.com/show/{vid}.html",
|
||||||
|
// 详情节点
|
||||||
|
"dtNode": "//div[@class='container-fluid']",
|
||||||
|
// 视频名
|
||||||
|
"dtName": "//div[@class='col-md-9']//div[@class='col-md-4']//img/@alt",
|
||||||
|
"dtNameR": "",
|
||||||
|
// 视频图片
|
||||||
|
"dtImg": "//div[@class='col-md-9']//div[@class='col-md-4']//img/@src",
|
||||||
|
"dtImgR": "",
|
||||||
|
// 视频分类
|
||||||
|
"dtCate": "//div[@class='col-md-8']//span[@class='info-label' and contains(text(), '类型')]/parent::*/following-sibling::*/text()",
|
||||||
|
"dtCateR": "",
|
||||||
|
// 视频年份
|
||||||
|
"dtYear": "//div[@class='col-md-8']//span[@class='info-label' and contains(text(), '日期')]/parent::*/following-sibling::*/text()",
|
||||||
|
"dtYearR": "",
|
||||||
|
// 视频地区
|
||||||
|
"dtArea": "//div[@class='col-md-8']//span[@class='info-label' and contains(text(), '国家')]/parent::*/following-sibling::*/text()",
|
||||||
|
"dtAreaR": "",
|
||||||
|
// 视频状态
|
||||||
|
"dtMark": "//div[@class='col-md-8']//span[@class='info-label' and contains(text(), '状态')]/parent::*/following-sibling::*/text()",
|
||||||
|
"dtMarkR": "",
|
||||||
|
// 主演
|
||||||
|
"dtActor": "//div[@class='col-md-8']//span[@class='info-label' and contains(text(), '主演')]/parent::*/following-sibling::*/text()",
|
||||||
|
"dtActorR": "",
|
||||||
|
// 导演
|
||||||
|
"dtDirector": "//div[@class='col-md-8']//span[@class='info-label' and contains(text(), '导演')]/parent::*/following-sibling::*/text()",
|
||||||
|
"dtDirectorR": "",
|
||||||
|
// 视频简介
|
||||||
|
"dtDesc": "//p[@class='summary']/text()",
|
||||||
|
"dtDescR": "",
|
||||||
|
// 播放源节点
|
||||||
|
"dtFromNode": "//div[contains(@class,'resource-list')]/div[@class='panel-heading']/strong",
|
||||||
|
// 播放源名称
|
||||||
|
"dtFromName": "/text()",
|
||||||
|
// 二次处理正则
|
||||||
|
"dtFromNameR": "\\S+\\.(\\S+) \\(",
|
||||||
|
// 播放列表节点
|
||||||
|
"dtUrlNode": "//div[contains(@class,'resource-list')]/ul[@class='dslist-group']",
|
||||||
|
// 播放地址节点
|
||||||
|
"dtUrlSubNode": "/li/a",
|
||||||
|
// 播放地址
|
||||||
|
"dtUrlId": "@href",
|
||||||
|
// 二次处理正则
|
||||||
|
"dtUrlIdR": "/play/(\\S+).html",
|
||||||
|
// 剧集名称
|
||||||
|
"dtUrlName": "/text()",
|
||||||
|
// 二次处理正则
|
||||||
|
"dtUrlNameR": "",
|
||||||
|
// 播放页面的地址 {playUrl} 对应上面 dtUrlId 获取到的地址
|
||||||
|
"playUrl": "http://www.9rmb.com/play/{playUrl}.html",
|
||||||
|
// 解析webview的user-agent
|
||||||
|
"playUa": "",
|
||||||
|
// 搜索地址
|
||||||
|
"searchUrl": "http://www.9rmb.com/search?wd={wd}",
|
||||||
|
// 同上面的homeVod字段 搜索结果中的视频信息, 这里有对苹果cms suggest搜索接口的特殊支持,参考示例中的极品影视
|
||||||
|
"scVodNode": "//div[@class='movie-item']/a",
|
||||||
|
"scVodName": "/@title",
|
||||||
|
"scVodId": "/@href",
|
||||||
|
"scVodIdR": "/show/(\\w+).html",
|
||||||
|
"scVodImg": "/img/@src",
|
||||||
|
"scVodMark": "/button/text()"
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
plugins {
|
||||||
|
id 'com.android.application'
|
||||||
|
id 'ru.cleverpumpkin.proguard-dictionaries-generator'
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion rootProject.compileSdkVersion
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.github.catvod.demo"
|
||||||
|
minSdkVersion rootProject.miniSdkVersion
|
||||||
|
targetSdkVersion rootProject.targetSdkVersion
|
||||||
|
versionCode rootProject.appVersionCode
|
||||||
|
versionName rootProject.appVersionName
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled true
|
||||||
|
proguardFiles 'proguard-rules.pro'
|
||||||
|
proguardDictionaries {
|
||||||
|
dictionaryNames = [
|
||||||
|
"build/class-dictionary",
|
||||||
|
"build/package-dictionary",
|
||||||
|
"build/obfuscation-dictionary"
|
||||||
|
]
|
||||||
|
minLineLength 1
|
||||||
|
maxLineLength 3
|
||||||
|
linesCountInDictionary 100000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "org.jsoup:jsoup:$jsoup_version"
|
||||||
|
implementation "cn.wanghaomiao:JsoupXpath:$jsoupxpath_version"
|
||||||
|
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
||||||
|
implementation ("com.github.liujingxing.rxhttp:rxhttp:$rxhttp_version") {
|
||||||
|
exclude group: "com.squareup.okhttp3"
|
||||||
|
}
|
||||||
|
annotationProcessor "com.github.liujingxing.rxhttp:rxhttp-compiler:$rxhttp_version"
|
||||||
|
}
|
||||||
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
-optimizationpasses 0
|
||||||
|
-dontusemixedcaseclassnames
|
||||||
|
-dontskipnonpubliclibraryclasses
|
||||||
|
-dontskipnonpubliclibraryclassmembers
|
||||||
|
-dontpreverify
|
||||||
|
-dontoptimize
|
||||||
|
-verbose
|
||||||
|
-printmapping proguardMapping.txt
|
||||||
|
-optimizations !code/simplification/cast,!field/*,!class/merging/*
|
||||||
|
-keepattributes *Annotation*,InnerClasses
|
||||||
|
-keepattributes EnclosingMethod, InnerClasses
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes LineNumberTable
|
||||||
|
-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-obfuscationdictionary build/obfuscation-dictionary.txt
|
||||||
|
-classobfuscationdictionary build/class-dictionary.txt
|
||||||
|
-packageobfuscationdictionary build/package-dictionary.txt
|
||||||
|
|
||||||
|
-flattenpackagehierarchy com.github.catvod.spider.merge
|
||||||
|
-repackageclasses com.github.catvod.spider.merge
|
||||||
|
|
||||||
|
-dontwarn okio.**
|
||||||
|
-keep class okio.**{*;}
|
||||||
|
-dontwarn com.squareup.okhttp.**
|
||||||
|
-dontwarn okhttp3.**
|
||||||
|
-keep class okhttp3.**{*;}
|
||||||
|
-dontwarn com.google.**
|
||||||
|
-keep class com.google.**{*;}
|
||||||
|
-dontwarn com.android.**
|
||||||
|
-keep class com.android.**{*;}
|
||||||
|
-dontwarn rxhttp.**
|
||||||
|
-keep class rxhttp.**{*;}
|
||||||
|
-dontwarn kotlin.**
|
||||||
|
-keep class kotlin.**{*;}
|
||||||
|
-dontwarn kotlinx.**
|
||||||
|
-keep class kotlinx.**{*;}
|
||||||
|
|
||||||
|
-keep class com.github.catvod.crawler.* { *; }
|
||||||
|
-keep class com.github.catvod.spider.* { public <methods>; }
|
||||||
|
-keep class com.github.catvod.parser.* { public <methods>; }
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.github.catvod.demo">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@drawable/app_icon"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
<activity android:name="com.github.catvod.demo.MainActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.github.catvod.crawler;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class Spider {
|
||||||
|
|
||||||
|
public static JSONObject empty = new JSONObject();
|
||||||
|
|
||||||
|
public void init(Context context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首页数据内容
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首页最近更新数据 如果上面的homeContent中不包含首页最近更新视频的数据 可以使用这个接口返回
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String homeVideoContent() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类数据
|
||||||
|
*
|
||||||
|
* @param tid
|
||||||
|
* @param pg
|
||||||
|
* @param filter
|
||||||
|
* @param extend
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情数据
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索数据内容
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param quick
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放信息
|
||||||
|
*
|
||||||
|
* @param flag
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* webview解析时使用 可自定义判断当前加载的 url 是否是视频
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isVideoFormat(String url) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否手动检测webview中加载的url
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean manualVideoCheck() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.github.catvod.crawler;
|
||||||
|
|
||||||
|
public class SpiderDebug {
|
||||||
|
public static void log(Throwable th) {
|
||||||
|
try {
|
||||||
|
android.util.Log.d("SpiderLog", th.getMessage(), th);
|
||||||
|
} catch (Throwable th1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void log(String msg) {
|
||||||
|
try {
|
||||||
|
android.util.Log.d("SpiderLog", msg);
|
||||||
|
} catch (Throwable th1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
package com.github.catvod.crawler;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import rxhttp.RxHttpPlugins;
|
||||||
|
import rxhttp.wrapper.param.RxHttp;
|
||||||
|
import rxhttp.wrapper.parse.Parser;
|
||||||
|
|
||||||
|
public class SpiderReq {
|
||||||
|
|
||||||
|
private static final String defaultTag = "sp_req_default";
|
||||||
|
|
||||||
|
private static OkHttpClient defaultClient = initDefaultClient();
|
||||||
|
|
||||||
|
private static OkHttpClient initDefaultClient() {
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
builder.readTimeout(15, TimeUnit.SECONDS);
|
||||||
|
builder.writeTimeout(15, TimeUnit.SECONDS);
|
||||||
|
builder.connectTimeout(15, TimeUnit.SECONDS);
|
||||||
|
builder.retryOnConnectionFailure(true);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消请求
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
*/
|
||||||
|
public static void cancel(String tag) {
|
||||||
|
try {
|
||||||
|
RxHttpPlugins.cancelAll(tag);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get
|
||||||
|
*
|
||||||
|
* @param su
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult get(SpiderUrl su) {
|
||||||
|
return get(defaultClient, su.url, defaultTag, su.headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whit custom tag
|
||||||
|
*
|
||||||
|
* @param su
|
||||||
|
* @param tag
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult get(SpiderUrl su, String tag) {
|
||||||
|
return get(defaultClient, su.url, tag, su.headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get with custom http client
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param su
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult get(OkHttpClient client, SpiderUrl su) {
|
||||||
|
return get(client, su.url, defaultTag, su.headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get with custom http client & tag
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param su
|
||||||
|
* @param tag
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static SpiderReqResult get(OkHttpClient client, SpiderUrl su, String tag) {
|
||||||
|
return get(client, su.url, tag, su.headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get base
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param url
|
||||||
|
* @param tag
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult get(OkHttpClient client, String url, String tag, HashMap<String, String> headers) {
|
||||||
|
try {
|
||||||
|
return RxHttp.get(url)
|
||||||
|
.setOkClient(client)
|
||||||
|
.tag(tag)
|
||||||
|
.addAllHeader(headers)
|
||||||
|
.execute(new Parser<SpiderReqResult>() {
|
||||||
|
@Override
|
||||||
|
public SpiderReqResult onParse(@NotNull Response response) throws IOException {
|
||||||
|
String content = "";
|
||||||
|
if (response.body() != null) {
|
||||||
|
content = response.body().string();
|
||||||
|
}
|
||||||
|
Map<String, List<String>> headers = response.headers().toMultimap();
|
||||||
|
return new SpiderReqResult(headers, content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return SpiderReqResult.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult header(String url, HashMap<String, String> headers) {
|
||||||
|
return header(defaultClient, url, defaultTag, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param url
|
||||||
|
* @param tag
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult header(OkHttpClient client, String url, String tag, HashMap<String, String> headers) {
|
||||||
|
try {
|
||||||
|
return RxHttp.head(url)
|
||||||
|
.setOkClient(client)
|
||||||
|
.tag(tag)
|
||||||
|
.addAllHeader(headers)
|
||||||
|
.execute(new Parser<SpiderReqResult>() {
|
||||||
|
@Override
|
||||||
|
public SpiderReqResult onParse(@NotNull Response response) throws IOException {
|
||||||
|
Map<String, List<String>> headers = response.headers().toMultimap();
|
||||||
|
return new SpiderReqResult(headers, "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return SpiderReqResult.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post Body
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param body
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult postBody(String url, RequestBody body, HashMap<String, String> headers) {
|
||||||
|
return postBody(defaultClient, url, body, defaultTag, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post Body
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param url
|
||||||
|
* @param body
|
||||||
|
* @param tag
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult postBody(OkHttpClient client, String url, RequestBody body, String tag, HashMap<String, String> headers) {
|
||||||
|
try {
|
||||||
|
return RxHttp.postBody(url)
|
||||||
|
.setOkClient(client)
|
||||||
|
.setBody(body)
|
||||||
|
.tag(tag)
|
||||||
|
.addAllHeader(headers)
|
||||||
|
.execute(new Parser<SpiderReqResult>() {
|
||||||
|
@Override
|
||||||
|
public SpiderReqResult onParse(@NotNull Response response) throws IOException {
|
||||||
|
String content = "";
|
||||||
|
if (response.body() != null) {
|
||||||
|
content = response.body().string();
|
||||||
|
}
|
||||||
|
Map<String, List<String>> headers = response.headers().toMultimap();
|
||||||
|
return new SpiderReqResult(headers, content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return SpiderReqResult.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post Form
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param form
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult postForm(String url, HashMap<String, String> form, HashMap<String, String> headers) {
|
||||||
|
return postForm(defaultClient, url, form, defaultTag, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post Form
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param url
|
||||||
|
* @param form
|
||||||
|
* @param tag
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult postForm(OkHttpClient client, String url, HashMap<String, String> form, String tag, HashMap<String, String> headers) {
|
||||||
|
try {
|
||||||
|
return RxHttp.postForm(url)
|
||||||
|
.setOkClient(client)
|
||||||
|
.addAll(form)
|
||||||
|
.tag(tag)
|
||||||
|
.addAllHeader(headers)
|
||||||
|
.execute(new Parser<SpiderReqResult>() {
|
||||||
|
@Override
|
||||||
|
public SpiderReqResult onParse(@NotNull Response response) throws IOException {
|
||||||
|
String content = "";
|
||||||
|
if (response.body() != null) {
|
||||||
|
content = response.body().string();
|
||||||
|
}
|
||||||
|
Map<String, List<String>> headers = response.headers().toMultimap();
|
||||||
|
return new SpiderReqResult(headers, content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return SpiderReqResult.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post Json
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param json
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult postJson(String url, HashMap<String, String> json, HashMap<String, String> headers) {
|
||||||
|
return postJson(defaultClient, url, json, defaultTag, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post Json
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param url
|
||||||
|
* @param json
|
||||||
|
* @param tag
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SpiderReqResult postJson(OkHttpClient client, String url, HashMap<String, String> json, String tag, HashMap<String, String> headers) {
|
||||||
|
try {
|
||||||
|
return RxHttp.postJson(url)
|
||||||
|
.setOkClient(client)
|
||||||
|
.addAll(json)
|
||||||
|
.tag(tag)
|
||||||
|
.addAllHeader(headers)
|
||||||
|
.execute(new Parser<SpiderReqResult>() {
|
||||||
|
@Override
|
||||||
|
public SpiderReqResult onParse(@NotNull Response response) throws IOException {
|
||||||
|
String content = "";
|
||||||
|
if (response.body() != null) {
|
||||||
|
content = response.body().string();
|
||||||
|
}
|
||||||
|
Map<String, List<String>> headers = response.headers().toMultimap();
|
||||||
|
return new SpiderReqResult(headers, content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return SpiderReqResult.empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.github.catvod.crawler;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SpiderReqResult {
|
||||||
|
SpiderReqResult(Map<String, List<String>> headers, String content) {
|
||||||
|
this.headers = headers;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpiderReqResult empty = new SpiderReqResult(new HashMap<String, List<String>>(), "");
|
||||||
|
|
||||||
|
public Map<String, List<String>> headers;
|
||||||
|
public String content;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.github.catvod.crawler;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class SpiderUrl {
|
||||||
|
|
||||||
|
public static SpiderUrl Empty = new SpiderUrl();
|
||||||
|
|
||||||
|
public String url = "";
|
||||||
|
public HashMap<String, String> headers = new HashMap<>();
|
||||||
|
|
||||||
|
public SpiderUrl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpiderUrl(String url, HashMap<String, String> headers) {
|
||||||
|
this.url = url;
|
||||||
|
if (headers != null)
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.github.catvod.demo;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package com.github.catvod.live;
|
||||||
|
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
public class TxtSubscribe {
|
||||||
|
|
||||||
|
public static void subscribe(LinkedHashMap<String, LinkedHashMap<String, ArrayList<String>>> allLives, String url, HashMap<String, String> headers) {
|
||||||
|
if (url.contains(".bmp")) {
|
||||||
|
String content = OkHttpUtil.string(url, headers);
|
||||||
|
String[] split = content.split("\\*\\*");
|
||||||
|
String a = new String(Base64.decode(split[1], Base64.DEFAULT));
|
||||||
|
parse(allLives, a);
|
||||||
|
} else {
|
||||||
|
String content = OkHttpUtil.string(url, headers);
|
||||||
|
parse(allLives, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void parse(LinkedHashMap<String, LinkedHashMap<String, ArrayList<String>>> allLives, String txt) {
|
||||||
|
try {
|
||||||
|
BufferedReader br = new BufferedReader(new StringReader(txt));
|
||||||
|
String line = br.readLine();
|
||||||
|
LinkedHashMap<String, ArrayList<String>> noGroup = new LinkedHashMap<>();
|
||||||
|
LinkedHashMap<String, ArrayList<String>> groupLives = noGroup;
|
||||||
|
while (line != null) {
|
||||||
|
if (line.trim().isEmpty()) {
|
||||||
|
line = br.readLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] lineInfo = line.split(",");
|
||||||
|
if (lineInfo.length < 2) {
|
||||||
|
line = br.readLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.contains("#genre#")) {
|
||||||
|
String group = lineInfo[0].trim();
|
||||||
|
if (!allLives.containsKey(group)) {
|
||||||
|
groupLives = new LinkedHashMap<>();
|
||||||
|
allLives.put(group, groupLives);
|
||||||
|
} else {
|
||||||
|
groupLives = allLives.get(group);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String title = lineInfo[0].trim();
|
||||||
|
String[] urlMix = lineInfo[1].trim().split("#");
|
||||||
|
for (int j = 0; j < urlMix.length; j++) {
|
||||||
|
String url = urlMix[j].trim();
|
||||||
|
if (url.isEmpty())
|
||||||
|
continue;
|
||||||
|
if (url.startsWith("http") || url.startsWith("rtsp") || url.startsWith("rtmp")) {
|
||||||
|
ArrayList<String> urls = null;
|
||||||
|
if (!groupLives.containsKey(title)) {
|
||||||
|
urls = new ArrayList<>();
|
||||||
|
groupLives.put(title, urls);
|
||||||
|
} else {
|
||||||
|
urls = groupLives.get(title);
|
||||||
|
}
|
||||||
|
if (!urls.contains(url))
|
||||||
|
urls.add(url);
|
||||||
|
} else {
|
||||||
|
// SpiderDebug.log("Skip " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = br.readLine();
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
if (!noGroup.isEmpty()) {
|
||||||
|
allLives.put("未分组", noGroup);
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String live2Json(LinkedHashMap<String, LinkedHashMap<String, ArrayList<String>>> lives) {
|
||||||
|
JSONArray groups = new JSONArray();
|
||||||
|
Iterator<String> groupKeys = lives.keySet().iterator();
|
||||||
|
while (groupKeys.hasNext()) {
|
||||||
|
String group = groupKeys.next();
|
||||||
|
JSONArray channels = new JSONArray();
|
||||||
|
LinkedHashMap<String, ArrayList<String>> allChannel = lives.get(group);
|
||||||
|
if (allChannel.isEmpty())
|
||||||
|
continue;
|
||||||
|
Iterator<String> channelKeys = allChannel.keySet().iterator();
|
||||||
|
while (channelKeys.hasNext()) {
|
||||||
|
String channel = channelKeys.next();
|
||||||
|
ArrayList<String> allUrls = allChannel.get(channel);
|
||||||
|
if (allUrls.isEmpty())
|
||||||
|
continue;
|
||||||
|
JSONArray urls = new JSONArray();
|
||||||
|
for (int i = 0; i < allUrls.size(); i++) {
|
||||||
|
urls.put(allUrls.get(i));
|
||||||
|
}
|
||||||
|
JSONObject newChannel = new JSONObject();
|
||||||
|
try {
|
||||||
|
newChannel.put("name", channel);
|
||||||
|
newChannel.put("urls", urls);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
channels.put(newChannel);
|
||||||
|
}
|
||||||
|
JSONObject newGroup = new JSONObject();
|
||||||
|
try {
|
||||||
|
newGroup.put("group", group);
|
||||||
|
newGroup.put("channels", channels);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
groups.put(newGroup);
|
||||||
|
}
|
||||||
|
return groups.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] load(String ext) {
|
||||||
|
try {
|
||||||
|
LinkedHashMap<String, LinkedHashMap<String, ArrayList<String>>> allLives = new LinkedHashMap<>();
|
||||||
|
TxtSubscribe.subscribe(allLives, ext, null);
|
||||||
|
String json = TxtSubscribe.live2Json(allLives);
|
||||||
|
Object[] result = new Object[3];
|
||||||
|
result[0] = 200;
|
||||||
|
result[1] = "text/plain; charset=utf-8";
|
||||||
|
ByteArrayInputStream baos = new ByteArrayInputStream(json.getBytes("UTF-8"));
|
||||||
|
result[2] = baos;
|
||||||
|
return result;
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package com.github.catvod.parser;
|
||||||
|
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class JsonBasic {
|
||||||
|
public static JSONObject parse(LinkedHashMap<String, String> jx, String url) {
|
||||||
|
try {
|
||||||
|
SpiderDebug.log("Load Json Parse Basic...");
|
||||||
|
if (jx.size() > 0) {
|
||||||
|
Set<String> jxNames = jx.keySet();
|
||||||
|
for (String jxName : jxNames) {
|
||||||
|
String parseUrl = jx.get(jxName);
|
||||||
|
HashMap<String, String> reqHeaders = getReqHeader(parseUrl);
|
||||||
|
try {
|
||||||
|
String realUrl = reqHeaders.get("url");
|
||||||
|
reqHeaders.remove("url");
|
||||||
|
SpiderDebug.log(realUrl + url);
|
||||||
|
String json = OkHttpUtil.string(realUrl + url, reqHeaders);
|
||||||
|
JSONObject taskResult = Misc.jsonParse(url, json);
|
||||||
|
if (taskResult == null)
|
||||||
|
continue;
|
||||||
|
taskResult.put("jxFrom", jxName);
|
||||||
|
SpiderDebug.log(taskResult.toString());
|
||||||
|
return taskResult;
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, String> getReqHeader(String url) {
|
||||||
|
HashMap<String, String> reqHeaders = new HashMap<>();
|
||||||
|
reqHeaders.put("url", url);
|
||||||
|
if (url.contains("cat_ext")) {
|
||||||
|
try {
|
||||||
|
int start = url.indexOf("cat_ext=");
|
||||||
|
int end = url.indexOf("&", start);
|
||||||
|
String ext = url.substring(start + 8, end);
|
||||||
|
ext = new String(Base64.decode(ext, Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP));
|
||||||
|
String newUrl = url.substring(0, start) + url.substring(end + 1);
|
||||||
|
JSONObject jsonObject = new JSONObject(ext);
|
||||||
|
if (jsonObject.has("header")) {
|
||||||
|
JSONObject headerJson = jsonObject.optJSONObject("header");
|
||||||
|
Iterator<String> keys = headerJson.keys();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String key = keys.next();
|
||||||
|
reqHeaders.put(key, headerJson.optString(key, ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reqHeaders.put("url", newUrl);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reqHeaders;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package com.github.catvod.parser;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletionService;
|
||||||
|
import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 并发解析,直到获得第一个结果
|
||||||
|
* <p>
|
||||||
|
* 默认解析超时时间为15秒,如果需要请自定义SpiderReq的HttpClient
|
||||||
|
* <p>
|
||||||
|
* Author: CatVod
|
||||||
|
*/
|
||||||
|
public class JsonParallel {
|
||||||
|
private static final String ParseOKTag = "p_json_parse";
|
||||||
|
|
||||||
|
public static JSONObject parse(LinkedHashMap<String, String> jx, String url) {
|
||||||
|
try {
|
||||||
|
if (jx.size() > 0) {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(3);
|
||||||
|
CompletionService<JSONObject> completionService = new ExecutorCompletionService<JSONObject>(executorService);
|
||||||
|
List<Future<JSONObject>> futures = new ArrayList<>();
|
||||||
|
Set<String> jxNames = jx.keySet();
|
||||||
|
for (String jxName : jxNames) {
|
||||||
|
String parseUrl = jx.get(jxName);
|
||||||
|
futures.add(completionService.submit(new Callable<JSONObject>() {
|
||||||
|
@Override
|
||||||
|
public JSONObject call() throws Exception {
|
||||||
|
try {
|
||||||
|
HashMap<String, String> reqHeaders = JsonBasic.getReqHeader(parseUrl);
|
||||||
|
String realUrl = reqHeaders.get("url");
|
||||||
|
reqHeaders.remove("url");
|
||||||
|
SpiderDebug.log(realUrl + url);
|
||||||
|
String json = OkHttpUtil.string(realUrl + url, ParseOKTag, reqHeaders);
|
||||||
|
JSONObject taskResult = Misc.jsonParse(url, json);
|
||||||
|
taskResult.put("jxFrom", jxName);
|
||||||
|
SpiderDebug.log(taskResult.toString());
|
||||||
|
return taskResult;
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
JSONObject pTaskResult = null;
|
||||||
|
for (int i = 0; i < futures.size(); ++i) {
|
||||||
|
Future<JSONObject> completed = completionService.take();
|
||||||
|
try {
|
||||||
|
pTaskResult = completed.get();
|
||||||
|
if (pTaskResult != null) {
|
||||||
|
OkHttpUtil.cancel(ParseOKTag);
|
||||||
|
for (int j = 0; j < futures.size(); j++) {
|
||||||
|
try {
|
||||||
|
futures.get(j).cancel(true);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
futures.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
executorService.shutdownNow();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
if (pTaskResult != null)
|
||||||
|
return pTaskResult;
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.github.catvod.parser;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 依次解析,失败尝试下一个
|
||||||
|
* <p>
|
||||||
|
* 默认解析超时时间为15秒,如果需要请自定义SpiderReq的HttpClient
|
||||||
|
* <p>
|
||||||
|
* Author: CatVod
|
||||||
|
*/
|
||||||
|
public class JsonSequence {
|
||||||
|
public static JSONObject parse(LinkedHashMap<String, String> jx, String url) {
|
||||||
|
try {
|
||||||
|
if (jx.size() > 0) {
|
||||||
|
Set<String> jxNames = jx.keySet();
|
||||||
|
for (String jxName : jxNames) {
|
||||||
|
String parseUrl = jx.get(jxName);
|
||||||
|
try {
|
||||||
|
HashMap<String, String> reqHeaders = JsonBasic.getReqHeader(parseUrl);
|
||||||
|
String realUrl = reqHeaders.get("url");
|
||||||
|
reqHeaders.remove("url");
|
||||||
|
SpiderDebug.log(realUrl + url);
|
||||||
|
String json = OkHttpUtil.string(realUrl + url, reqHeaders);
|
||||||
|
JSONObject taskResult = Misc.jsonParse(url, json);
|
||||||
|
if (taskResult == null)
|
||||||
|
continue;
|
||||||
|
taskResult.put("jxFrom", jxName);
|
||||||
|
return taskResult;
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
package com.github.catvod.parser;
|
||||||
|
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
public class MixDemo {
|
||||||
|
|
||||||
|
/*
|
||||||
|
"parses": [
|
||||||
|
{
|
||||||
|
"name": "聚合",
|
||||||
|
"type": 3,
|
||||||
|
"url": "Demo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "解析",
|
||||||
|
"type": 1,
|
||||||
|
"url": "https://192.168.10.88/jx.php?url=",
|
||||||
|
"ext": {
|
||||||
|
"flag": [
|
||||||
|
"qq",
|
||||||
|
"iqiyi",
|
||||||
|
"qiyi",
|
||||||
|
"爱奇艺",
|
||||||
|
"腾讯",
|
||||||
|
"letv",
|
||||||
|
"sohu",
|
||||||
|
"tudou",
|
||||||
|
"pptv",
|
||||||
|
"mgtv",
|
||||||
|
"wasu",
|
||||||
|
"bilibili"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static HashMap<String, ArrayList<String>> flagWebJx = new HashMap<>();
|
||||||
|
|
||||||
|
static HashMap<String, ArrayList<String>> configs = null;
|
||||||
|
|
||||||
|
public static JSONObject parse(LinkedHashMap<String, HashMap<String, String>> jx, String nameMe, String flag, String url) {
|
||||||
|
try {
|
||||||
|
if (configs == null) {
|
||||||
|
configs = new HashMap<>();
|
||||||
|
Iterator<String> keys = jx.keySet().iterator();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String key = keys.next();
|
||||||
|
HashMap<String, String> parseBean = jx.get(key);
|
||||||
|
String type = parseBean.get("type");
|
||||||
|
if (type.equals("1") || type.equals("0")) {
|
||||||
|
try {
|
||||||
|
JSONArray flags = new JSONObject(parseBean.get("ext")).getJSONArray("flag");
|
||||||
|
for (int j = 0; j < flags.length(); j++) {
|
||||||
|
String flagKey = flags.getString(j);
|
||||||
|
ArrayList<String> flagJx = configs.get(flagKey);
|
||||||
|
if (flagJx == null) {
|
||||||
|
flagJx = new ArrayList<>();
|
||||||
|
configs.put(flagKey, flagJx);
|
||||||
|
}
|
||||||
|
flagJx.add(key);
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 通过上面的配置获得解析列表
|
||||||
|
LinkedHashMap<String, String> jsonJx = new LinkedHashMap<>();
|
||||||
|
ArrayList<String> webJx = new ArrayList<>();
|
||||||
|
ArrayList<String> flagJx = configs.get(flag);
|
||||||
|
if (flagJx != null && !flagJx.isEmpty()) {
|
||||||
|
for (int i = 0; i < flagJx.size(); i++) {
|
||||||
|
String key = flagJx.get(i);
|
||||||
|
HashMap<String, String> parseBean = jx.get(key);
|
||||||
|
String type = parseBean.get("type");
|
||||||
|
if (type.equals("1")) {
|
||||||
|
jsonJx.put(key, mixUrl(parseBean.get("url"), parseBean.get("ext")));
|
||||||
|
} else if (type.equals("0")) {
|
||||||
|
webJx.add(parseBean.get("url"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Iterator<String> keys = jx.keySet().iterator();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String key = keys.next();
|
||||||
|
HashMap<String, String> parseBean = jx.get(key);
|
||||||
|
String type = parseBean.get("type");
|
||||||
|
if (type.equals("1")) {
|
||||||
|
jsonJx.put(key, mixUrl(parseBean.get("url"), parseBean.get("ext")));
|
||||||
|
} else if (type.equals("0")) {
|
||||||
|
webJx.add(parseBean.get("url"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!webJx.isEmpty()) {
|
||||||
|
flagWebJx.put(flag, webJx);
|
||||||
|
}
|
||||||
|
// 优先使用json并发解析
|
||||||
|
JSONObject jsonResult = JsonParallel.parse(jsonJx, url);
|
||||||
|
if (jsonResult != null && jsonResult.has("url")) {
|
||||||
|
return jsonResult;
|
||||||
|
}
|
||||||
|
// json解析没有得到结果 用webview解析
|
||||||
|
if (!webJx.isEmpty()) {
|
||||||
|
JSONObject webResult = new JSONObject();
|
||||||
|
webResult.put("url", "proxy://do=MixDemo&flag=" + flag + "&url=" + Base64.encodeToString(url.getBytes(), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP));
|
||||||
|
webResult.put("parse", 1);
|
||||||
|
return webResult;
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String mixUrl(String url, String ext) {
|
||||||
|
if (ext.trim().length() > 0) {
|
||||||
|
int idx = url.indexOf("?");
|
||||||
|
if (idx > 0) {
|
||||||
|
return url.substring(0, idx + 1) + "cat_ext=" + Base64.encodeToString(ext.getBytes(), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP) + "&" + url.substring(idx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] loadHtml(String flag, String url) {
|
||||||
|
try {
|
||||||
|
url = new String(Base64.decode(url, Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");
|
||||||
|
String html = "\n" +
|
||||||
|
"<!doctype html>\n" +
|
||||||
|
"<html>\n" +
|
||||||
|
"<head>\n" +
|
||||||
|
"<title>解析</title>\n" +
|
||||||
|
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n" +
|
||||||
|
"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE10\" />\n" +
|
||||||
|
"<meta name=\"renderer\" content=\"webkit|ie-comp|ie-stand\">\n" +
|
||||||
|
"<meta name=\"viewport\" content=\"width=device-width\">\n" +
|
||||||
|
"</head>\n" +
|
||||||
|
"<body>\n" +
|
||||||
|
"<script>\n" +
|
||||||
|
"var apiArray=[#jxs#];\n" +
|
||||||
|
"var urlPs=\"#url#\";\n" +
|
||||||
|
"var iframeHtml=\"\";\n" +
|
||||||
|
"for(var i=0;i<apiArray.length;i++){\n" +
|
||||||
|
"var URL=apiArray[i]+urlPs;\n" +
|
||||||
|
"iframeHtml=iframeHtml+\"<iframe sandbox='allow-scripts allow-same-origin allow-forms' frameborder='0' allowfullscreen='true' webkitallowfullscreen='true' mozallowfullscreen='true' src=\"+URL+\"></iframe>\";\n" +
|
||||||
|
"}\n" +
|
||||||
|
"document.write(iframeHtml);\n" +
|
||||||
|
"</script>\n" +
|
||||||
|
"</body>\n" +
|
||||||
|
"</html>";
|
||||||
|
|
||||||
|
StringBuilder jxs = new StringBuilder();
|
||||||
|
if (flagWebJx.containsKey(flag)) {
|
||||||
|
ArrayList<String> jxUrls = flagWebJx.get(flag);
|
||||||
|
for (int i = 0; i < jxUrls.size(); i++) {
|
||||||
|
jxs.append("\"");
|
||||||
|
jxs.append(jxUrls.get(i));
|
||||||
|
jxs.append("\"");
|
||||||
|
if (i < jxUrls.size() - 1) {
|
||||||
|
jxs.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html = html.replace("#url#", url).replace("#jxs#", jxs.toString());
|
||||||
|
Object[] result = new Object[3];
|
||||||
|
result[0] = 200;
|
||||||
|
result[1] = "text/html; charset=\"UTF-8\"";
|
||||||
|
ByteArrayInputStream baos = new ByteArrayInputStream(html.toString().getBytes("UTF-8"));
|
||||||
|
result[2] = baos;
|
||||||
|
return result;
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
|
||||||
|
public class AliPS extends Spider {
|
||||||
|
private PushAgent pushAgent;
|
||||||
|
private static String b = "https://www.alipansou.com";
|
||||||
|
private static Pattern a = Pattern.compile("(https:\\/\\/www.aliyundrive.com\\/s\\/[^\\\"]+)");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
pushAgent = new PushAgent();
|
||||||
|
pushAgent.init(context, extend);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> list) {
|
||||||
|
try {
|
||||||
|
Pattern pattern = a;
|
||||||
|
if (pattern.matcher(list.get(0)).find()) {
|
||||||
|
return pushAgent.detailContent(list);
|
||||||
|
}
|
||||||
|
Matcher matcher = pattern.matcher(OkHttpUtil.string("https://www.alipansou.com" + list.get(0), null));
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
list.set(0, matcher.group(1).replaceAll("\\\\",""));
|
||||||
|
return pushAgent.detailContent(list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
return pushAgent.playerContent(str, str2, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String, String> sHeaders() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean z) {
|
||||||
|
try {
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
hashMap.put("7", "文件夹");
|
||||||
|
hashMap.put("1", "视频");
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
Iterator entries = hashMap.entrySet().iterator();
|
||||||
|
while (entries.hasNext()) {
|
||||||
|
Map.Entry entry = (Map.Entry) entries.next();
|
||||||
|
String str2 = (String) entry.getValue();
|
||||||
|
String sb2 = b + "/search?k=" + URLEncoder.encode(key) + "&t=" + (String) entry.getKey();
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(sb2, sHeaders()));
|
||||||
|
Elements Data = doc.select("van-row a");
|
||||||
|
for (int i = 0; i < Data.size(); i++) {
|
||||||
|
Element next = Data.get(i);
|
||||||
|
String filename = next.select("template div").text();
|
||||||
|
Pattern pattern = Pattern.compile("(时间: \\S+)");
|
||||||
|
Matcher matcher = pattern.matcher(filename);
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String remark = matcher.group(1);
|
||||||
|
if (filename.contains(key)) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
String id = next.attr("href");
|
||||||
|
String title = "[" + str2 + "]" + filename;
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("remark", remark);
|
||||||
|
v.put("vod_pic", "https://inews.gtimg.com/newsapp_bt/0/13263837859/1000");
|
||||||
|
jSONArray.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("list", jSONArray);
|
||||||
|
return jSONObject2.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,1124 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* M浏览器中的App影视
|
||||||
|
* <p>
|
||||||
|
* Author: 群友 不负此生
|
||||||
|
*/
|
||||||
|
public class AppYs extends Spider {
|
||||||
|
|
||||||
|
private String extString = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
this.extString = extend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
String url = getCateUrl(extString);
|
||||||
|
JSONArray jsonArray = null;
|
||||||
|
if (!url.isEmpty()) {
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("data");
|
||||||
|
}
|
||||||
|
} else { // 通过filter列表读分类
|
||||||
|
String filterStr = getFilterTypes(url, null);
|
||||||
|
String[] classes = filterStr.split("\n")[0].split("\\+");
|
||||||
|
jsonArray = new JSONArray();
|
||||||
|
for (int i = 1; i < classes.length; i++) {
|
||||||
|
String[] kv = classes[i].trim().split("=");
|
||||||
|
if (kv.length < 2)
|
||||||
|
continue;
|
||||||
|
JSONObject newCls = new JSONObject();
|
||||||
|
newCls.put("type_name", kv[0].trim());
|
||||||
|
newCls.put("type_id", kv[1].trim());
|
||||||
|
jsonArray.put(newCls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
if (jsonArray != null) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject jObj = jsonArray.getJSONObject(i);
|
||||||
|
String typeName = jObj.getString("type_name");
|
||||||
|
if (isBan(typeName))
|
||||||
|
continue;
|
||||||
|
String typeId = jObj.getString("type_id");
|
||||||
|
JSONObject newCls = new JSONObject();
|
||||||
|
newCls.put("type_id", typeId);
|
||||||
|
newCls.put("type_name", typeName);
|
||||||
|
JSONObject typeExtend = jObj.optJSONObject("type_extend");
|
||||||
|
if (filter) {
|
||||||
|
String filterStr = getFilterTypes(url, typeExtend);
|
||||||
|
String[] filters = filterStr.split("\n");
|
||||||
|
JSONArray filterArr = new JSONArray();
|
||||||
|
for (int k = url.isEmpty() ? 1 : 0; k < filters.length; k++) {
|
||||||
|
String l = filters[k].trim();
|
||||||
|
if (l.isEmpty())
|
||||||
|
continue;
|
||||||
|
String[] oneLine = l.split("\\+");
|
||||||
|
String type = oneLine[0].trim();
|
||||||
|
String typeN = type;
|
||||||
|
if (type.contains("筛选")) {
|
||||||
|
type = type.replace("筛选", "");
|
||||||
|
if (type.equals("class"))
|
||||||
|
typeN = "类型";
|
||||||
|
else if (type.equals("area"))
|
||||||
|
typeN = "地区";
|
||||||
|
else if (type.equals("lang"))
|
||||||
|
typeN = "语言";
|
||||||
|
else if (type.equals("year"))
|
||||||
|
typeN = "年份";
|
||||||
|
}
|
||||||
|
JSONObject jOne = new JSONObject();
|
||||||
|
jOne.put("key", type);
|
||||||
|
jOne.put("name", typeN);
|
||||||
|
JSONArray valueArr = new JSONArray();
|
||||||
|
for (int j = 1; j < oneLine.length; j++) {
|
||||||
|
JSONObject kvo = new JSONObject();
|
||||||
|
String kv = oneLine[j].trim();
|
||||||
|
int sp = kv.indexOf("=");
|
||||||
|
if (sp == -1) {
|
||||||
|
if (isBan(kv))
|
||||||
|
continue;
|
||||||
|
kvo.put("n", kv);
|
||||||
|
kvo.put("v", kv);
|
||||||
|
} else {
|
||||||
|
String n = kv.substring(0, sp);
|
||||||
|
if (isBan(n))
|
||||||
|
continue;
|
||||||
|
kvo.put("n", n.trim());
|
||||||
|
kvo.put("v", kv.substring(sp + 1).trim());
|
||||||
|
}
|
||||||
|
valueArr.put(kvo);
|
||||||
|
}
|
||||||
|
jOne.put("value", valueArr);
|
||||||
|
filterArr.put(jOne);
|
||||||
|
}
|
||||||
|
if (!result.has("filters")) {
|
||||||
|
result.put("filters", new JSONObject());
|
||||||
|
}
|
||||||
|
result.getJSONObject("filters").put(typeId, filterArr);
|
||||||
|
}
|
||||||
|
classes.put(newCls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
String apiUrl = extString;
|
||||||
|
String url = getRecommendUrl(apiUrl);
|
||||||
|
boolean isTV = false;
|
||||||
|
if (url.isEmpty()) {
|
||||||
|
url = getCateFilterUrlPrefix(apiUrl) + "movie&page=1&area=&type=&start=";
|
||||||
|
isTV = true;
|
||||||
|
}
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (isTV) {
|
||||||
|
JSONArray jsonArray = obj.getJSONArray("data");
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("nextlink"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("state"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ArrayList<JSONArray> arrays = new ArrayList<>();
|
||||||
|
findJsonArray(obj, "vlist", arrays);
|
||||||
|
if (arrays.isEmpty()) {
|
||||||
|
findJsonArray(obj, "vod_list", arrays);
|
||||||
|
}
|
||||||
|
List<String> ids = new ArrayList<>();
|
||||||
|
for (JSONArray jsonArray : arrays) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
String vid = vObj.getString("vod_id");
|
||||||
|
if (ids.contains(vid))
|
||||||
|
continue;
|
||||||
|
ids.add(vid);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vid);
|
||||||
|
v.put("vod_name", vObj.getString("vod_name"));
|
||||||
|
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String apiUrl = extString;
|
||||||
|
String url = getCateFilterUrlPrefix(apiUrl) + tid + getCateFilterUrlSuffix(apiUrl);
|
||||||
|
url = url.replace("#PN#", pg);
|
||||||
|
url = url.replace("筛选class", (extend != null && extend.containsKey("class")) ? extend.get("class") : "");
|
||||||
|
url = url.replace("筛选area", (extend != null && extend.containsKey("area")) ? extend.get("area") : "");
|
||||||
|
url = url.replace("筛选lang", (extend != null && extend.containsKey("lang")) ? extend.get("lang") : "");
|
||||||
|
url = url.replace("筛选year", (extend != null && extend.containsKey("year")) ? extend.get("year") : "");
|
||||||
|
url = url.replace("排序", (extend != null && extend.containsKey("排序")) ? extend.get("排序") : "");
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
int totalPg = Integer.MAX_VALUE;
|
||||||
|
try {
|
||||||
|
if (obj.has("totalpage") && obj.get("totalpage") instanceof Integer) {
|
||||||
|
totalPg = obj.getInt("totalpage");
|
||||||
|
} else if (obj.has("pagecount") && obj.get("pagecount") instanceof Integer) {
|
||||||
|
totalPg = obj.getInt("pagecount");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject &&
|
||||||
|
(obj.getJSONObject("data").has("total") && obj.getJSONObject("data").get("total") instanceof Integer &&
|
||||||
|
obj.getJSONObject("data").has("limit") && obj.getJSONObject("data").get("limit") instanceof Integer)) {
|
||||||
|
int limit = obj.getJSONObject("data").getInt("limit");
|
||||||
|
int total = obj.getJSONObject("data").getInt("total");
|
||||||
|
totalPg = total % limit == 0 ? (total / limit) : (total / limit + 1);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray jsonArray = null;
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("data");
|
||||||
|
}
|
||||||
|
if (jsonArray != null) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
if (vObj.has("vod_id")) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("vod_id"));
|
||||||
|
v.put("vod_name", vObj.getString("vod_name"));
|
||||||
|
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||||
|
videos.put(v);
|
||||||
|
} else {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("nextlink"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("state"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("page", pg);
|
||||||
|
result.put("pagecount", totalPg);
|
||||||
|
result.put("limit", 90);
|
||||||
|
result.put("total", Integer.MAX_VALUE);
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
String apiUrl = extString;
|
||||||
|
String url = getPlayUrlPrefix(apiUrl) + ids.get(0);
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vod = new JSONObject();
|
||||||
|
genPlayList(apiUrl, obj, json, vod, ids.get(0));
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vod);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String apiUrl = extString;
|
||||||
|
String url = getSearchUrl(apiUrl, URLEncoder.encode(key));
|
||||||
|
String json = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
JSONArray jsonArray = null;
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("data");
|
||||||
|
}
|
||||||
|
if (jsonArray != null) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
if (vObj.has("vod_id")) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("vod_id"));
|
||||||
|
v.put("vod_name", vObj.getString("vod_name"));
|
||||||
|
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||||
|
videos.put(v);
|
||||||
|
} else {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("nextlink"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("state"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
String apiUrl = extString;
|
||||||
|
String parseUrl = getParseUrl(apiUrl, flag);
|
||||||
|
String playerUrl = getPlayerUrl(apiUrl, parseUrl, id);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
getFinalVideo(playerUrl, result);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findJsonArray(JSONObject obj, String match, ArrayList<JSONArray> result) {
|
||||||
|
Iterator<String> keys = obj.keys();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String k = keys.next();
|
||||||
|
try {
|
||||||
|
Object o = obj.get(k);
|
||||||
|
if (k.equals(match) && o instanceof JSONArray)
|
||||||
|
result.add((JSONArray) o);
|
||||||
|
if (o instanceof JSONObject) {
|
||||||
|
findJsonArray((JSONObject) o, match, result);
|
||||||
|
} else if (o instanceof JSONArray) {
|
||||||
|
JSONArray array = (JSONArray) o;
|
||||||
|
for (int i = 0; i < array.length(); i++) {
|
||||||
|
findJsonArray(array.getJSONObject(i), match, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String jsonArr2Str(JSONArray array) {
|
||||||
|
try {
|
||||||
|
ArrayList<String> strings = new ArrayList<>();
|
||||||
|
for (int i = 0; i < array.length(); i++) {
|
||||||
|
strings.add(array.getString(i));
|
||||||
|
}
|
||||||
|
return TextUtils.join(",", strings);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HashMap<String, String> fakeVips = null;
|
||||||
|
private static final Object lock = new Object();
|
||||||
|
|
||||||
|
private static String stopVipFlag(String flag) {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (fakeVips == null) {
|
||||||
|
fakeVips = new HashMap<>();
|
||||||
|
fakeVips.put("youku", "优酷M");
|
||||||
|
fakeVips.put("qq", "腾讯M");
|
||||||
|
fakeVips.put("iqiyi", "爱奇艺M");
|
||||||
|
fakeVips.put("qiyi", "奇艺M");
|
||||||
|
fakeVips.put("letv", "乐视M");
|
||||||
|
fakeVips.put("sohu", "搜狐M");
|
||||||
|
fakeVips.put("tudou", "土豆M");
|
||||||
|
fakeVips.put("pptv", "PPTVM");
|
||||||
|
fakeVips.put("mgtv", "芒果TVM");
|
||||||
|
fakeVips.put("wasu", "华数M");
|
||||||
|
fakeVips.put("bilibili", "哔哩M");
|
||||||
|
}
|
||||||
|
if (fakeVips.containsKey(flag)) {
|
||||||
|
return fakeVips.get(flag);
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<String, String> getHeaders(String URL) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", UA(URL));
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBan(String key) {
|
||||||
|
return key.equals("伦理") || key.equals("情色") || key.equals("福利");
|
||||||
|
}
|
||||||
|
|
||||||
|
// M 扩展方法
|
||||||
|
|
||||||
|
// ######重组搜索
|
||||||
|
private String getSearchUrl(String URL, String KEY) {
|
||||||
|
if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun.com")) {
|
||||||
|
return URL + "/list?wd=" + KEY + "&page=";
|
||||||
|
} else {
|
||||||
|
return URL + "?wd=" + KEY + "&page=";
|
||||||
|
}
|
||||||
|
} else if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return URL + "search?text=" + KEY + "&pg=";
|
||||||
|
} else if (urlPattern1.matcher(URL).find()) {
|
||||||
|
if (URL.contains("esellauto")
|
||||||
|
|| URL.contains("1.14.63.101")
|
||||||
|
|| URL.contains("zjys")
|
||||||
|
|| URL.contains("dcd")
|
||||||
|
|| URL.contains("lxue")
|
||||||
|
|| URL.contains("weetai.cn")
|
||||||
|
|| URL.contains("haokanju1")
|
||||||
|
|| URL.contains("fit:8")
|
||||||
|
|| URL.contains("zjj.life")
|
||||||
|
|| URL.contains("love9989")
|
||||||
|
|| URL.contains("8d8q")
|
||||||
|
|| URL.contains("lk.pxun")
|
||||||
|
|| URL.contains("hgyx")
|
||||||
|
|| URL.contains("521x5")
|
||||||
|
|| URL.contains("lxyyy")
|
||||||
|
|| URL.contains("0818tv")
|
||||||
|
|| URL.contains("diyoui")
|
||||||
|
|| URL.contains("diliktv")
|
||||||
|
|| URL.contains("ppzhu")
|
||||||
|
|| URL.contains("aitesucai")
|
||||||
|
|| URL.contains("zz.ci")
|
||||||
|
|| URL.contains("chxjon")
|
||||||
|
|| URL.contains("watchmi")
|
||||||
|
|| URL.contains("vipbp")
|
||||||
|
|| URL.contains("bhtv")
|
||||||
|
|| URL.contains("xfykl")) {
|
||||||
|
return URL + "?ac=list&" + "wd=" + KEY + "&page=";
|
||||||
|
} else {
|
||||||
|
return URL + "?ac=list&" + "zm=" + KEY + "&page=";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######UA
|
||||||
|
private static final Pattern urlPattern1 = Pattern.compile("api\\.php/.*?/vod");
|
||||||
|
private static final Pattern urlPattern2 = Pattern.compile("api\\.php/.+?\\.vod");
|
||||||
|
private static final Pattern parsePattern = Pattern.compile("/.+\\?.+=");
|
||||||
|
private static final Pattern parsePattern1 = Pattern.compile(".*(url|v|vid|php\\?id)=");
|
||||||
|
private static final Pattern parsePattern2 = Pattern.compile("https?://[^/]*");
|
||||||
|
private static final Pattern[] parseMatchForDotVod = new Pattern[]{
|
||||||
|
Pattern.compile("jx\\.+huimaojia\\.+com/player"),
|
||||||
|
Pattern.compile("py\\.+789pan\\.+cn/player/tm\\.php\\?url="),
|
||||||
|
Pattern.compile("ztys\\.+waruanzy\\.+com/player/\\?url="),
|
||||||
|
Pattern.compile("yingshi\\.+waruanzy\\.+com/789pan/\\?url="),
|
||||||
|
Pattern.compile("vip\\.+parwix\\.+com:4433/player/\\?url="),
|
||||||
|
Pattern.compile("api\\.+cxitco\\.+cn"),
|
||||||
|
Pattern.compile("/vip\\.+renrenmi.cc"),
|
||||||
|
Pattern.compile("yanbing\\.+parwix\\.+com:4433/player"),
|
||||||
|
Pattern.compile("json\\.+cantin\\.+cc/apijson\\.php"),
|
||||||
|
Pattern.compile("ffdm\\.+miaoletv\\.+com/\\?url="),
|
||||||
|
Pattern.compile("vip\\.+sylwl\\.+cn/api/\\?key="),
|
||||||
|
Pattern.compile("jx\\.+dikotv\\.+com/\\?url="),
|
||||||
|
Pattern.compile("zly\\.+xjqxz\\.+top/player/\\?url="),
|
||||||
|
Pattern.compile("5znn\\.+xyz/m3u8\\.+php"),
|
||||||
|
Pattern.compile("uid=1735&my="),
|
||||||
|
Pattern.compile("api\\.+xkvideo\\.+design/m3u8\\.+php\\?url="),
|
||||||
|
Pattern.compile("play\\.+szbodankyy\\.+com/xxoocnmb"),
|
||||||
|
Pattern.compile("vip\\.+fj6080\\.+xyz/player/\\?url="),
|
||||||
|
Pattern.compile("a\\.+dxzj88\\.+com/jiexi"),
|
||||||
|
Pattern.compile("host\\.+q-q\\.+wang/api"),
|
||||||
|
Pattern.compile("保佑")
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Pattern[] htmlVideoKeyMatch = new Pattern[]{
|
||||||
|
Pattern.compile("player=new"),
|
||||||
|
Pattern.compile("<div id=\"video\""),
|
||||||
|
Pattern.compile("<div id=\"[^\"]*?player\""),
|
||||||
|
Pattern.compile("//视频链接"),
|
||||||
|
Pattern.compile("HlsJsPlayer\\("),
|
||||||
|
Pattern.compile("<iframe[\\s\\S]*?src=\"[^\"]+?\""),
|
||||||
|
Pattern.compile("<video[\\s\\S]*?src=\"[^\"]+?\"")
|
||||||
|
};
|
||||||
|
|
||||||
|
private String UA(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp") || URL.contains("freekan")) {
|
||||||
|
return "Dart/2.14 (dart:io)";
|
||||||
|
} else if (URL.contains("zsb") || URL.contains("fkxs") || URL.contains("xays") || URL.contains("xcys") || URL.contains("szys") || URL.contains("dxys") || URL.contains("ytys") || URL.contains("qnys")) {
|
||||||
|
return "Dart/2.15 (dart:io)";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return "okhttp/4.1.0";
|
||||||
|
} else {
|
||||||
|
return "Dalvik/2.1.0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######POST
|
||||||
|
String post(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return "";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######cookie
|
||||||
|
String cookie(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return "";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######获取分类地址
|
||||||
|
String getCateUrl(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return URL + "nav?token=";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun.com")) {
|
||||||
|
return URL + "/list?type";
|
||||||
|
} else {
|
||||||
|
return URL + "/types";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######分类筛选前缀地址
|
||||||
|
String getCateFilterUrlPrefix(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
if (URL.contains("dijiaxia")) {
|
||||||
|
URL = "http://www.dijiaxia.com/api.php/app/";
|
||||||
|
return URL + "video?tid=";
|
||||||
|
} else {
|
||||||
|
return URL + "video?tid=";
|
||||||
|
}
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun")) {
|
||||||
|
return URL + "/list?type=";
|
||||||
|
} else {
|
||||||
|
return URL + "?type=";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return URL + "?ac=list&class=";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######分类筛选后缀地址
|
||||||
|
String getCateFilterUrlSuffix(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&limit=18&pg=#PN#";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&by=排序&limit=18&page=#PN#";
|
||||||
|
} else {
|
||||||
|
return "&page=#PN#&area=筛选area&type=筛选class&start=筛选year";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######筛选内容
|
||||||
|
String getFilterTypes(String URL, JSONObject typeExtend) {
|
||||||
|
String str = "";
|
||||||
|
if (typeExtend != null) {
|
||||||
|
Iterator<String> typeExtendKeys = typeExtend.keys();
|
||||||
|
while (typeExtendKeys.hasNext()) {
|
||||||
|
String key = typeExtendKeys.next();
|
||||||
|
if (key.equals("class") || key.equals("area") || key.equals("lang") || key.equals("year")) {
|
||||||
|
try {
|
||||||
|
str = str + "筛选" + key + "+全部=+" + typeExtend.getString(key).replace(",", "+") + "\n";
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (URL.contains(".vod")) {
|
||||||
|
str += "\n" + "排序+全部=+最新=time+最热=hits+评分=score";
|
||||||
|
} else if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
} else {
|
||||||
|
str = "分类+全部=+电影=movie+连续剧=tvplay+综艺=tvshow+动漫=comic+4K=movie_4k+体育=tiyu\n筛选class+全部=+喜剧+爱情+恐怖+动作+科幻+剧情+战争+警匪+犯罪+动画+奇幻+武侠+冒险+枪战+恐怖+悬疑+惊悚+经典+青春+文艺+微电影+古装+历史+运动+农村+惊悚+惊悚+伦理+情色+福利+三级+儿童+网络电影\n筛选area+全部=+大陆+香港+台湾+美国+英国+法国+日本+韩国+德国+泰国+印度+西班牙+加拿大+其他\n筛选year+全部=+2022+2021+2020+2019+2018+2017+2016+2015+2014+2013+2012+2011+2010+2009+2008+2007+2006+2005+2004+2003+2002+2001+2000";
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######推荐地址
|
||||||
|
String getRecommendUrl(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return URL + "index_video?token=";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return URL + "/vodPhbAll";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######播放器前缀地址
|
||||||
|
String getPlayUrlPrefix(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
if (URL.contains("dijiaxia")) {
|
||||||
|
URL = "https://www.dijiaxia.com/api.php/app/";
|
||||||
|
return URL + "video_detail?id=";
|
||||||
|
} else if (URL.contains("1010dy")) {
|
||||||
|
URL = "http://www.1010dy.cc/api.php/app/";
|
||||||
|
return URL + "video_detail?id=";
|
||||||
|
} else {
|
||||||
|
return URL + "video_detail?id=";
|
||||||
|
}
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun")) {
|
||||||
|
return URL + "/detailID?vod_id=";
|
||||||
|
} else {
|
||||||
|
return URL + "/detail?vod_id=";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######选集
|
||||||
|
private final HashMap<String, String> parseUrlMap = new HashMap<>();
|
||||||
|
|
||||||
|
private void genPlayList(String URL, JSONObject object, String json, JSONObject vod, String vid) throws JSONException {
|
||||||
|
ArrayList<String> playUrls = new ArrayList<>();
|
||||||
|
ArrayList<String> playFlags = new ArrayList<>();
|
||||||
|
if (URL.contains("api.php/app/")) {
|
||||||
|
JSONObject data = object.getJSONObject("data");
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("vod_name"));
|
||||||
|
vod.put("vod_pic", data.getString("vod_pic"));
|
||||||
|
vod.put("type_name", data.optString("vod_class"));
|
||||||
|
vod.put("vod_year", data.optString("vod_year"));
|
||||||
|
vod.put("vod_area", data.optString("vod_area"));
|
||||||
|
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||||
|
vod.put("vod_actor", data.optString("vod_actor"));
|
||||||
|
vod.put("vod_director", data.optString("vod_director"));
|
||||||
|
vod.put("vod_content", data.optString("vod_content"));
|
||||||
|
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_url_with_player");
|
||||||
|
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||||
|
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||||
|
String flag = stopVipFlag(from.getString("name"));
|
||||||
|
playFlags.add(flag);
|
||||||
|
playUrls.add(from.getString("url"));
|
||||||
|
String purl = from.optString("parse_api");
|
||||||
|
if (purl.contains("jpg.hou.lu/jm/za/index.php")) {
|
||||||
|
purl = "http://vip.mengx.vip/home/api?type=ys&uid=3249696&key=aefqrtuwxyEFHKNOQY&url=";
|
||||||
|
}
|
||||||
|
parseUrlMap.put(flag, purl);
|
||||||
|
}
|
||||||
|
} else if (URL.contains("xgapp")) {
|
||||||
|
JSONObject data = object.getJSONObject("data").getJSONObject("vod_info");
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("vod_name"));
|
||||||
|
vod.put("vod_pic", data.getString("vod_pic"));
|
||||||
|
vod.put("type_name", data.optString("vod_class"));
|
||||||
|
vod.put("vod_year", data.optString("vod_year"));
|
||||||
|
vod.put("vod_area", data.optString("vod_area"));
|
||||||
|
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||||
|
vod.put("vod_actor", data.optString("vod_actor"));
|
||||||
|
vod.put("vod_director", data.optString("vod_director"));
|
||||||
|
vod.put("vod_content", data.optString("vod_content"));
|
||||||
|
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_url_with_player");
|
||||||
|
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||||
|
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||||
|
String flag = stopVipFlag(from.getString("name"));
|
||||||
|
playFlags.add(flag);
|
||||||
|
playUrls.add(from.getString("url"));
|
||||||
|
String purl = from.optString("parse_api");
|
||||||
|
if (purl.contains("jpg.hou.lu/jm/za/index.php")) {
|
||||||
|
purl = "http://vip.mengx.vip/home/api?type=ys&uid=3249696&key=aefqrtuwxyEFHKNOQY&url=";
|
||||||
|
}
|
||||||
|
parseUrlMap.put(flag, purl);
|
||||||
|
}
|
||||||
|
} else if (/*urlPattern2.matcher(URL).find()*/URL.contains(".vod")) {
|
||||||
|
JSONObject data = object.getJSONObject("data");
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("vod_name"));
|
||||||
|
vod.put("vod_pic", data.getString("vod_pic"));
|
||||||
|
vod.put("type_name", data.optString("vod_class"));
|
||||||
|
vod.put("vod_year", data.optString("vod_year"));
|
||||||
|
vod.put("vod_area", data.optString("vod_area"));
|
||||||
|
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||||
|
vod.put("vod_actor", data.optString("vod_actor"));
|
||||||
|
vod.put("vod_director", data.optString("vod_director"));
|
||||||
|
vod.put("vod_content", data.optString("vod_content"));
|
||||||
|
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_play_list");
|
||||||
|
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||||
|
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||||
|
String flag = stopVipFlag(from.getJSONObject("player_info").getString("show"));
|
||||||
|
playFlags.add(flag);
|
||||||
|
playUrls.add(from.getString("url"));
|
||||||
|
try {
|
||||||
|
ArrayList<String> parses = new ArrayList<>();
|
||||||
|
String[] parse1 = from.getJSONObject("player_info").optString("parse").split(",");
|
||||||
|
String[] parse2 = from.getJSONObject("player_info").optString("parse2").split(",");
|
||||||
|
for (String p : parse1) {
|
||||||
|
if (parsePattern.matcher(p).find()) {
|
||||||
|
boolean add = true;
|
||||||
|
for (Pattern pt : parseMatchForDotVod) {
|
||||||
|
if (pt.matcher(p).find()) {
|
||||||
|
add = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add) {
|
||||||
|
parses.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String p : parse2) {
|
||||||
|
if (parsePattern.matcher(p).find()) {
|
||||||
|
boolean add = true;
|
||||||
|
for (Pattern pt : parseMatchForDotVod) {
|
||||||
|
if (pt.matcher(p).find()) {
|
||||||
|
add = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add) {
|
||||||
|
parses.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parses.size() > 0 && parses.get(0).contains("=")) {
|
||||||
|
String purl = parses.get(0);
|
||||||
|
if (purl.contains("http")) {
|
||||||
|
Matcher matcher = parsePattern1.matcher(purl);
|
||||||
|
if (matcher.find()) {
|
||||||
|
purl = matcher.group(0).replace("..", ".").replace("vip.aotian.love", "vip.gaotian.love");
|
||||||
|
}
|
||||||
|
} else if (purl.contains("//")) {
|
||||||
|
Matcher matcher = parsePattern1.matcher(purl);
|
||||||
|
if (matcher.find()) {
|
||||||
|
purl = "http:" + matcher.group(0).replace("..", ".");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Matcher matcher = parsePattern2.matcher(URL);
|
||||||
|
if (matcher.find()) {
|
||||||
|
Matcher matcher1 = parsePattern1.matcher(URL);
|
||||||
|
if (matcher1.find()) {
|
||||||
|
purl = matcher.group(0) + matcher1.group(0).replace("..", ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parseUrlMap.put(flag, purl);
|
||||||
|
} else {
|
||||||
|
parseUrlMap.put(flag, "http://1.117.152.239:39000/?url=");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (urlPattern1.matcher(URL).find()) {
|
||||||
|
JSONObject data = object;
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("title"));
|
||||||
|
vod.put("vod_pic", data.getString("img_url"));
|
||||||
|
vod.put("type_name", jsonArr2Str(data.optJSONArray("type")));
|
||||||
|
vod.put("vod_year", data.optString("pubtime"));
|
||||||
|
vod.put("vod_area", jsonArr2Str(data.optJSONArray("area")));
|
||||||
|
vod.put("vod_remarks", data.optString("trunk"));
|
||||||
|
vod.put("vod_actor", jsonArr2Str(data.optJSONArray("actor")));
|
||||||
|
vod.put("vod_director", jsonArr2Str(data.optJSONArray("director")));
|
||||||
|
vod.put("vod_content", data.optString("intro"));
|
||||||
|
JSONObject playList = data.getJSONObject("videolist");
|
||||||
|
Iterator<String> playListKeys = playList.keys();
|
||||||
|
while (playListKeys.hasNext()) {
|
||||||
|
String from = playListKeys.next();
|
||||||
|
JSONArray playListUrls = playList.getJSONArray(from);
|
||||||
|
ArrayList<String> urls = new ArrayList<>();
|
||||||
|
for (int j = 0; j < playListUrls.length(); j++) {
|
||||||
|
JSONObject urlObj = playListUrls.getJSONObject(j);
|
||||||
|
urls.add(urlObj.getString("title") + "$" + urlObj.getString("url"));
|
||||||
|
}
|
||||||
|
playFlags.add(stopVipFlag(from));
|
||||||
|
playUrls.add(TextUtils.join("#", urls));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for (int i = 0; i < playFlags.size(); i++) {
|
||||||
|
// String pu = playUrls.get(i).split("#")[0].split("\\$")[1];
|
||||||
|
// System.out.println(pu + " is video?" + isVideoFormat(pu));
|
||||||
|
// playerContent(playFlags.get(i), pu, new ArrayList<>());
|
||||||
|
// }
|
||||||
|
vod.put("vod_play_from", TextUtils.join("$$$", playFlags));
|
||||||
|
vod.put("vod_play_url", TextUtils.join("$$$", playUrls));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getParseUrl(String URL, String flag) {
|
||||||
|
String parseUrl = "";
|
||||||
|
if (urlPattern2.matcher(URL).find()) {
|
||||||
|
if (parseUrlMap.containsKey(flag))
|
||||||
|
parseUrl = parseUrlMap.get(flag);
|
||||||
|
} else if (URL.contains("api.php/app/") || URL.contains("xgapp")) {
|
||||||
|
if (parseUrlMap.containsKey(flag))
|
||||||
|
parseUrl = parseUrlMap.get(flag);
|
||||||
|
} else {
|
||||||
|
parseUrl = URL;
|
||||||
|
}
|
||||||
|
if (parseUrl.contains("svip.jhyun.jx.cn") || parseUrl.contains("svip.jhdyw.vip")) {
|
||||||
|
if (flag.contains("人人迷")) {
|
||||||
|
parseUrl = "http://www.1080kan.cc/jiexi/rrmi.php?url=";
|
||||||
|
} else if (flag.contains("人人")) {
|
||||||
|
parseUrl = "http://www.1080kan.cc/jiexi/rr.php?url=";
|
||||||
|
} else if (flag.contains("番茄")) {
|
||||||
|
parseUrl = "http://www.1080kan.cc/jiexi/fq.php?url=";
|
||||||
|
} else {
|
||||||
|
parseUrl = "https://jx.parwix.com:4433/player/?url=";
|
||||||
|
}
|
||||||
|
} else if (parseUrl.contains("jhsj.manduhu.com") || parseUrl.contains("v.jhdyw.vip/nhdz666")) {
|
||||||
|
parseUrl = "https://jx.parwix.com:4433/player/?url=";
|
||||||
|
} else if (parseUrl.contains("x-n.cc")) {
|
||||||
|
parseUrl = "https://jx.parwix.com:4433/player/?url=";
|
||||||
|
}
|
||||||
|
return parseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPlayerUrl(String URL, String parseUrl, String playUrl) {
|
||||||
|
if (URL.contains("xgapp") || URL.contains("api.php/app/") || /*urlPattern2.matcher(URL).find()*/URL.contains(".vod")) {
|
||||||
|
if (playUrl.indexOf(".m3u8") > 15 || playUrl.indexOf(".mp4") > 15 || playUrl.contains("/obj/tos")) {
|
||||||
|
if (playUrl.contains("url=")) {
|
||||||
|
return "https://www.baidu.com/s?wd=" + playUrl.split("url=")[1];
|
||||||
|
} else {
|
||||||
|
return "https://www.baidu.com/s?wd=" + playUrl;
|
||||||
|
}
|
||||||
|
} else if (!parseUrl.contains("url=") && playUrl.contains("RongXingVR")) {
|
||||||
|
return "https://www.baidu.com/s?wd=https://fast.rongxingvr.cn:8866/api/?key=nShWumGdMIbTwngTbI&url=" + playUrl;
|
||||||
|
} else if (!parseUrl.contains("url=") && playUrl.contains("LT")) {
|
||||||
|
return "https://www.baidu.com/s?wd=https://f7.pyxddc.com/bcjx/4k.php?url=" + playUrl;
|
||||||
|
} else if (!parseUrl.contains("url=") && playUrl.contains("renrenmi")) {
|
||||||
|
return "https://www.baidu.com/s?wd=https://kuba.renrenmi.cc:2266/api/?key=Y6UYLYtjImTCKe98JD&url=" + playUrl;
|
||||||
|
} else if (!parseUrl.contains("url=") && playUrl.contains(".html")) {
|
||||||
|
return "https://www.baidu.com/s?wd=http://1.117.152.239:39000/?url=" + playUrl;
|
||||||
|
} else if (playUrl.contains("xfy")) {
|
||||||
|
return "https://www.baidu.com/s?wd=http://jiexi.yunl.cc/api/?key=xYNESYSvHp1DV2ckKs&url=" + playUrl;
|
||||||
|
} else {
|
||||||
|
return "https://www.baidu.com/s?wd=" + parseUrl + playUrl;
|
||||||
|
}
|
||||||
|
} else if (urlPattern1.matcher(URL).find()) {
|
||||||
|
if (playUrl.indexOf(".m3u8") > 15 || playUrl.indexOf(".mp4") > 15 || playUrl.contains("/obj/tos")) {
|
||||||
|
if (playUrl.contains("url=")) {
|
||||||
|
return "https://www.baidu.com/s?wd=" + playUrl.split("url=")[1];
|
||||||
|
} else {
|
||||||
|
return "https://www.baidu.com/s?wd=" + playUrl;
|
||||||
|
}
|
||||||
|
} else if (playUrl.contains("xfy")) {
|
||||||
|
if (playUrl.contains("url=")) {
|
||||||
|
return "https://www.baidu.com/s?wd=http://cache.dmtt.xyz/xfyjx/xfyjx.php?url=" + playUrl.split("url=")[1];
|
||||||
|
} else {
|
||||||
|
return "https://www.baidu.com/s?wd=https://json.hfyrw.com/mao.go?url=" + playUrl;
|
||||||
|
}
|
||||||
|
} else if (playUrl.contains("www.bilibili.com")) {
|
||||||
|
String spUrl = playUrl.split("url=")[1];
|
||||||
|
return "https://www.baidu.com/s?wd=https://jx.parwix.com:4433/player/?url=" + spUrl;
|
||||||
|
} else if (URL.contains("zhenfy") || URL.contains("cztv") || URL.contains("1.14.63.101") || URL.contains("fit:8") || URL.contains("diliktv.xyz") || URL.contains("ppzhu.vip") || URL.contains("api.8d8q.com") || URL.contains("haokanju1.cc") || URL.contains("cztv")) {
|
||||||
|
return "https://www.baidu.com/s?wd=" + playUrl + "&app=10000&account=272775028&password=qq272775028";
|
||||||
|
} else if (URL.contains("lxyyy") || URL.contains("j.zjj.life") || URL.contains("lktv") || URL.contains("0818tv") || URL.contains("ruoxinew")) {
|
||||||
|
return "https://www.baidu.com/s?wd=https://play.tkys.tv/?url=" + playUrl.split("url=")[1];
|
||||||
|
} else {
|
||||||
|
return "https://www.baidu.com/s?wd=" + playUrl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "https://www.baidu.com/s?wd=" + playUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######视频地址
|
||||||
|
private void getFinalVideo(String uu, JSONObject result) throws JSONException {
|
||||||
|
if (uu.contains("baidu.com")) {
|
||||||
|
String playurl = uu.split("wd=")[1];
|
||||||
|
if (playurl.contains("duoduozy.com") || playurl.contains("suoyo.cc")) {
|
||||||
|
String uuu = "https://www.6080kan.cc/app.php?url=" + playurl;
|
||||||
|
String content = OkHttpUtil.string(uuu, null);
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", obj.getString("url"));
|
||||||
|
result.put("header", "{\"User-Agent\":\" Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0\",\"referer\":\" https://player.duoduozy.com\",\"origin\":\" https://dp.duoduozy.com\",\"Host\":\" cache.m3u8.suoyo.cc\"}");
|
||||||
|
} else if (playurl.contains("xfy")) {
|
||||||
|
String content = OkHttpUtil.string(playurl, null);
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", obj.getString("url"));
|
||||||
|
result.put("header", "{\"referer\":\" appguapi.lihaoyun.top:11543\",\"User-Agent\":\" Dart/2.14 (dart:io)\"}}");
|
||||||
|
} else if (playurl.contains("api.iopenyun.com:88")) {
|
||||||
|
if (playurl.contains("html")) {
|
||||||
|
String content = OkHttpUtil.string("https://api.m3u8.tv:5678/home/api?type=ys&uid=233711&key=dgilouvFKNRSWX2467&url=" + playurl.split("=")[1], null);
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
String ppurl = obj.getString("url");
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", ppurl);
|
||||||
|
} else {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", playurl);
|
||||||
|
result.put("ua", "Mozilla/5.0 Windows10");
|
||||||
|
result.put("header", "{\"Referer\":\"https://user.iopenyun.com:520/user/video/\"}");
|
||||||
|
}
|
||||||
|
} else if (playurl.contains("cat.wkfile.com")) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", playurl);
|
||||||
|
result.put("header", "{\"User-Agent\":\" Lavf/58.12.100\",\"Referer\":\" wkfile.com\"}");
|
||||||
|
} else if (!playurl.contains("=") && playurl.indexOf(".m3u8") > 15 || playurl.indexOf(".mp4") > 15 || playurl.contains("/obj/tos")) {
|
||||||
|
if (playurl.contains("hsl.ysgc.xyz")) {
|
||||||
|
String content = OkHttpUtil.string("https://jx.ysgc.xyz/?url=" + playurl, null);
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
String ppurl = obj.getString("url");
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", ppurl);
|
||||||
|
result.put("header", "{\"Referer\":\" https://ysgc.cc\"}");
|
||||||
|
} else if (playurl.contains("1.ruifenglb.com")) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", playurl);
|
||||||
|
result.put("header", "{\"Referer\":\" https://1.ruifenglb.com\"}");
|
||||||
|
} else {
|
||||||
|
Matcher matcher = Pattern.compile(".*(http.*)").matcher(playurl);
|
||||||
|
if (matcher.find()) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", matcher.group(1));
|
||||||
|
} else {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", playurl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (playurl.contains("=")) {
|
||||||
|
HashMap<String, String> headers = new HashMap();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 Android");
|
||||||
|
Map<String, List<String>> respHeaders = new TreeMap<>();
|
||||||
|
String content = OkHttpUtil.stringNoRedirect(playurl, headers, respHeaders);
|
||||||
|
String redLoc = OkHttpUtil.getRedirectLocation(respHeaders);
|
||||||
|
if (redLoc != null) {
|
||||||
|
String finalurl = "";
|
||||||
|
while (redLoc != null) {
|
||||||
|
finalurl = redLoc;
|
||||||
|
if (redLoc.indexOf(".mp4") > 30) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 Android");
|
||||||
|
content = OkHttpUtil.stringNoRedirect(finalurl, headers, respHeaders);
|
||||||
|
redLoc = OkHttpUtil.getRedirectLocation(respHeaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String realurl = finalurl;
|
||||||
|
if (realurl.contains("=http") || realurl.contains("url=")) {
|
||||||
|
if (content.contains("<html")) {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
} else {
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
String ppurl = obj.getString("url");
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", ppurl);
|
||||||
|
if (realurl.contains("mgtv.com")) {
|
||||||
|
result.put("header", "{\"User-Agent\":\" Mozilla/5.0\", \"Referer\":\" \"}");
|
||||||
|
} else if (realurl.contains("bilibili.com")) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (playurl.contains("www.mgtv.com")) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
result.put("header", "{\"User-Agent\":\" Mozilla/5.0\", \"Referer\":\" \"}");
|
||||||
|
} else {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (content.contains("<html")) {
|
||||||
|
boolean sniffer = false;
|
||||||
|
for (Pattern p : htmlVideoKeyMatch) {
|
||||||
|
if (p.matcher(content).find()) {
|
||||||
|
sniffer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sniffer) {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", playurl);
|
||||||
|
} else {
|
||||||
|
if (playurl.split("url=")[1].contains("http")) {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", "http://1.117.152.239:39000/?url=" + playurl.split("url=")[1]);
|
||||||
|
} else if (playurl.split("url=")[1].contains("renrenmi")) {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", "http://www.1080kan.cc/jiexi/rrmi.php?url=" + playurl.split("url=")[1]);
|
||||||
|
result.put("header", "{\"Referer\":\"http://www.1080kan.cc/\"}");
|
||||||
|
} else {
|
||||||
|
String id = playurl.split("url=")[1];
|
||||||
|
/*
|
||||||
|
String uuu = "https://vip.gaotian.love/api/?key=sRy0QAq8hqXRlrEtrq&url=" + id;
|
||||||
|
content = OkHttpUtil.string(uuu, null);
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
String realurl = obj.optString("url", "");
|
||||||
|
if (realurl.isEmpty())
|
||||||
|
realurl = obj.optString("msg", "");
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
*/
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", "https://jx.banyung.xyz:7799/player/?url=" + playurl.split("url=")[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String jsonUrl = "";
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
jsonUrl = obj.optString("url");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (jsonUrl.length() > 1) {
|
||||||
|
String realurl = jsonUrl;
|
||||||
|
if (playurl.contains("mgtv.com")) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
result.put("header", "{\"User-Agent\":\" Mozilla/5.0\", \"Referer\":\" \"}");
|
||||||
|
} else if (playurl.contains("bilibili.com")) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
} else {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
}
|
||||||
|
} else if (playurl.split("url=")[1].contains("http")) {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", "http://1.117.152.239:39000/?url=" + playurl.split("url=")[1]);
|
||||||
|
} else if (playurl.split("url=")[1].contains("renrenmi")) {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", "http://www.1080kan.cc/jiexi/rrmi.php?url=" + playurl.split("url=")[1]);
|
||||||
|
result.put("header", "{\"Referer\":\"http://www.1080kan.cc/\"}");
|
||||||
|
} else {
|
||||||
|
String id = playurl.split("url=")[1];
|
||||||
|
/*
|
||||||
|
String uuu = "https://vip.gaotian.love/api/?key=sRy0QAq8hqXRlrEtrq&url=" + id;
|
||||||
|
content = OkHttpUtil.string(uuu, null);
|
||||||
|
JSONObject obj = new JSONObject(content);
|
||||||
|
String realurl = obj.optString("url", "");
|
||||||
|
if (realurl.isEmpty())
|
||||||
|
realurl = obj.optString("msg", "");
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", realurl);
|
||||||
|
*/
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", "https://jx.banyung.xyz:7799/player/?url=" + playurl.split("url=")[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", playurl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", uu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean manualVideoCheck() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVideoFormat(String url) {
|
||||||
|
return Misc.isVideoFormat(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,845 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* M浏览器中的App影视
|
||||||
|
* <p>
|
||||||
|
* Author: 群友 不负此生
|
||||||
|
*/
|
||||||
|
public class AppYsV2 extends Spider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
try {
|
||||||
|
extInfos = extend.split("###");
|
||||||
|
} catch (Throwable th) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
String url = getCateUrl(getApiUrl());
|
||||||
|
JSONArray jsonArray = null;
|
||||||
|
if (!url.isEmpty()) {
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = desc(OkHttpUtil.string(url, getHeaders(url)), (byte) 0);
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("data");
|
||||||
|
}
|
||||||
|
} else { // 通过filter列表读分类
|
||||||
|
String filterStr = getFilterTypes(url, null);
|
||||||
|
String[] classes = filterStr.split("\n")[0].split("\\+");
|
||||||
|
jsonArray = new JSONArray();
|
||||||
|
for (int i = 1; i < classes.length; i++) {
|
||||||
|
String[] kv = classes[i].trim().split("=");
|
||||||
|
if (kv.length < 2)
|
||||||
|
continue;
|
||||||
|
JSONObject newCls = new JSONObject();
|
||||||
|
newCls.put("type_name", kv[0].trim());
|
||||||
|
newCls.put("type_id", kv[1].trim());
|
||||||
|
jsonArray.put(newCls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
if (jsonArray != null) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject jObj = jsonArray.getJSONObject(i);
|
||||||
|
String typeName = jObj.getString("type_name");
|
||||||
|
if (isBan(typeName))
|
||||||
|
continue;
|
||||||
|
String typeId = jObj.getString("type_id");
|
||||||
|
JSONObject newCls = new JSONObject();
|
||||||
|
newCls.put("type_id", typeId);
|
||||||
|
newCls.put("type_name", typeName);
|
||||||
|
JSONObject typeExtend = jObj.optJSONObject("type_extend");
|
||||||
|
if (filter) {
|
||||||
|
String filterStr = getFilterTypes(url, typeExtend);
|
||||||
|
String[] filters = filterStr.split("\n");
|
||||||
|
JSONArray filterArr = new JSONArray();
|
||||||
|
for (int k = url.isEmpty() ? 1 : 0; k < filters.length; k++) {
|
||||||
|
String l = filters[k].trim();
|
||||||
|
if (l.isEmpty())
|
||||||
|
continue;
|
||||||
|
String[] oneLine = l.split("\\+");
|
||||||
|
String type = oneLine[0].trim();
|
||||||
|
String typeN = type;
|
||||||
|
if (type.contains("筛选")) {
|
||||||
|
type = type.replace("筛选", "");
|
||||||
|
if (type.equals("class"))
|
||||||
|
typeN = "类型";
|
||||||
|
else if (type.equals("area"))
|
||||||
|
typeN = "地区";
|
||||||
|
else if (type.equals("lang"))
|
||||||
|
typeN = "语言";
|
||||||
|
else if (type.equals("year"))
|
||||||
|
typeN = "年份";
|
||||||
|
}
|
||||||
|
JSONObject jOne = new JSONObject();
|
||||||
|
jOne.put("key", type);
|
||||||
|
jOne.put("name", typeN);
|
||||||
|
JSONArray valueArr = new JSONArray();
|
||||||
|
for (int j = 1; j < oneLine.length; j++) {
|
||||||
|
JSONObject kvo = new JSONObject();
|
||||||
|
String kv = oneLine[j].trim();
|
||||||
|
int sp = kv.indexOf("=");
|
||||||
|
if (sp == -1) {
|
||||||
|
if (isBan(kv))
|
||||||
|
continue;
|
||||||
|
kvo.put("n", kv);
|
||||||
|
kvo.put("v", kv);
|
||||||
|
} else {
|
||||||
|
String n = kv.substring(0, sp);
|
||||||
|
if (isBan(n))
|
||||||
|
continue;
|
||||||
|
kvo.put("n", n.trim());
|
||||||
|
kvo.put("v", kv.substring(sp + 1).trim());
|
||||||
|
}
|
||||||
|
valueArr.put(kvo);
|
||||||
|
}
|
||||||
|
jOne.put("value", valueArr);
|
||||||
|
filterArr.put(jOne);
|
||||||
|
}
|
||||||
|
if (!result.has("filters")) {
|
||||||
|
result.put("filters", new JSONObject());
|
||||||
|
}
|
||||||
|
result.getJSONObject("filters").put(typeId, filterArr);
|
||||||
|
}
|
||||||
|
classes.put(newCls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
String apiUrl = getApiUrl();
|
||||||
|
String url = getRecommendUrl(apiUrl);
|
||||||
|
boolean isTV = false;
|
||||||
|
if (url.isEmpty()) {
|
||||||
|
url = getCateFilterUrlPrefix(apiUrl) + "movie&page=1&area=&type=&start=";
|
||||||
|
isTV = true;
|
||||||
|
}
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = desc(OkHttpUtil.string(url, getHeaders(url)), (byte) 1);
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (isTV) {
|
||||||
|
JSONArray jsonArray = obj.getJSONArray("data");
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("nextlink"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("state"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ArrayList<JSONArray> arrays = new ArrayList<>();
|
||||||
|
findJsonArray(obj, "vlist", arrays);
|
||||||
|
if (arrays.isEmpty()) {
|
||||||
|
findJsonArray(obj, "vod_list", arrays);
|
||||||
|
}
|
||||||
|
List<String> ids = new ArrayList<>();
|
||||||
|
for (JSONArray jsonArray : arrays) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
String vid = vObj.getString("vod_id");
|
||||||
|
if (ids.contains(vid))
|
||||||
|
continue;
|
||||||
|
ids.add(vid);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vid);
|
||||||
|
v.put("vod_name", vObj.getString("vod_name"));
|
||||||
|
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String apiUrl = getApiUrl();
|
||||||
|
String url = getCateFilterUrlPrefix(apiUrl) + tid + getCateFilterUrlSuffix(apiUrl);
|
||||||
|
url = url.replace("#PN#", pg);
|
||||||
|
url = url.replace("筛选class", (extend != null && extend.containsKey("class")) ? extend.get("class") : "");
|
||||||
|
url = url.replace("筛选area", (extend != null && extend.containsKey("area")) ? extend.get("area") : "");
|
||||||
|
url = url.replace("筛选lang", (extend != null && extend.containsKey("lang")) ? extend.get("lang") : "");
|
||||||
|
url = url.replace("筛选year", (extend != null && extend.containsKey("year")) ? extend.get("year") : "");
|
||||||
|
url = url.replace("排序", (extend != null && extend.containsKey("排序")) ? extend.get("排序") : "");
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = desc(OkHttpUtil.string(url, getHeaders(url)), (byte) 2);
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
int totalPg = Integer.MAX_VALUE;
|
||||||
|
try {
|
||||||
|
if (obj.has("totalpage") && obj.get("totalpage") instanceof Integer) {
|
||||||
|
totalPg = obj.getInt("totalpage");
|
||||||
|
} else if (obj.has("pagecount") && obj.get("pagecount") instanceof Integer) {
|
||||||
|
totalPg = obj.getInt("pagecount");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject &&
|
||||||
|
(obj.getJSONObject("data").has("total") && obj.getJSONObject("data").get("total") instanceof Integer &&
|
||||||
|
obj.getJSONObject("data").has("limit") && obj.getJSONObject("data").get("limit") instanceof Integer)) {
|
||||||
|
int limit = obj.getJSONObject("data").getInt("limit");
|
||||||
|
int total = obj.getJSONObject("data").getInt("total");
|
||||||
|
totalPg = total % limit == 0 ? (total / limit) : (total / limit + 1);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray jsonArray = null;
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("data");
|
||||||
|
}
|
||||||
|
if (jsonArray != null) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
if (vObj.has("vod_id")) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("vod_id"));
|
||||||
|
v.put("vod_name", vObj.getString("vod_name"));
|
||||||
|
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||||
|
videos.put(v);
|
||||||
|
} else {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("nextlink"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("state"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("page", pg);
|
||||||
|
result.put("pagecount", totalPg);
|
||||||
|
result.put("limit", 90);
|
||||||
|
result.put("total", Integer.MAX_VALUE);
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
String apiUrl = getApiUrl();
|
||||||
|
String url = getPlayUrlPrefix(apiUrl) + ids.get(0);
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
String json = desc(OkHttpUtil.string(url, getHeaders(url)), (byte) 3);
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vod = new JSONObject();
|
||||||
|
genPlayList(apiUrl, obj, json, vod, ids.get(0));
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vod);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String apiUrl = getApiUrl();
|
||||||
|
String url = getSearchUrl(apiUrl, URLEncoder.encode(key));
|
||||||
|
//System.out.println(url);
|
||||||
|
String json = desc(OkHttpUtil.string(url, getHeaders(url)), (byte) 5);
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
JSONArray jsonArray = null;
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||||
|
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||||
|
jsonArray = obj.getJSONArray("data");
|
||||||
|
}
|
||||||
|
if (jsonArray != null) {
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
if (vObj.has("vod_id")) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("vod_id"));
|
||||||
|
v.put("vod_name", vObj.getString("vod_name"));
|
||||||
|
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||||
|
videos.put(v);
|
||||||
|
} else {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("nextlink"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("state"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||||
|
if (parseUrls == null)
|
||||||
|
parseUrls = new ArrayList<>();
|
||||||
|
if (!parseUrls.isEmpty()) {
|
||||||
|
JSONObject result = getFinalVideo(flag, parseUrls, id);
|
||||||
|
if (result != null)
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
if (Misc.isVideoFormat(id)) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", id);
|
||||||
|
return result.toString();
|
||||||
|
} else {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("jx", "1");
|
||||||
|
result.put("url", id);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findJsonArray(JSONObject obj, String match, ArrayList<JSONArray> result) {
|
||||||
|
Iterator<String> keys = obj.keys();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String k = keys.next();
|
||||||
|
try {
|
||||||
|
Object o = obj.get(k);
|
||||||
|
if (k.equals(match) && o instanceof JSONArray)
|
||||||
|
result.add((JSONArray) o);
|
||||||
|
if (o instanceof JSONObject) {
|
||||||
|
findJsonArray((JSONObject) o, match, result);
|
||||||
|
} else if (o instanceof JSONArray) {
|
||||||
|
JSONArray array = (JSONArray) o;
|
||||||
|
for (int i = 0; i < array.length(); i++) {
|
||||||
|
findJsonArray(array.getJSONObject(i), match, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String jsonArr2Str(JSONArray array) {
|
||||||
|
try {
|
||||||
|
ArrayList<String> strings = new ArrayList<>();
|
||||||
|
for (int i = 0; i < array.length(); i++) {
|
||||||
|
strings.add(array.getString(i));
|
||||||
|
}
|
||||||
|
return TextUtils.join(",", strings);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<String, String> getHeaders(String URL) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", UA(URL));
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBan(String key) {
|
||||||
|
return key.equals("伦理") || key.equals("情色") || key.equals("福利");
|
||||||
|
}
|
||||||
|
|
||||||
|
// M 扩展方法
|
||||||
|
|
||||||
|
// ######重组搜索
|
||||||
|
private String getSearchUrl(String URL, String KEY) {
|
||||||
|
if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun.com")) {
|
||||||
|
return URL + "/list?wd=" + KEY + "&page=";
|
||||||
|
} else {
|
||||||
|
return URL + "?wd=" + KEY + "&page=";
|
||||||
|
}
|
||||||
|
} else if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return URL + "search?text=" + KEY + "&pg=";
|
||||||
|
} else if (urlPattern1.matcher(URL).find()) {
|
||||||
|
if (URL.contains("esellauto")
|
||||||
|
|| URL.contains("1.14.63.101")
|
||||||
|
|| URL.contains("zjys")
|
||||||
|
|| URL.contains("dcd")
|
||||||
|
|| URL.contains("lxue")
|
||||||
|
|| URL.contains("weetai.cn")
|
||||||
|
|| URL.contains("haokanju1")
|
||||||
|
|| URL.contains("fit:8")
|
||||||
|
|| URL.contains("zjj.life")
|
||||||
|
|| URL.contains("love9989")
|
||||||
|
|| URL.contains("8d8q")
|
||||||
|
|| URL.contains("lk.pxun")
|
||||||
|
|| URL.contains("hgyx")
|
||||||
|
|| URL.contains("521x5")
|
||||||
|
|| URL.contains("lxyyy")
|
||||||
|
|| URL.contains("0818tv")
|
||||||
|
|| URL.contains("diyoui")
|
||||||
|
|| URL.contains("diliktv")
|
||||||
|
|| URL.contains("ppzhu")
|
||||||
|
|| URL.contains("aitesucai")
|
||||||
|
|| URL.contains("zz.ci")
|
||||||
|
|| URL.contains("chxjon")
|
||||||
|
|| URL.contains("watchmi")
|
||||||
|
|| URL.contains("vipbp")
|
||||||
|
|| URL.contains("bhtv")
|
||||||
|
|| URL.contains("xfykl")) {
|
||||||
|
return URL + "?ac=list&" + "wd=" + KEY + "&page=";
|
||||||
|
} else {
|
||||||
|
return URL + "?ac=list&" + "zm=" + KEY + "&page=";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######UA
|
||||||
|
private static final Pattern urlPattern1 = Pattern.compile("api\\.php/.*?/vod");
|
||||||
|
private static final Pattern urlPattern2 = Pattern.compile("api\\.php/.+?\\.vod");
|
||||||
|
private static final Pattern parsePattern = Pattern.compile("/.+\\?.+=");
|
||||||
|
private static final Pattern parsePattern1 = Pattern.compile(".*(url|v|vid|php\\?id)=");
|
||||||
|
private static final Pattern parsePattern2 = Pattern.compile("https?://[^/]*");
|
||||||
|
|
||||||
|
protected static final Pattern[] htmlVideoKeyMatch = new Pattern[]{
|
||||||
|
Pattern.compile("player=new"),
|
||||||
|
Pattern.compile("<div id=\"video\""),
|
||||||
|
Pattern.compile("<div id=\"[^\"]*?player\""),
|
||||||
|
Pattern.compile("//视频链接"),
|
||||||
|
Pattern.compile("HlsJsPlayer\\("),
|
||||||
|
Pattern.compile("<iframe[\\s\\S]*?src=\"[^\"]+?\""),
|
||||||
|
Pattern.compile("<video[\\s\\S]*?src=\"[^\"]+?\"")
|
||||||
|
};
|
||||||
|
|
||||||
|
private String UA(String URL) {
|
||||||
|
if (URL.contains("vod.9e03.com")) {
|
||||||
|
return "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36";
|
||||||
|
} else if (URL.contains("api.php/app") || URL.contains("xgapp") || URL.contains("freekan")) {
|
||||||
|
return "Dart/2.14 (dart:io)";
|
||||||
|
} else if (URL.contains("zsb") || URL.contains("fkxs") || URL.contains("xays") || URL.contains("xcys") || URL.contains("szys") || URL.contains("dxys") || URL.contains("ytys") || URL.contains("qnys")) {
|
||||||
|
return "Dart/2.15 (dart:io)";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return "okhttp/4.1.0";
|
||||||
|
} else {
|
||||||
|
return "Dalvik/2.1.0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######获取分类地址
|
||||||
|
String getCateUrl(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return URL + "nav?token=";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun.com")) {
|
||||||
|
return URL + "/list?type";
|
||||||
|
} else {
|
||||||
|
return URL + "/types";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######分类筛选前缀地址
|
||||||
|
String getCateFilterUrlPrefix(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
if (URL.contains("dijiaxia")) {
|
||||||
|
URL = "http://www.dijiaxia.com/api.php/app/";
|
||||||
|
return URL + "video?tid=";
|
||||||
|
} else {
|
||||||
|
return URL + "video?tid=";
|
||||||
|
}
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun")) {
|
||||||
|
return URL + "/list?type=";
|
||||||
|
} else {
|
||||||
|
return URL + "?type=";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return URL + "?ac=list&class=";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######分类筛选后缀地址
|
||||||
|
String getCateFilterUrlSuffix(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&limit=18&pg=#PN#";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&by=排序&limit=18&page=#PN#";
|
||||||
|
} else {
|
||||||
|
return "&page=#PN#&area=筛选area&type=筛选class&start=筛选year";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######筛选内容
|
||||||
|
String getFilterTypes(String URL, JSONObject typeExtend) {
|
||||||
|
String str = "";
|
||||||
|
if (typeExtend != null) {
|
||||||
|
Iterator<String> typeExtendKeys = typeExtend.keys();
|
||||||
|
while (typeExtendKeys.hasNext()) {
|
||||||
|
String key = typeExtendKeys.next();
|
||||||
|
if (key.equals("class") || key.equals("area") || key.equals("lang") || key.equals("year")) {
|
||||||
|
try {
|
||||||
|
str = str + "筛选" + key + "+全部=+" + typeExtend.getString(key).replace(",", "+") + "\n";
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (URL.contains(".vod")) {
|
||||||
|
str += "\n" + "排序+全部=+最新=time+最热=hits+评分=score";
|
||||||
|
} else if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
} else {
|
||||||
|
str = "分类+全部=+电影=movie+连续剧=tvplay+综艺=tvshow+动漫=comic+4K=movie_4k+体育=tiyu\n筛选class+全部=+喜剧+爱情+恐怖+动作+科幻+剧情+战争+警匪+犯罪+动画+奇幻+武侠+冒险+枪战+恐怖+悬疑+惊悚+经典+青春+文艺+微电影+古装+历史+运动+农村+惊悚+惊悚+伦理+情色+福利+三级+儿童+网络电影\n筛选area+全部=+大陆+香港+台湾+美国+英国+法国+日本+韩国+德国+泰国+印度+西班牙+加拿大+其他\n筛选year+全部=+2022+2021+2020+2019+2018+2017+2016+2015+2014+2013+2012+2011+2010+2009+2008+2007+2006+2005+2004+2003+2002+2001+2000";
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######推荐地址
|
||||||
|
String getRecommendUrl(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
return URL + "index_video?token=";
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
return URL + "/vodPhbAll";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######播放器前缀地址
|
||||||
|
String getPlayUrlPrefix(String URL) {
|
||||||
|
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||||
|
if (URL.contains("dijiaxia")) {
|
||||||
|
URL = "https://www.dijiaxia.com/api.php/app/";
|
||||||
|
return URL + "video_detail?id=";
|
||||||
|
} else if (URL.contains("1010dy")) {
|
||||||
|
URL = "http://www.1010dy.cc/api.php/app/";
|
||||||
|
return URL + "video_detail?id=";
|
||||||
|
} else {
|
||||||
|
return URL + "video_detail?id=";
|
||||||
|
}
|
||||||
|
} else if (URL.contains(".vod")) {
|
||||||
|
if (URL.contains("iopenyun")) {
|
||||||
|
return URL + "/detailID?vod_id=";
|
||||||
|
} else {
|
||||||
|
return URL + "/detail?vod_id=";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######选集
|
||||||
|
protected final HashMap<String, ArrayList<String>> parseUrlMap = new HashMap<>();
|
||||||
|
|
||||||
|
private void genPlayList(String URL, JSONObject object, String json, JSONObject vod, String vid) throws JSONException {
|
||||||
|
ArrayList<String> playUrls = new ArrayList<>();
|
||||||
|
ArrayList<String> playFlags = new ArrayList<>();
|
||||||
|
if (URL.contains("api.php/app/")) {
|
||||||
|
JSONObject data = object.getJSONObject("data");
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("vod_name"));
|
||||||
|
vod.put("vod_pic", data.getString("vod_pic"));
|
||||||
|
vod.put("type_name", data.optString("vod_class"));
|
||||||
|
vod.put("vod_year", data.optString("vod_year"));
|
||||||
|
vod.put("vod_area", data.optString("vod_area"));
|
||||||
|
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||||
|
vod.put("vod_actor", data.optString("vod_actor"));
|
||||||
|
vod.put("vod_director", data.optString("vod_director"));
|
||||||
|
vod.put("vod_content", data.optString("vod_content"));
|
||||||
|
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_url_with_player");
|
||||||
|
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||||
|
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||||
|
String flag = from.optString("code").trim();
|
||||||
|
if (flag.isEmpty())
|
||||||
|
flag = from.getString("name").trim();
|
||||||
|
playFlags.add(flag);
|
||||||
|
playUrls.add(from.getString("url"));
|
||||||
|
String purl = from.optString("parse_api").trim();
|
||||||
|
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||||
|
if (parseUrls == null) {
|
||||||
|
parseUrls = new ArrayList<>();
|
||||||
|
parseUrlMap.put(flag, parseUrls);
|
||||||
|
}
|
||||||
|
if (!purl.isEmpty() && !parseUrls.contains(purl))
|
||||||
|
parseUrls.add(purl);
|
||||||
|
}
|
||||||
|
} else if (URL.contains("xgapp")) {
|
||||||
|
JSONObject data = object.getJSONObject("data").getJSONObject("vod_info");
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("vod_name"));
|
||||||
|
vod.put("vod_pic", data.getString("vod_pic"));
|
||||||
|
vod.put("type_name", data.optString("vod_class"));
|
||||||
|
vod.put("vod_year", data.optString("vod_year"));
|
||||||
|
vod.put("vod_area", data.optString("vod_area"));
|
||||||
|
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||||
|
vod.put("vod_actor", data.optString("vod_actor"));
|
||||||
|
vod.put("vod_director", data.optString("vod_director"));
|
||||||
|
vod.put("vod_content", data.optString("vod_content"));
|
||||||
|
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_url_with_player");
|
||||||
|
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||||
|
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||||
|
String flag = from.optString("code").trim();
|
||||||
|
if (flag.isEmpty())
|
||||||
|
flag = from.getString("name").trim();
|
||||||
|
playFlags.add(flag);
|
||||||
|
playUrls.add(from.getString("url"));
|
||||||
|
String purl = from.optString("parse_api").trim();
|
||||||
|
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||||
|
if (parseUrls == null) {
|
||||||
|
parseUrls = new ArrayList<>();
|
||||||
|
parseUrlMap.put(flag, parseUrls);
|
||||||
|
}
|
||||||
|
if (!purl.isEmpty() && !parseUrls.contains(purl))
|
||||||
|
parseUrls.add(purl);
|
||||||
|
}
|
||||||
|
} else if (/*urlPattern2.matcher(URL).find()*/URL.contains(".vod")) {
|
||||||
|
JSONObject data = object.getJSONObject("data");
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("vod_name"));
|
||||||
|
vod.put("vod_pic", data.getString("vod_pic"));
|
||||||
|
vod.put("type_name", data.optString("vod_class"));
|
||||||
|
vod.put("vod_year", data.optString("vod_year"));
|
||||||
|
vod.put("vod_area", data.optString("vod_area"));
|
||||||
|
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||||
|
vod.put("vod_actor", data.optString("vod_actor"));
|
||||||
|
vod.put("vod_director", data.optString("vod_director"));
|
||||||
|
vod.put("vod_content", data.optString("vod_content"));
|
||||||
|
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_play_list");
|
||||||
|
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||||
|
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||||
|
String flag = from.getJSONObject("player_info").optString("from").trim();
|
||||||
|
if (flag.isEmpty())
|
||||||
|
flag = from.getJSONObject("player_info").optString("show").trim();
|
||||||
|
playFlags.add(flag);
|
||||||
|
playUrls.add(from.getString("url"));
|
||||||
|
try {
|
||||||
|
ArrayList<String> parses = new ArrayList<>();
|
||||||
|
String[] parse1 = from.getJSONObject("player_info").optString("parse").split(",");
|
||||||
|
String[] parse2 = from.getJSONObject("player_info").optString("parse2").split(",");
|
||||||
|
parses.addAll(Arrays.asList(parse1));
|
||||||
|
parses.addAll(Arrays.asList(parse2));
|
||||||
|
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||||
|
if (parseUrls == null) {
|
||||||
|
parseUrls = new ArrayList<>();
|
||||||
|
parseUrlMap.put(flag, parseUrls);
|
||||||
|
}
|
||||||
|
for (String purl : parses) {
|
||||||
|
if (purl.contains("http")) {
|
||||||
|
Matcher matcher = parsePattern1.matcher(purl);
|
||||||
|
if (matcher.find()) {
|
||||||
|
purl = matcher.group(0);
|
||||||
|
}
|
||||||
|
} else if (purl.contains("//")) {
|
||||||
|
Matcher matcher = parsePattern1.matcher(purl);
|
||||||
|
if (matcher.find()) {
|
||||||
|
purl = "http:" + matcher.group(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Matcher matcher = parsePattern2.matcher(URL);
|
||||||
|
if (matcher.find()) {
|
||||||
|
Matcher matcher1 = parsePattern1.matcher(URL);
|
||||||
|
if (matcher1.find()) {
|
||||||
|
purl = matcher.group(0) + matcher1.group(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
purl = purl.replace("..", ".").trim();
|
||||||
|
if (!purl.isEmpty() && !parseUrls.contains(purl))
|
||||||
|
parseUrls.add(purl);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (urlPattern1.matcher(URL).find()) {
|
||||||
|
JSONObject data = object;
|
||||||
|
vod.put("vod_id", data.optString("vod_id", vid));
|
||||||
|
vod.put("vod_name", data.getString("title"));
|
||||||
|
vod.put("vod_pic", data.getString("img_url"));
|
||||||
|
vod.put("type_name", jsonArr2Str(data.optJSONArray("type")));
|
||||||
|
vod.put("vod_year", data.optString("pubtime"));
|
||||||
|
vod.put("vod_area", jsonArr2Str(data.optJSONArray("area")));
|
||||||
|
vod.put("vod_remarks", data.optString("trunk"));
|
||||||
|
vod.put("vod_actor", jsonArr2Str(data.optJSONArray("actor")));
|
||||||
|
vod.put("vod_director", jsonArr2Str(data.optJSONArray("director")));
|
||||||
|
vod.put("vod_content", data.optString("intro"));
|
||||||
|
JSONObject playList = data.getJSONObject("videolist");
|
||||||
|
Iterator<String> playListKeys = playList.keys();
|
||||||
|
while (playListKeys.hasNext()) {
|
||||||
|
String flag = playListKeys.next();
|
||||||
|
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||||
|
if (parseUrls == null) {
|
||||||
|
parseUrls = new ArrayList<>();
|
||||||
|
parseUrlMap.put(flag, parseUrls);
|
||||||
|
}
|
||||||
|
JSONArray playListUrls = playList.getJSONArray(flag);
|
||||||
|
ArrayList<String> urls = new ArrayList<>();
|
||||||
|
for (int j = 0; j < playListUrls.length(); j++) {
|
||||||
|
JSONObject urlObj = playListUrls.getJSONObject(j);
|
||||||
|
String url = urlObj.getString("url");
|
||||||
|
if (url.contains("url=")) {
|
||||||
|
int spIdx = url.indexOf("url=") + 4;
|
||||||
|
String pUrl = url.substring(0, spIdx).trim();
|
||||||
|
if (!pUrl.isEmpty() && !parseUrls.contains(pUrl))
|
||||||
|
parseUrls.add(pUrl);
|
||||||
|
urls.add(urlObj.getString("title") + "$" + url.substring(spIdx).trim());
|
||||||
|
} else {
|
||||||
|
urls.add(urlObj.getString("title") + "$" + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playFlags.add(flag);
|
||||||
|
playUrls.add(TextUtils.join("#", urls));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vod.put("vod_play_from", TextUtils.join("$$$", playFlags));
|
||||||
|
vod.put("vod_play_url", TextUtils.join("$$$", playUrls));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ######视频地址
|
||||||
|
protected JSONObject getFinalVideo(String flag, ArrayList<String> parseUrls, String url) throws JSONException {
|
||||||
|
String htmlPlayUrl = "";
|
||||||
|
for (String parseUrl : parseUrls) {
|
||||||
|
if (parseUrl.isEmpty() || parseUrl.equals("null"))
|
||||||
|
continue;
|
||||||
|
String playUrl = parseUrl + url;
|
||||||
|
String content = desc(OkHttpUtil.string(playUrl, null), (byte) 4);
|
||||||
|
if (parseUrl.contains("49.233.47.42:9898")) {
|
||||||
|
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
OkHttpUtil.stringNoRedirect(playUrl,null, hashMap);
|
||||||
|
String d = OkHttpUtil.getRedirectLocation(hashMap);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", d);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
JSONObject tryJson = null;
|
||||||
|
try {
|
||||||
|
tryJson = Misc.jsonParse(url, content);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (tryJson != null && tryJson.has("url") && tryJson.has("header")) {
|
||||||
|
tryJson.put("header", tryJson.getJSONObject("header").toString());
|
||||||
|
return tryJson;
|
||||||
|
}
|
||||||
|
if (content.contains("<html")) {
|
||||||
|
boolean sniffer = false;
|
||||||
|
for (Pattern p : htmlVideoKeyMatch) {
|
||||||
|
if (p.matcher(content).find()) {
|
||||||
|
sniffer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sniffer) {
|
||||||
|
htmlPlayUrl = parseUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!htmlPlayUrl.isEmpty()) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", htmlPlayUrl);
|
||||||
|
result.put("url", url);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean manualVideoCheck() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVideoFormat(String url) {
|
||||||
|
return Misc.isVideoFormat(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getApiUrl() {
|
||||||
|
if (extInfos == null || extInfos.length < 1)
|
||||||
|
return "";
|
||||||
|
return extInfos[0].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] extInfos = null;
|
||||||
|
|
||||||
|
protected String desc(String src, byte type) {
|
||||||
|
if (extInfos.length > 1) {
|
||||||
|
String descFlag = extInfos[1];
|
||||||
|
if (descFlag.equals("nftv")) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,540 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Auete extends Spider {
|
||||||
|
private static final String siteUrl = "https://auete.com";
|
||||||
|
private static final String siteHost = "auete.com";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
//分类页URL规则
|
||||||
|
private Pattern regexCategory = Pattern.compile("/(\\w+)/index.html");
|
||||||
|
//详情页URL规则
|
||||||
|
private Pattern regexVid = Pattern.compile("/(\\w+/\\w+/\\w+)/");
|
||||||
|
//播放页URL规则
|
||||||
|
private Pattern regexPlay = Pattern.compile("(/\\w+/\\w+/\\w+/play-\\d+-\\d+.html)");
|
||||||
|
//筛选页URL规则
|
||||||
|
//private Pattern regexPage = Pattern.compile("/\\w+/\\w+/index(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("/index(\\d+).html");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"byun\":{\"sh\":\"云播B线\",\"pu\":\"\",\"sn\":0,\"or\":999},\"dphd\":{\"sh\":\"云播A线\",\"pu\":\"\",\"sn\":0,\"or\":999},\"cyun\":{\"sh\":\"云播C线\",\"pu\":\"\",\"sn\":0,\"or\":999},\"dbm3u8\":{\"sh\":\"云播D线\",\"pu\":\"\",\"sn\":0,\"or\":999},\"i8i\":{\"sh\":\"云播E线\",\"pu\":\"\",\"sn\":0,\"or\":999},\"m3u8hd\":{\"sh\":\"云播F线\",\"pu\":\"https://auete.com/api/?url=\",\"sn\":1,\"or\":999},\"languang\":{\"sh\":\"云播G线\",\"pu\":\"https://auete.com/api/?url=\",\"sn\":1,\"or\":999},\"hyun\":{\"sh\":\"云播H线\",\"pu\":\"https://auete.com/api/?url=\",\"sn\":1,\"or\":999},\"kyun\":{\"sh\":\"云播K线\",\"pu\":\"https://auete.com/api/?url=\",\"sn\":1,\"or\":999},\"bpyueyu\":{\"sh\":\"云播粤语\",\"pu\":\"\",\"sn\":0,\"or\":999},\"bpguoyu\":{\"sh\":\"云播国语\",\"pu\":\"\",\"sn\":0,\"or\":999},\"lyun\":{\"sh\":\"云播L线\",\"pu\":\"https://auete.com/api/?url=\",\"sn\":1,\"or\":999},\"myun\":{\"sh\":\"云播M线\",\"pu\":\"\",\"sn\":0,\"or\":999},\"dp\":{\"sh\":\"Dplayer\",\"pu\":\"\",\"sn\":0,\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"Movie\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧片\",\"v\":\"xjp\"},{\"n\":\"动作片\",\"v\":\"dzp\"},{\"n\":\"爱情片\",\"v\":\"aqp\"},{\"n\":\"科幻片\",\"v\":\"khp\"},{\"n\":\"恐怖片\",\"v\":\"kbp\"},{\"n\":\"惊悚片\",\"v\":\"jsp\"},{\"n\":\"战争片\",\"v\":\"zzp\"},{\"n\":\"剧情片\",\"v\":\"jqp\"}]}],\"Tv\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"美剧\",\"v\":\"oumei\"},{\"n\":\"韩剧\",\"v\":\"hanju\"},{\"n\":\"日剧\",\"v\":\"riju\"},{\"n\":\"泰剧\",\"v\":\"yataiju\"},{\"n\":\"网剧\",\"v\":\"wangju\"},{\"n\":\"台剧\",\"v\":\"taiju\"},{\"n\":\"国产\",\"v\":\"neidi\"},{\"n\":\"港剧\",\"v\":\"tvbgj\"}]}],\"Zy\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国综\",\"v\":\"guozong\"},{\"n\":\"韩综\",\"v\":\"hanzong\"},{\"n\":\"美综\",\"v\":\"meizong\"}]}],\"Dm\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"动画\",\"v\":\"donghua\"},{\"n\":\"日漫\",\"v\":\"riman\"},{\"n\":\"国漫\",\"v\":\"guoman\"},{\"n\":\"美漫\",\"v\":\"meiman\"}]}],\"qita\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"纪录片\",\"v\":\"Jlp\"},{\"n\":\"经典片\",\"v\":\"Jdp\"},{\"n\":\"经典剧\",\"v\":\"Jdj\"},{\"n\":\"网大电影\",\"v\":\"wlp\"},{\"n\":\"国产老电影\",\"v\":\"laodianying\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Host", siteHost);
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul[class='navbar-nav mr-auto']> li a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
//分类名
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = name.equals("电影") ||
|
||||||
|
name.equals("电视剧") ||
|
||||||
|
name.equals("综艺") ||
|
||||||
|
name.equals("动漫") ||
|
||||||
|
name.equals("其他");
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("ul.threadlist").get(0);
|
||||||
|
Elements list = homeList.select("li");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst("h2 a").attr("title");
|
||||||
|
String cover = vod.selectFirst("a img").attr("src");
|
||||||
|
String remark = vod.selectFirst("a button").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst("a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
// 获取分类数据的url
|
||||||
|
String url = "";
|
||||||
|
try {
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value != null && value.length() != 0 && value != " ") {
|
||||||
|
url = siteUrl + "/" + tid + "/" + value;
|
||||||
|
} else {
|
||||||
|
url = siteUrl + "/" + tid;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
url = siteUrl + "/" + tid;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
if (pg.equals("1")) {
|
||||||
|
url = url + "/index.html";
|
||||||
|
} else {
|
||||||
|
url = url + "/index" + pg + ".html";
|
||||||
|
}
|
||||||
|
//System.out.println(url);
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select("ul.pagination li");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
String name = a.text();
|
||||||
|
//System.out.println("名称"+name);
|
||||||
|
if (page == -1 && li.hasClass("active")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
//System.out.println("哈哈"+matcher.group(1));
|
||||||
|
page = Integer.parseInt(matcher.group(1));
|
||||||
|
} else {
|
||||||
|
Elements list = doc.select("ul.threadlist li");
|
||||||
|
if (list.size() > 0) {
|
||||||
|
page = 1;
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.equals("尾页")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
//System.out.println("尾页" + matcher.group(1));
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1));
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("ul.threadlist li");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst("h2 a").attr("title");
|
||||||
|
String cover = vod.selectFirst("a img").attr("src");
|
||||||
|
String remark = vod.selectFirst("a button").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst("a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 20);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 20);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/" + ids.get(0) + "/";
|
||||||
|
//System.out.println(url);
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
String cover = doc.selectFirst("div.cover a").attr("href");
|
||||||
|
String title = doc.selectFirst("div.cover a").attr("title");
|
||||||
|
Elements list1 = doc.select("div.message>p");
|
||||||
|
String desc = doc.select("div.message>p").get(list1.size() - 1).text();
|
||||||
|
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||||
|
Elements span_text_muted = doc.select("div.message>p");
|
||||||
|
for (int i = 0; i < span_text_muted.size() - 2; i++) {
|
||||||
|
Element text = span_text_muted.get(i);
|
||||||
|
String info = text.text();
|
||||||
|
if (info.contains("分类")) {
|
||||||
|
try {
|
||||||
|
category = text.text().split(": ")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
category = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("年份")) {
|
||||||
|
try {
|
||||||
|
year = text.text().split(": ")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
year = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("地区")) {
|
||||||
|
try {
|
||||||
|
area = text.text().split(": ")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
area = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("影片备注")) {
|
||||||
|
try {
|
||||||
|
remark = text.text().split(": ")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
remark = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("导演")) {
|
||||||
|
try {
|
||||||
|
director = text.text().split(": ")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
director = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("主演")) {
|
||||||
|
try {
|
||||||
|
actor = text.text().split(": ")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
actor = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vodList.put("vod_id", ids.get(0));
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
//System.out.println(vodList.toString());
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div#player_list>h2");
|
||||||
|
//System.out.println(sources.size());
|
||||||
|
Elements sourceList = doc.select("div#player_list>ul");
|
||||||
|
//System.out.println(sourceList.size());
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
//System.out.println(sources.text().split(":")[0].split("』")[1]);
|
||||||
|
String sourceName = source.text().split("』")[1].split(":")[0];
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = flag;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("li > a");
|
||||||
|
//System.out.println(playListA.size());
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + id;
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
/*取得script下面的JS变量*/
|
||||||
|
Elements e = doc.select("div>script");
|
||||||
|
/*循环遍历script下面的JS变量*/
|
||||||
|
String player = "";
|
||||||
|
String pn = "";
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (Element element : e) {
|
||||||
|
/*取得JS变量数组*/
|
||||||
|
String[] data = element.data().toString().split("var");
|
||||||
|
/*取得单个JS变量*/
|
||||||
|
for (String variable : data) {
|
||||||
|
/*过滤variable为空的数据*/
|
||||||
|
if (variable.contains("=")) {
|
||||||
|
/*取到满足条件的JS变量*/
|
||||||
|
if (variable.contains("now")) {
|
||||||
|
String[] kvp = variable.split("=");
|
||||||
|
player = kvp[1].replaceAll("\"", "").replaceAll(";", "");
|
||||||
|
if (player.startsWith("base64")) {
|
||||||
|
String[] plist1 = player.split("\\(");
|
||||||
|
String[] plist2 = plist1[1].split("\\)");
|
||||||
|
// 解码
|
||||||
|
player = new String(Base64.decode(plist2[0].getBytes(), Base64.DEFAULT));
|
||||||
|
//byte[] base64Data = Base64.getDecoder().decode(plist2[0]);
|
||||||
|
//player = new String(base64Data, "utf-8");
|
||||||
|
}
|
||||||
|
if (player.startsWith("http")) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", player);
|
||||||
|
result.put("header", "");
|
||||||
|
} else if (player.contains("m3u8")) {
|
||||||
|
String finalvideo = "https://datas-s8pwfqdu9yystn90fb----------------cache.haozhansou.com/" + player;
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", finalvideo);
|
||||||
|
result.put("header", "");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (variable.contains("pn")) {
|
||||||
|
String[] kvp = variable.split("=");
|
||||||
|
pn = kvp[1].replaceAll("\"", "").replaceAll(";", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (playerConfig.has(pn)) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(pn);
|
||||||
|
String videoUrl = player;
|
||||||
|
String playUrl = pCfg.getString("pu");
|
||||||
|
result.put("parse", pCfg.getInt("sn"));
|
||||||
|
result.put("playUrl", playUrl);
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
result.put("header", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param quick 是否播放页的快捷搜索
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/search.php?searchword=" + key;
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
Elements list = doc.select("div.card-body>ul>li.media");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.select("div.media-body>div.subject>a>span").text();
|
||||||
|
String cover = "";
|
||||||
|
String remark = vod.selectFirst("div.media-body>div.d-flex>div.text-muted>span").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.select("div.media-body>div.subject>a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
|
||||||
|
// 视频封面
|
||||||
|
String vodurl = siteUrl + "/" + id + "/";
|
||||||
|
Document voddoc = Jsoup.parse(OkHttpUtil.string(vodurl, getHeaders(vodurl)));
|
||||||
|
cover = voddoc.selectFirst("div.cover a").attr("href");
|
||||||
|
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,273 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Bili extends Spider {
|
||||||
|
|
||||||
|
protected JSONObject ext = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
try {
|
||||||
|
String content = OkHttpUtil.string(extend, null);
|
||||||
|
ext = new JSONObject(content);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
JSONObject results = new JSONObject();
|
||||||
|
try {
|
||||||
|
results.put("class", ext.getJSONArray("classes"));
|
||||||
|
if (filter) {
|
||||||
|
results.put("filters", ext.getJSONObject("filter"));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return results.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
try {
|
||||||
|
String url = "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=窗 白噪音";
|
||||||
|
String content = OkHttpUtil.string(url, null);
|
||||||
|
JSONObject data = new JSONObject(content).getJSONObject("data");
|
||||||
|
JSONArray RArray = data.getJSONArray("result");
|
||||||
|
for (int i = 0; i < RArray.length(); i++) {
|
||||||
|
JSONObject info = RArray.getJSONObject(i);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
String pic = info.getString("pic");
|
||||||
|
if (pic.startsWith("//")) {
|
||||||
|
pic = "https:" + pic;
|
||||||
|
}
|
||||||
|
result.put("vod_id", info.getString("bvid"));
|
||||||
|
String title = info.getString("title");
|
||||||
|
Document KS = Jsoup.parse(title);
|
||||||
|
String name = KS.text();
|
||||||
|
result.put("vod_name", name);
|
||||||
|
result.put("vod_pic", pic);
|
||||||
|
String duration = info.getString("duration");
|
||||||
|
String words = duration.split(":")[0];
|
||||||
|
String remark = words + "分钟";
|
||||||
|
result.put("vod_remarks", remark);
|
||||||
|
videos.put(result);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String url = "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=";
|
||||||
|
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||||
|
url += extend.get("tid");
|
||||||
|
} else {
|
||||||
|
url += tid;
|
||||||
|
}
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
url += "&" + key + "=" + URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url += "&page=" + pg;
|
||||||
|
String content = OkHttpUtil.string(url, null);
|
||||||
|
JSONObject data = new JSONObject(content).getJSONObject("data");
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
JSONArray RSArray = data.getJSONArray("result");
|
||||||
|
for (int i = 0; i < RSArray.length(); i++) {
|
||||||
|
JSONObject info = RSArray.getJSONObject(i);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
String pic = info.getString("pic");
|
||||||
|
if (pic.startsWith("//")) {
|
||||||
|
pic = "https:" + pic;
|
||||||
|
}
|
||||||
|
result.put("vod_id", info.getString("bvid"));
|
||||||
|
String title = info.getString("title");
|
||||||
|
Document doc = Jsoup.parse(title);
|
||||||
|
String name = doc.text();
|
||||||
|
result.put("vod_name", name);
|
||||||
|
result.put("vod_pic", pic);
|
||||||
|
String duration = info.getString("duration");
|
||||||
|
String Split = duration.split(":")[0];
|
||||||
|
String remark = Split + "分钟";
|
||||||
|
result.put("vod_remarks", remark);
|
||||||
|
list.put(result);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int limit = 20;
|
||||||
|
int page = Integer.parseInt(pg);
|
||||||
|
result.put("page", page);
|
||||||
|
int pageCount = list.length() == limit ? page + 1 : page;
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", limit);
|
||||||
|
result.put("total", Integer.MAX_VALUE);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
int i = 0;
|
||||||
|
try {
|
||||||
|
String str = ids.get(0);
|
||||||
|
String sb2 = "https://api.bilibili.com/x/web-interface/archive/stat?bvid=" + str;
|
||||||
|
JSONObject jSONObject = new JSONObject(OkHttpUtil.string(sb2, null));
|
||||||
|
JSONObject jSONObject2 = jSONObject.getJSONObject("data");
|
||||||
|
long j = jSONObject2.getLong("aid");
|
||||||
|
String sb4 = j + "";
|
||||||
|
String sb6 = "https://api.bilibili.com/x/web-interface/view?aid=" + sb4;
|
||||||
|
JSONObject jSONObject3 = new JSONObject(OkHttpUtil.string(sb6, null));
|
||||||
|
JSONObject jSONObject4 = jSONObject3.getJSONObject("data");
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", str);
|
||||||
|
String string = jSONObject4.getString("title");
|
||||||
|
v.put("vod_name", string);
|
||||||
|
String string2 = jSONObject4.getString("pic");
|
||||||
|
v.put("vod_pic", string2);
|
||||||
|
String string3 = jSONObject4.getString("tname");
|
||||||
|
v.put("type_name", string3);
|
||||||
|
v.put("vod_year", "");
|
||||||
|
v.put("vod_area", "");
|
||||||
|
String sb7 = jSONObject4.getLong("duration") / 60 + "分钟";
|
||||||
|
v.put("vod_remarks", sb7);
|
||||||
|
v.put("vod_actor", "");
|
||||||
|
v.put("vod_director", "");
|
||||||
|
String string4 = jSONObject4.getString("desc");
|
||||||
|
v.put("vod_content", string4);
|
||||||
|
v.put("vod_play_from", "B站");
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
JSONArray jSONArray = jSONObject4.getJSONArray("pages");
|
||||||
|
while (true) {
|
||||||
|
int length = jSONArray.length();
|
||||||
|
if (i < length) {
|
||||||
|
JSONObject jSONObject6 = jSONArray.getJSONObject(i);
|
||||||
|
String string5 = jSONObject6.getString("part");
|
||||||
|
String replace = string5.replace("$", "_").replace("#", "_");
|
||||||
|
StringBuilder sb8 = new StringBuilder();
|
||||||
|
sb8.append(replace);
|
||||||
|
sb8.append("$");
|
||||||
|
sb8.append(sb4);
|
||||||
|
sb8.append("+ ");
|
||||||
|
long j2 = jSONObject6.getLong("cid");
|
||||||
|
sb8.append(j2);
|
||||||
|
String sb9 = sb8.toString();
|
||||||
|
arrayList.add(sb9);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
v.put("vod_play_url", TextUtils.join("#", arrayList));
|
||||||
|
JSONArray jSONArray2 = new JSONArray();
|
||||||
|
jSONArray2.put(v);
|
||||||
|
JSONObject jSONObject7 = new JSONObject();
|
||||||
|
jSONObject7.put("list", jSONArray2);
|
||||||
|
return jSONObject7.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
try {
|
||||||
|
String[] split = str2.split("\\+");
|
||||||
|
String str3 = split[0];
|
||||||
|
String str4 = split[1];
|
||||||
|
String sb2 = "https://api.bilibili.com/x/player/playurl?avid=" + str3 + "&cid= " + str4 + "&qn=120&fourk=1";
|
||||||
|
JSONObject jSONObject = new JSONObject(OkHttpUtil.string(sb2, null));
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("parse", "0");
|
||||||
|
jSONObject2.put("playUrl", "");
|
||||||
|
JSONObject jSONObject3 = jSONObject.getJSONObject("data");
|
||||||
|
JSONObject jSONObject4 = jSONObject3.getJSONArray("durl").getJSONObject(0);
|
||||||
|
String string = jSONObject4.getString("url");
|
||||||
|
jSONObject2.put("url", string);
|
||||||
|
jSONObject2.put("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\"}");
|
||||||
|
jSONObject2.put("contentType", "video/x-flv");
|
||||||
|
return jSONObject2.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
String url = "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=" + URLEncoder.encode(key);
|
||||||
|
String content = OkHttpUtil.string(url, null);
|
||||||
|
JSONObject data = new JSONObject(content).getJSONObject("data");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
JSONArray RSArray = data.getJSONArray("result");
|
||||||
|
for (int i = 0; i < RSArray.length(); i++) {
|
||||||
|
JSONObject info = RSArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
String pic = info.getString("pic");
|
||||||
|
if (pic.startsWith("//")) {
|
||||||
|
pic = "https:" + pic;
|
||||||
|
}
|
||||||
|
v.put("vod_id", info.getString("bvid"));
|
||||||
|
String title = info.getString("title");
|
||||||
|
Document doc = Jsoup.parse(title);
|
||||||
|
String name = doc.text();
|
||||||
|
v.put("vod_name", name);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
String duration = info.getString("duration");
|
||||||
|
String Split = duration.split(":")[0];
|
||||||
|
String remark = Split + "分钟";
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,467 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import okhttp3.Headers;
|
||||||
|
|
||||||
|
public class Cokemv extends Spider {
|
||||||
|
private static final String siteUrl = "https://cokemv.me";
|
||||||
|
private static final String siteHost = "cokemv.me";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/vodtype/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/voddetail/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/vodplay/(\\d+)-(\\d+)-(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("/vodshow/(\\S+).html");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"cokemv0555\":{\"sh\":\"COKEMV\",\"pu\":\"\",\"sn\":0,\"or\":999},\"cokeqie01\":{\"sh\":\"極速路線\",\"pu\":\"\",\"sn\":0,\"or\":999},\"xin\":{\"sh\":\"高速路線\",\"pu\":\"\",\"sn\":0,\"or\":999},\"90mm\":{\"sh\":\"藍光號路\",\"pu\":\"\",\"sn\":0,\"or\":999},\"age01\":{\"sh\":\"動漫一線\",\"pu\":\"\",\"sn\":0,\"or\":999},\"age02\":{\"sh\":\"動漫二線\",\"pu\":\"\",\"sn\":0,\"or\":999},\"mahua\":{\"sh\":\"海外(禁國內)\",\"pu\":\"\",\"sn\":0,\"or\":999},\"toutiao\":{\"sh\":\"蓝光不卡\",\"pu\":\"\",\"sn\":0,\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"5\":[{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜劇\"},{\"n\":\"爱情\",\"v\":\"愛情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"動作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"劇情\"},{\"n\":\"战争\",\"v\":\"戰爭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"動畫\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"悬疑\",\"v\":\"懸疑\"},{\"n\":\"微电影\",\"v\":\"微電影\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"國語\"},{\"n\":\"英语\",\"v\":\"英語\"},{\"n\":\"粤语\",\"v\":\"粵語\"},{\"n\":\"闽南语\",\"v\":\"閩南語\"},{\"n\":\"韩语\",\"v\":\"韓語\"},{\"n\":\"日语\",\"v\":\"日語\"},{\"n\":\"法语\",\"v\":\"法語\"},{\"n\":\"德语\",\"v\":\"德語\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"2\"},{\"n\":\"大陆剧\",\"v\":\"13\"},{\"n\":\"香港剧\",\"v\":\"14\"},{\"n\":\"韩国剧\",\"v\":\"15\"},{\"n\":\"欧美剧\",\"v\":\"16\"},{\"n\":\"日本剧\",\"v\":\"20\"},{\"n\":\"台湾剧\",\"v\":\"21\"},{\"n\":\"泰国剧\",\"v\":\"22\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"1\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"1\"},{\"n\":\"动作片\",\"v\":\"6\"},{\"n\":\"喜剧片\",\"v\":\"7\"},{\"n\":\"爱情片\",\"v\":\"8\"},{\"n\":\"科幻片\",\"v\":\"9\"},{\"n\":\"恐怖片\",\"v\":\"10\"},{\"n\":\"剧情片\",\"v\":\"11\"},{\"n\":\"战争片\",\"v\":\"12\"},{\"n\":\"犯罪片\",\"v\":\"23\"},{\"n\":\"奇幻片\",\"v\":\"24\"},{\"n\":\"悬疑片\",\"v\":\"25\"},{\"n\":\"记录片\",\"v\":\"27\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"4\"},{\"n\":\"动画电影\",\"v\":\"41\"}]},{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"韩国\",\"v\":\"韩国\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
headers.put("Referer", siteUrl);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Host", siteHost);
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul.navbar-items>li.navbar-item>a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = name.equals("抖音电影") ||
|
||||||
|
name.equals("电视剧") ||
|
||||||
|
name.equals("电影") ||
|
||||||
|
name.equals("动漫") ||
|
||||||
|
name.equals("综艺");
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("div.module-main").get(0);
|
||||||
|
Elements list = homeList.select("div.module-items>a");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.attr("title");
|
||||||
|
String cover = vod.selectFirst("img.lazyload").attr("data-original");
|
||||||
|
String remark = vod.selectFirst("div.module-item-note").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||||
|
urlParams[0] = tid;
|
||||||
|
urlParams[8] = pg;
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取分类数据的url
|
||||||
|
String url = siteUrl + "/vodshow/" + TextUtils.join("-", urlParams) + ".html";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select("div[id=page]");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
String span = doc.select("span.page-current").text();
|
||||||
|
String wy = doc.select("div[id=page] a").last().attr("href");
|
||||||
|
if (page == -1) {
|
||||||
|
page = Integer.parseInt(span);
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
Matcher matcher = regexPage.matcher(wy);
|
||||||
|
if (matcher.find()) {
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("div.module-main>div.module-items>a");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.attr("title");
|
||||||
|
String cover = vod.selectFirst("img.lazyload").attr("data-original");
|
||||||
|
String remark = vod.selectFirst("div.module-item-note").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 48);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/voddetail/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, Headers()));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
Elements sourcediv = doc.select("div.module-item-cover>div");
|
||||||
|
String cover = sourcediv.get(0).select("div.module-item-pic>img").attr("data-original");
|
||||||
|
String title = sourcediv.get(0).select("div.module-item-pic>img").attr("alt");
|
||||||
|
String category = "", area = "", year = "", remark = "", director = "", actor = "", desc = "";
|
||||||
|
Elements data = doc.select("div.module-info-tag-link");
|
||||||
|
category = data.get(2).select("a").text();
|
||||||
|
area = data.get(1).select("a").text();
|
||||||
|
year = data.get(0).select("a").text();
|
||||||
|
remark = doc.select("div.module-info-item-content").get(4).text();
|
||||||
|
List<String> actors = new ArrayList<>();
|
||||||
|
Elements aa = doc.select("div.module-info-item-content").get(2).select("a");
|
||||||
|
for (int j = 0; j < aa.size(); j++) {
|
||||||
|
actors.add(aa.get(j).text());
|
||||||
|
}
|
||||||
|
actor = TextUtils.join(",", actors);
|
||||||
|
List<String> directors = new ArrayList<>();
|
||||||
|
Elements bb = doc.select("div.module-info-item-content").get(0).select("a");
|
||||||
|
for (int j = 0; j < bb.size(); j++) {
|
||||||
|
directors.add(bb.get(j).text());
|
||||||
|
}
|
||||||
|
director = TextUtils.join(",", directors);
|
||||||
|
desc = doc.selectFirst("div.module-info-introduction-content>p").text().trim();
|
||||||
|
|
||||||
|
vodList.put("vod_id", ids.get(0));
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.module-tab-items-box>div>span");
|
||||||
|
Elements sourceList = doc.select("div.module-list>div.module-play-list");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.text();
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = playerConfig.getJSONObject(flag).getString("sh");
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("div.module-play-list-content>a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
//定义播放用的headers
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
//headers.put("Host", " cokemv.co");
|
||||||
|
headers.put("origin", " https://cokemv.me");
|
||||||
|
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", " */*");
|
||||||
|
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||||
|
headers.put("Accept-Encoding", " gzip, deflate");
|
||||||
|
|
||||||
|
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + "/vodplay/" + id + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) { // 取直链
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
String videoUrl = player.getString("url");
|
||||||
|
String playUrl = pCfg.getString("pu");
|
||||||
|
result.put("parse", pCfg.getInt("sn"));
|
||||||
|
result.put("playUrl", playUrl);
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
result.put("header", headers.toString());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String, String> sHeaders() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
|
||||||
|
headers.put("Accept-encoding", "gzip, deflate, br");
|
||||||
|
headers.put("Accept-language", "zh-SG,zh;q=0.9,en-GB;q=0.8,en;q=0.7,zh-CN;q=0.6");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String url = "https://shitu.paodekuaiweixinqun.com/search?q=site%3Acokemv.me%2Fvoddetail+" + URLEncoder.encode(key);
|
||||||
|
Document docs = Jsoup.parse(OkHttpUtil.string(url, sHeaders()));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
Elements list = docs.select("div.NJo7tc div.yuRUbf");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element doc = list.get(i);
|
||||||
|
String sourceName = doc.select("div.yuRUbf a h3").text();
|
||||||
|
if (sourceName.contains(key)) {
|
||||||
|
String list1 = doc.select("div.yuRUbf a").attr("href");
|
||||||
|
Document link = Jsoup.parse(OkHttpUtil.string(list1, getHeaders(url)));
|
||||||
|
Matcher matcher = regexVid.matcher(list1);
|
||||||
|
if (matcher.find()) {
|
||||||
|
|
||||||
|
String group = matcher.group(1);
|
||||||
|
String cover = link.select("div.module-item-pic>img").attr("data-original");
|
||||||
|
String title = link.select("div.module-item-pic>img").attr("alt");
|
||||||
|
String remark = link.select("div.module-info-item-content").get(4).text();
|
||||||
|
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
v.put("vod_id", group);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,435 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.AES;
|
||||||
|
import com.github.catvod.utils.CBC;
|
||||||
|
import com.github.catvod.utils.gZip;
|
||||||
|
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
public class Czsapp extends Spider {
|
||||||
|
private static final Pattern Y = Pattern.compile("\"([^\"]+)\";var [\\d\\w]+=function dncry.*md5.enc.Utf8.parse\\(\"([\\d\\w]+)\".*md5.enc.Utf8.parse\\(([\\d]+)\\)");
|
||||||
|
private static final Pattern pY = Pattern.compile("video: \\{url: \"([^\"]+)\"");
|
||||||
|
private static final Pattern m = Pattern.compile("subtitle: \\{url:\"([^\"]+\\.vtt)\"");
|
||||||
|
private static final Pattern Q = Pattern.compile("src: '([^']+\\.css)',");
|
||||||
|
private static final Pattern Db = Pattern.compile("/movie/(\\d+).html");
|
||||||
|
private static final Pattern I = Pattern.compile("/page/(\\d+)");
|
||||||
|
private static final Pattern d = Pattern.compile("/v_play/(.*)\\.html");
|
||||||
|
private static final Pattern K = Pattern.compile("var vkey = ['\"]([^'\"]+)['\"]");
|
||||||
|
private static final Pattern Oe = Pattern.compile("var fvkey = ['\"]([^'\"]+)['\"]");
|
||||||
|
private static final Pattern fi = Pattern.compile("var ua = ['\"]([^'\"]+)['\"]");
|
||||||
|
private static final Pattern M = Pattern.compile("var cip = ['\"]([^'\"]+)['\"]");
|
||||||
|
private static final Pattern X = Pattern.compile("var time = ['\"]([^'\"]+)['\"]");
|
||||||
|
private static final Pattern a = Pattern.compile("var url = ['\"]([^'\"]+)['\"]");
|
||||||
|
|
||||||
|
|
||||||
|
private String mmd5(String str) {
|
||||||
|
try {
|
||||||
|
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
|
||||||
|
messageDigest.update(str.getBytes());
|
||||||
|
byte[] digest = messageDigest.digest();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte b : digest) {
|
||||||
|
String hexString = Integer.toHexString(b & 255);
|
||||||
|
while (hexString.length() < 2) {
|
||||||
|
hexString = "0" + hexString;
|
||||||
|
}
|
||||||
|
sb.append(hexString);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] loadsub(String sub) {
|
||||||
|
try {
|
||||||
|
OKCallBack.OKCallBackDefault callBack = new OKCallBack.OKCallBackDefault() {
|
||||||
|
@Override
|
||||||
|
protected void onFailure(Call call, Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResponse(Response response) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OkHttpClient YM = OkHttpUtil.defaultClient();
|
||||||
|
OkHttpUtil.get(YM, sub, null, Headers(), callBack);
|
||||||
|
Response result = callBack.getResult();
|
||||||
|
int code = result.code();
|
||||||
|
if (code == 404) {
|
||||||
|
return new Object[]{200, "application/octet-stream", new ByteArrayInputStream("WEBVTT".getBytes())};
|
||||||
|
}
|
||||||
|
ResponseBody body = result.body();
|
||||||
|
byte[] bytes = body.bytes();
|
||||||
|
byte[] tokenkey = Arrays.copyOfRange(bytes, 0, 16);
|
||||||
|
byte[] data = Arrays.copyOfRange(bytes, 16, bytes.length);
|
||||||
|
byte[] KS = CBC.CBC(data, tokenkey, tokenkey);
|
||||||
|
String vtt = gZip.KS(KS);
|
||||||
|
|
||||||
|
|
||||||
|
vtt = vtt.replaceAll("(\\d{2}:\\d{2}:\\d{2}.\\d{3}.+\\d{2}:\\d{2}:\\d{2}.\\d{3}).*", "$1");
|
||||||
|
vtt = vtt.replaceAll("(\\d{2}:\\d{2}.\\d{3}).*?( --> )(\\d{2}:\\d{2}.\\d{3}).*", "00:$1$200:$3");
|
||||||
|
vtt = vtt.replaceAll("<.*><.*>(.*)<.*><.*>", "$1");
|
||||||
|
vtt = vtt.replaceAll("&(.*);", "");
|
||||||
|
vtt = vtt.replaceAll(".*NOTE.*", "");
|
||||||
|
BufferedReader br = new BufferedReader(new StringReader(vtt));
|
||||||
|
ArrayList<String> lines = new ArrayList<>();
|
||||||
|
int captionNumber = 1;
|
||||||
|
String line = br.readLine();
|
||||||
|
while (line != null) {
|
||||||
|
if (line.matches("\\d{2}:\\d{2}:\\d{2}.\\d{3}.+\\d{2}:\\d{2}:\\d{2}.\\d{3}")) {
|
||||||
|
if (lines.get(lines.size() - 1).trim().isEmpty()) {
|
||||||
|
lines.add(captionNumber + "");
|
||||||
|
captionNumber++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines.add(line);
|
||||||
|
line = br.readLine();
|
||||||
|
}
|
||||||
|
String join = TextUtils.join("\n", lines);
|
||||||
|
|
||||||
|
return new Object[]{200, "application/octet-stream", new ByteArrayInputStream(join.getBytes())};
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String categoryContent(String str, String str2, boolean z, HashMap<String, String> hashMap) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string("https://czspp.com/" + str + "/page/" + str2, Headers()));
|
||||||
|
int parseInt = Integer.parseInt(str2);
|
||||||
|
int parseInt2 = Integer.parseInt(str2);
|
||||||
|
Matcher matcher = I.matcher(doc.select("div.pagenavi_txt > a.extend").last().attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
parseInt2 = Integer.parseInt(matcher.group(1));
|
||||||
|
}
|
||||||
|
Elements jS = doc.select("div.mi_ne_kd > ul > li");
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
for (Element next : jS) {
|
||||||
|
Matcher matcher2 = Db.matcher(next.select("a").attr("href"));
|
||||||
|
if (matcher2.find()) {
|
||||||
|
String group = matcher2.group(1);
|
||||||
|
String trim = next.select("img").attr("alt").trim();
|
||||||
|
String trim2 = next.select("img").attr("data-original").trim();
|
||||||
|
String trim3 = next.select("div.hdinfo > span").text().trim();
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("vod_id", group);
|
||||||
|
jSONObject2.put("vod_name", trim);
|
||||||
|
jSONObject2.put("vod_pic", trim2);
|
||||||
|
jSONObject2.put("vod_remarks", trim3);
|
||||||
|
jSONArray.put(jSONObject2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jSONObject.put("list", jSONArray);
|
||||||
|
jSONObject.put("page", parseInt);
|
||||||
|
jSONObject.put("pagecount", parseInt2);
|
||||||
|
jSONObject.put("limit", 24);
|
||||||
|
jSONObject.put("total", parseInt2 <= 1 ? jSONArray.length() : parseInt2 * 24);
|
||||||
|
return jSONObject.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String detailContent(List<String> list) {
|
||||||
|
String str2 = "";
|
||||||
|
try {
|
||||||
|
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string("https://czspp.com/movie/" + list.get(0) + ".html", Headers()));
|
||||||
|
String trim = doc.select("div.moviedteail_tt > h1").text().trim();
|
||||||
|
String pY2 = doc.select("div.dyimg > img").attr("src");
|
||||||
|
Iterator<Element> it = doc.select("ul.moviedteail_list > li").iterator();
|
||||||
|
String str3 = str2;
|
||||||
|
String str4 = str3;
|
||||||
|
String str5 = str4;
|
||||||
|
String str6 = str5;
|
||||||
|
String str7 = str6;
|
||||||
|
String str8 = str7;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
String trim2 = it.next().text().trim();
|
||||||
|
if (trim2.length() >= 4) {
|
||||||
|
try {
|
||||||
|
String substring = trim2.substring(0, 2);
|
||||||
|
String substring2 = trim2.substring(3);
|
||||||
|
if (substring.equals("类型")) {
|
||||||
|
str3 = substring2;
|
||||||
|
} else if (substring.equals("地区")) {
|
||||||
|
str5 = substring2;
|
||||||
|
} else if (substring.equals("年份")) {
|
||||||
|
str4 = substring2;
|
||||||
|
} else if (substring.equals("导演")) {
|
||||||
|
str8 = substring2;
|
||||||
|
} else if (substring.equals("主演")) {
|
||||||
|
str7 = substring2;
|
||||||
|
} else if (substring.equals("豆瓣")) {
|
||||||
|
str6 = substring2;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jSONObject2.put("vod_id", list.get(0));
|
||||||
|
jSONObject2.put("vod_name", trim);
|
||||||
|
jSONObject2.put("vod_pic", pY2);
|
||||||
|
jSONObject2.put("type_name", str3);
|
||||||
|
jSONObject2.put("vod_year", str4);
|
||||||
|
jSONObject2.put("vod_area", str5);
|
||||||
|
jSONObject2.put("vod_remarks", str6);
|
||||||
|
jSONObject2.put("vod_actor", str7);
|
||||||
|
jSONObject2.put("vod_director", str8);
|
||||||
|
jSONObject2.put("vod_content", doc.select("div.yp_context").text().trim());
|
||||||
|
jSONObject2.put("vod_play_from", "厂长资源");
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
for (Element next : doc.select("div.paly_list_btn > a")) {
|
||||||
|
Matcher matcher = d.matcher(next.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
arrayList.add(next.text() + "$" + matcher.group(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jSONObject2.put("vod_play_url", TextUtils.join("#", arrayList));
|
||||||
|
jSONArray.put(jSONObject2);
|
||||||
|
jSONObject.put("list", jSONArray);
|
||||||
|
return jSONObject.toString();
|
||||||
|
} catch (Exception e3) {
|
||||||
|
}return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String homeContent(boolean z) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string("https://czspp.com", Headers()));
|
||||||
|
Elements jS = doc.select(".navlist > li > a");
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
for (Element next : jS) {
|
||||||
|
String pY2 = next.attr("href");
|
||||||
|
if (pY2.length() > 1) {
|
||||||
|
String substring = pY2.substring(1);
|
||||||
|
String trim = next.text().trim();
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("type_id", substring);
|
||||||
|
jSONObject2.put("type_name", trim);
|
||||||
|
jSONArray.put(jSONObject2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jSONObject.put("class", jSONArray);
|
||||||
|
Elements jS2 = doc.select("div.mi_ne_kd > ul > li");
|
||||||
|
JSONArray jSONArray2 = new JSONArray();
|
||||||
|
for (Element next2 : jS2) {
|
||||||
|
Matcher matcher = Db.matcher(next2.select("a").attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
String group = matcher.group(1);
|
||||||
|
String trim2 = next2.select("img").attr("alt").trim();
|
||||||
|
String trim3 = next2.select("img").attr("data-original").trim();
|
||||||
|
String trim4 = next2.select("div.hdinfo > span").text().trim();
|
||||||
|
JSONObject jSONObject3 = new JSONObject();
|
||||||
|
jSONObject3.put("vod_id", group);
|
||||||
|
jSONObject3.put("vod_name", trim2);
|
||||||
|
jSONObject3.put("vod_pic", trim3);
|
||||||
|
jSONObject3.put("vod_remarks", trim4);
|
||||||
|
jSONArray2.put(jSONObject3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jSONObject.put("list", jSONArray2);
|
||||||
|
return jSONObject.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> hashMap = new HashMap<>();
|
||||||
|
hashMap.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36");
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
String str3;
|
||||||
|
String str4;
|
||||||
|
Elements G8;
|
||||||
|
try {
|
||||||
|
String K2 = OkHttpUtil.string("https://czspp.com/v_play/" + str2 + ".html", Headers());
|
||||||
|
Document UR = Jsoup.parse(K2);
|
||||||
|
Matcher matcher = Y.matcher(K2);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String group = matcher.group(1);
|
||||||
|
String KEY = matcher.group(2);
|
||||||
|
String IV = matcher.group(3);
|
||||||
|
String str5 = AES.CBC(group, KEY, IV);
|
||||||
|
Matcher matcher2 = pY.matcher(str5);
|
||||||
|
str3 = matcher2.find() ? matcher2.group(1) : "";
|
||||||
|
Matcher matcher3 = m.matcher(str5);
|
||||||
|
str4 = matcher3.find() ? matcher3.group(1) : "";
|
||||||
|
} else {
|
||||||
|
str4 = "";
|
||||||
|
str3 = str4;
|
||||||
|
}
|
||||||
|
if (TextUtils.isEmpty(str3) && (G8 = UR.select("iframe.viframe")) != null) {
|
||||||
|
String pY2 = G8.attr("src");
|
||||||
|
if (pY2.contains("jx.xmflv.com")) {
|
||||||
|
String K3 = OkHttpUtil.string(pY2, Headers());
|
||||||
|
Matcher matcher4 = X.matcher(K3);
|
||||||
|
if (!matcher4.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group2 = matcher4.group(1);
|
||||||
|
Matcher matcher5 = a.matcher(K3);
|
||||||
|
if (!matcher5.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group3 = matcher5.group(1);
|
||||||
|
String K4 = OkHttpUtil.string("https://jx.xmflv.com/player.php?time=" + group2 + "&url=" + group3, Headers());
|
||||||
|
Matcher matcher6 = K.matcher(K4);
|
||||||
|
if (!matcher6.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group4 = matcher6.group(1);
|
||||||
|
Matcher matcher7 = Oe.matcher(K4);
|
||||||
|
if (!matcher7.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group5 = matcher7.group(1);
|
||||||
|
Matcher matcher8 = fi.matcher(K4);
|
||||||
|
if (!matcher8.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group6 = matcher8.group(1);
|
||||||
|
Matcher matcher9 = M.matcher(K4);
|
||||||
|
if (!matcher9.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group7 = matcher9.group(1);
|
||||||
|
Matcher matcher10 = X.matcher(K4);
|
||||||
|
if (!matcher10.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group8 = matcher10.group(1);
|
||||||
|
byte[] bytes3 = mmd5(group5).getBytes();
|
||||||
|
byte[] bytes4 = "UVE1NTY4MDY2NQ==".getBytes();
|
||||||
|
Cipher cipher2 = Cipher.getInstance("AES/CBC/NoPadding");
|
||||||
|
cipher2.init(1, new SecretKeySpec(bytes3, "AES"), new IvParameterSpec(bytes4));
|
||||||
|
String encodeToString = Base64.encodeToString(cipher2.doFinal(group5.getBytes()), 0);
|
||||||
|
OKCallBack.OKCallBackDefault callBack = new OKCallBack.OKCallBackDefault() {
|
||||||
|
|
||||||
|
public void onResponse(Response response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
hashMap.put("url", group3);
|
||||||
|
hashMap.put("time", group8);
|
||||||
|
hashMap.put("ua", group6);
|
||||||
|
hashMap.put("cip", group7);
|
||||||
|
hashMap.put("vkey", group4);
|
||||||
|
hashMap.put("fvkey", encodeToString);
|
||||||
|
OkHttpUtil.post(OkHttpUtil.defaultClient(), "https://jx.xmflv.com/xmflv-1.SVG", hashMap, Headers(), callBack);
|
||||||
|
str3 = new JSONObject(callBack.getResult().body().string()).getString("url");
|
||||||
|
} else {
|
||||||
|
Matcher matcher11 = Q.matcher(OkHttpUtil.string(pY2, Headers()));
|
||||||
|
if (matcher11.find()) {
|
||||||
|
str3 = matcher11.group(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
jSONObject.put("parse", "0");
|
||||||
|
jSONObject.put("playUrl", "");
|
||||||
|
jSONObject.put("url", str3);
|
||||||
|
jSONObject.put("header", "");
|
||||||
|
if (!TextUtils.isEmpty(str4)) {
|
||||||
|
jSONObject.put("subf", "/vtt/utf-8");
|
||||||
|
jSONObject.put("subt", Proxy.localProxyUrl() + "?do=czspp&url=" + URLEncoder.encode(str4));
|
||||||
|
}
|
||||||
|
return jSONObject.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String searchContent(String str, boolean z) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
Elements jS = Jsoup.parse(OkHttpUtil.string("https://czspp.com/xssearch?q=" + URLEncoder.encode(str), Headers())).select("div.mi_ne_kd > ul > li");
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
for (Element next : jS) {
|
||||||
|
Matcher matcher = Db.matcher(next.select("a").attr("href"));
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
if (matcher.find()) {
|
||||||
|
String group = matcher.group(1);
|
||||||
|
String trim = next.select("img").attr("alt").trim();
|
||||||
|
if (trim.contains(str)) {
|
||||||
|
String trim2 = next.select("img").attr("src").trim();
|
||||||
|
if (next.hasClass(".jidi")) {
|
||||||
|
String remark = next.select(".jidi span").text();
|
||||||
|
jSONObject2.put("vod_remarks", remark);
|
||||||
|
} else {
|
||||||
|
String id = next.select("a").attr("href");
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(id, Headers()));
|
||||||
|
String remark = doc.select("ul.moviedteail_list li span").get(0).text();
|
||||||
|
jSONObject2.put("vod_id", group);
|
||||||
|
jSONObject2.put("vod_name", trim);
|
||||||
|
jSONObject2.put("vod_pic", trim2);
|
||||||
|
jSONObject2.put("vod_remarks", remark);
|
||||||
|
jSONArray.put(jSONObject2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jSONObject.put("list", jSONArray);
|
||||||
|
return jSONObject.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,309 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.TimeUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class Gitcafe extends Spider {
|
||||||
|
private Map<String, JSONObject> a;
|
||||||
|
private List<String> b;
|
||||||
|
private PushAgent pushAgent;
|
||||||
|
private JSONObject d;
|
||||||
|
private JSONObject Home;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
pushAgent = new PushAgent();
|
||||||
|
pushAgent.init(context, extend);
|
||||||
|
try {
|
||||||
|
d = new JSONObject("{\"hyds\":\"华语电视\",\"rhds\":\"日韩电视\",\"omds\":\"欧美电视\",\"qtds\":\"其他电视\",\"hydy\":\"华语电影\",\"rhdy\":\"日韩电影\",\"omdy\":\"欧美电影\",\"qtdy\":\"其他电影\",\"hydm\":\"华语动漫\",\"rhdm\":\"日韩动漫\",\"omdm\":\"欧美动漫\",\"jlp\":\"纪录片\",\"zyp\":\"综艺片\",\"jypx\":\"教育培训\",\"qtsp\":\"其他视频\",\"hyyy\":\"华语音乐\",\"rhyy\":\"日韩音乐\",\"omyy\":\"欧美音乐\",\"qtyy\":\"其他音乐\",\"kfrj\":\"娱乐软件\",\"xtrj\":\"系统软件\",\"wlrj\":\"网络软件\",\"bgrj\":\"办公软件\",\"qtrj\":\"其他软件\",\"mh\":\"漫画\",\"xs\":\"小说\",\"cbs\":\"出版书\",\"zspx\":\"知识培训\",\"qtwd\":\"其他文档\",\"bz\":\"壁纸\",\"rw\":\"人物\",\"fj\":\"风景\",\"qttp\":\"其他图片\",\"qt\":\"其他\"}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
this.b = arrayList;
|
||||||
|
arrayList.add("hydm");
|
||||||
|
List<String> list = this.b;
|
||||||
|
list.add("hyds");
|
||||||
|
List<String> list2 = this.b;
|
||||||
|
list2.add("hydy");
|
||||||
|
List<String> list3 = this.b;
|
||||||
|
list3.add("omdm");
|
||||||
|
List<String> list4 = this.b;
|
||||||
|
list4.add("omds");
|
||||||
|
List<String> list5 = this.b;
|
||||||
|
list5.add("omdy");
|
||||||
|
List<String> list6 = this.b;
|
||||||
|
list6.add("rhdm");
|
||||||
|
List<String> list7 = this.b;
|
||||||
|
list7.add("rhds");
|
||||||
|
List<String> list8 = this.b;
|
||||||
|
list8.add("rhdy");
|
||||||
|
List<String> list9 = this.b;
|
||||||
|
list9.add("qtds");
|
||||||
|
List<String> list10 = this.b;
|
||||||
|
list10.add("qtdy");
|
||||||
|
List<String> list11 = this.b;
|
||||||
|
list11.add("qtsp");
|
||||||
|
List<String> list12 = this.b;
|
||||||
|
list12.add("jlp");
|
||||||
|
List<String> list13 = this.b;
|
||||||
|
list13.add("zyp");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HashMap<String, String> LT() {
|
||||||
|
HashMap<String, String> hashMap = new HashMap<>();
|
||||||
|
hashMap.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36");
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String str, String str2, boolean z, HashMap<String, String> hashMap) {
|
||||||
|
try {
|
||||||
|
Map allData = getAllData(this, this, this);
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
Set<String> keySet = allData.keySet();
|
||||||
|
for (String str3 : keySet) {
|
||||||
|
JSONObject jSONObject = (JSONObject) allData.get(str3);
|
||||||
|
if (jSONObject.has("cat")) {
|
||||||
|
String string = jSONObject.getString("cat");
|
||||||
|
if (string.equals(str)) {
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
String sb2 = "https://www.aliyundrive.com/s/" + jSONObject.getString("key");
|
||||||
|
jSONObject2.put("vod_id", sb2);
|
||||||
|
String string2 = jSONObject.getString("title");
|
||||||
|
jSONObject2.put("vod_name", string2);
|
||||||
|
jSONObject2.put("vod_pic", "https://www.lgstatic.com/i/image2/M01/15/7E/CgoB5lysLXCADg6ZAABapAHUnQM321.jpg");
|
||||||
|
jSONArray.put(jSONObject2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject jSONObject3 = new JSONObject();
|
||||||
|
jSONObject3.put("page", 1);
|
||||||
|
jSONObject3.put("pagecount", 1);
|
||||||
|
int length = jSONArray.length();
|
||||||
|
jSONObject3.put("limit", length);
|
||||||
|
TimeUtils.getTimeZoneDatabaseVersion();
|
||||||
|
int length2 = jSONArray.length();
|
||||||
|
jSONObject3.put("total", length2);
|
||||||
|
jSONObject3.put("list", jSONArray);
|
||||||
|
return jSONObject3.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> list) {
|
||||||
|
try {
|
||||||
|
Map allData = getAllData(this, this, this);
|
||||||
|
JSONObject jSONObject = new JSONObject(pushAgent.detailContent(list));
|
||||||
|
JSONArray jSONArray = jSONObject.getJSONArray("list");
|
||||||
|
int i = 0;
|
||||||
|
while (true) {
|
||||||
|
if (i >= list.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i >= jSONArray.length()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JSONObject jSONObject2 = jSONArray.getJSONObject(i);
|
||||||
|
Pattern pattern = PushAgent.Folder;
|
||||||
|
Matcher matcher = pattern.matcher(list.get(i));
|
||||||
|
if (matcher.find()) {
|
||||||
|
String group = matcher.group(1);
|
||||||
|
if (allData.containsKey(group)) {
|
||||||
|
JSONObject jSONObject3 = (JSONObject) allData.get(group);
|
||||||
|
jSONObject2.put("vod_pic", "https://www.lgstatic.com/i/image2/M01/15/7E/CgoB5lysLXCADg6ZAABapAHUnQM321.jpg");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return jSONObject.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Map getAllData(Object obj, Object obj2, Object obj3) {
|
||||||
|
Map<String, JSONObject> map;
|
||||||
|
obj.getClass();
|
||||||
|
obj2.getClass();
|
||||||
|
obj3.getClass();
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
if (a == null) {
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
HashMap<String, String> LT = LT();
|
||||||
|
for (Iterator<String> iter = b.iterator(); iter.hasNext(); ) {
|
||||||
|
String element = iter.next();
|
||||||
|
String content = OkHttpUtil.string("https://gitcafe.net/alipaper/data/" + element + ".json", LT);
|
||||||
|
JSONObject data = new JSONObject(content);
|
||||||
|
JSONArray jSONArray = data.getJSONArray("data");
|
||||||
|
for (int i = 0; i < jSONArray.length(); i++) {
|
||||||
|
JSONObject jSONObject = jSONArray.getJSONObject(i);
|
||||||
|
hashMap.put(jSONObject.getString("key"), jSONObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = hashMap;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
map = a;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getHomeData(Object obj) {
|
||||||
|
obj.getClass();
|
||||||
|
try {
|
||||||
|
if (Home == null) {
|
||||||
|
HashMap<String, String> LT = LT();
|
||||||
|
Home = new JSONObject(OkHttpUtil.string("https://gitcafe.net/alipaper/home.json", LT));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return Home;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean z) {
|
||||||
|
String str = "https://www.lgstatic.com/i/image2/M01/15/7E/CgoB5lysLXCADg6ZAABapAHUnQM321.jpg";
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject homeData = getHomeData(this);
|
||||||
|
JSONObject jSONObject = homeData.getJSONObject("info");
|
||||||
|
JSONArray jSONArray = jSONObject.getJSONArray("new");
|
||||||
|
JSONArray jSONArray2 = new JSONArray();
|
||||||
|
List<String> list = b;
|
||||||
|
Iterator<String> it = list.iterator();
|
||||||
|
while (true) {
|
||||||
|
if (!it.hasNext()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String next = it.next();
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("type_id", next);
|
||||||
|
JSONObject jSONObject3 = d;
|
||||||
|
String string = jSONObject3.getString(next);
|
||||||
|
jSONObject2.put("type_name", string);
|
||||||
|
jSONArray2.put(jSONObject2);
|
||||||
|
}
|
||||||
|
Map allData = getAllData(this, this, this);
|
||||||
|
JSONArray jSONArray3 = new JSONArray();
|
||||||
|
for (int i = 0; i < jSONArray.length(); i++) {
|
||||||
|
JSONObject jSONObject4 = jSONArray.getJSONObject(i);
|
||||||
|
String string2 = jSONObject4.getString("cat");
|
||||||
|
List<String> list2 = b;
|
||||||
|
if (list2.contains(string2)) {
|
||||||
|
String string3 = jSONObject4.getString("key");
|
||||||
|
if (allData.containsKey(string3)) {
|
||||||
|
JSONObject jSONObject5 = (JSONObject) allData.get(string3);
|
||||||
|
JSONObject jSONObject6 = new JSONObject();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("https://www.aliyundrive.com/s/");
|
||||||
|
String string4 = jSONObject4.getString("key");
|
||||||
|
sb.append(string4);
|
||||||
|
String sb2 = sb.toString();
|
||||||
|
jSONObject6.put("vod_id", sb2);
|
||||||
|
String string5 = jSONObject4.getString("title");
|
||||||
|
jSONObject6.put("vod_name", string5);
|
||||||
|
jSONObject6.put("vod_pic", str);
|
||||||
|
String string6 = jSONObject4.getString("date");
|
||||||
|
jSONObject6.put("vod_remarks", string6);
|
||||||
|
jSONArray3.put(jSONObject6);
|
||||||
|
|
||||||
|
}
|
||||||
|
JSONObject jSONObject62 = new JSONObject();
|
||||||
|
StringBuilder sb3 = new StringBuilder();
|
||||||
|
sb3.append("https://www.aliyundrive.com/s/");
|
||||||
|
String string42 = jSONObject4.getString("key");
|
||||||
|
sb3.append(string42);
|
||||||
|
String sb22 = sb3.toString();
|
||||||
|
jSONObject62.put("vod_id", sb22);
|
||||||
|
String string52 = jSONObject4.getString("title");
|
||||||
|
jSONObject62.put("vod_name", string52);
|
||||||
|
jSONObject62.put("vod_pic", str);
|
||||||
|
String string62 = jSONObject4.getString("date");
|
||||||
|
jSONObject62.put("vod_remarks", string62);
|
||||||
|
jSONArray3.put(jSONObject62);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject jSONObject7 = new JSONObject();
|
||||||
|
jSONObject7.put("class", jSONArray2);
|
||||||
|
jSONObject7.put("list", jSONArray3);
|
||||||
|
return jSONObject7.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
return pushAgent.playerContent(str, str2, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String str, boolean z) {
|
||||||
|
try {
|
||||||
|
Map allData = getAllData(this, this, this);
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
Set keySet = allData.keySet();
|
||||||
|
Iterator it = keySet.iterator();
|
||||||
|
while (true) {
|
||||||
|
if (it.hasNext()) {
|
||||||
|
Object next = it.next();
|
||||||
|
JSONObject jSONObject = (JSONObject) allData.get(next);
|
||||||
|
if (jSONObject.has("cat")) {
|
||||||
|
String string = jSONObject.getString("cat");
|
||||||
|
List<String> list = b;
|
||||||
|
if (list.contains(string)) {
|
||||||
|
String string2 = jSONObject.getString("title");
|
||||||
|
if (string2.contains(str)) {
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("https://www.aliyundrive.com/s/");
|
||||||
|
String string3 = jSONObject.getString("key");
|
||||||
|
sb.append(string3);
|
||||||
|
String sb2 = sb.toString();
|
||||||
|
jSONObject2.put("vod_id", sb2);
|
||||||
|
jSONObject2.put("vod_name", string2);
|
||||||
|
jSONArray.put(jSONObject2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
JSONObject jSONObject3 = new JSONObject();
|
||||||
|
jSONObject3.put("list", jSONArray);
|
||||||
|
return jSONObject3.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.Cookie;
|
||||||
|
import okhttp3.CookieJar;
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
|
public class IKan extends AppYsV2 {
|
||||||
|
private final OkHttpClient y;
|
||||||
|
private boolean K = false;
|
||||||
|
private Context cccc = null;
|
||||||
|
|
||||||
|
public IKan() {
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
TimeUnit timeUnit = TimeUnit.SECONDS;
|
||||||
|
y = builder.readTimeout(15L, timeUnit).writeTimeout(15L, timeUnit).connectTimeout(15L, timeUnit).cookieJar(new CookieJar() {
|
||||||
|
final List<Cookie> Mf = new ArrayList();
|
||||||
|
|
||||||
|
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
ArrayList arrayList2 = new ArrayList();
|
||||||
|
for (Cookie cookie : Mf) {
|
||||||
|
if (cookie.expiresAt() < System.currentTimeMillis()) {
|
||||||
|
arrayList.add(cookie);
|
||||||
|
} else if (cookie.matches(httpUrl)) {
|
||||||
|
arrayList2.add(cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mf.removeAll(arrayList);
|
||||||
|
return arrayList2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
|
||||||
|
Mf.addAll(list);
|
||||||
|
}
|
||||||
|
}).retryOnConnectionFailure(true).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void S(final String str, final String str2) {
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
hashMap.put("user_name", str);
|
||||||
|
hashMap.put("user_pwd", str2);
|
||||||
|
hashMap.put("user_pwd2", str2);
|
||||||
|
try {
|
||||||
|
HashMap hashMap2 = new HashMap();
|
||||||
|
hashMap2.put("Host", "tvcms.ikan6.vip");
|
||||||
|
hashMap2.put("User-Agent", "okhttp/3.11.0");
|
||||||
|
OkHttpUtil.post(this.y, "http://tvcms.ikan6.vip/api.php/gctvapi.auth/register", hashMap, hashMap2, new OKCallBack.OKCallBackString() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str3) {
|
||||||
|
try {
|
||||||
|
if (new JSONObject(str3).optInt("code", 0) == 200) {
|
||||||
|
cccc.getSharedPreferences("spider_IKan", 0).edit().putString("user", str).putString("pwd", str2).commit();
|
||||||
|
login(str, str2);
|
||||||
|
}
|
||||||
|
} catch (JSONException unused) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable unused) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void iq() {
|
||||||
|
SharedPreferences sharedPreferences = cccc.getSharedPreferences("spider_IKan", 0);
|
||||||
|
try {
|
||||||
|
String string = sharedPreferences.getString("user", null);
|
||||||
|
String string2 = sharedPreferences.getString("pwd", null);
|
||||||
|
if (!(string == null || string2 == null)) {
|
||||||
|
login(string, string2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Throwable unused) {
|
||||||
|
}
|
||||||
|
S(random(18), random(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String random(int i) {
|
||||||
|
Random random = new Random();
|
||||||
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
|
for (int i2 = 0; i2 < i; i2++) {
|
||||||
|
stringBuffer.append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456".charAt(random.nextInt(59)));
|
||||||
|
}
|
||||||
|
return stringBuffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void init(Context context) {
|
||||||
|
cccc = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void login(String str, String str2) {
|
||||||
|
HashMap headers = new HashMap();
|
||||||
|
headers.put("user_name", str);
|
||||||
|
headers.put("user_pwd", str2);
|
||||||
|
try {
|
||||||
|
HashMap hashMap2 = new HashMap();
|
||||||
|
hashMap2.put("Host", "tvcms.ikan6.vip");
|
||||||
|
hashMap2.put("User-Agent", "okhttp/3.11.0");
|
||||||
|
OkHttpUtil.post(y, "http://tvcms.ikan6.vip/api.php/gctvapi.auth/login", headers, hashMap2, new OKCallBack.OKCallBackString() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str3) {
|
||||||
|
try {
|
||||||
|
if (new JSONObject(str3).optInt("code", 0) == 200) {
|
||||||
|
K = true;
|
||||||
|
}
|
||||||
|
} catch (JSONException unused) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable unused) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<String, String> getHeaders(String URL) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
String url = "http://tvcms.ikan6.vip/api.php/gctvapi.vod";
|
||||||
|
String json = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
String vid = vObj.getString("vod_id");
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vid);
|
||||||
|
v.put("vod_name", vObj.getString("vod_name"));
|
||||||
|
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
try {
|
||||||
|
if (str.equals("lekanzyw")) {
|
||||||
|
if (!K) {
|
||||||
|
iq();
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", " */*");
|
||||||
|
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||||
|
headers.put("Accept-Encoding", " gzip, deflate");
|
||||||
|
headers.put("Connection", " Keep-Alive");
|
||||||
|
|
||||||
|
String parseUrl = "https://player.4kan.top/?url=" + str2;
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(parseUrl, null));
|
||||||
|
Pattern pattern = Pattern.compile("(?<=getrandom\\S\").*?(?=\")");
|
||||||
|
Elements allScripts = doc.select("body script");
|
||||||
|
for (int j = 0; j < allScripts.size(); j++) {
|
||||||
|
String scContents = allScripts.get(j).html().trim();
|
||||||
|
Matcher matcher = pattern.matcher(scContents);
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String players = new String(Base64.decode(matcher.group(0), Base64.DEFAULT));
|
||||||
|
int start = players.indexOf("http");
|
||||||
|
int end = players.lastIndexOf("key=") + 36;
|
||||||
|
String url = players.substring(start, end);
|
||||||
|
Map<String, List<String>> respHeaders = new TreeMap<>();
|
||||||
|
OkHttpUtil.stringNoRedirect(url, null, respHeaders);
|
||||||
|
String redLoc = OkHttpUtil.getRedirectLocation(respHeaders);
|
||||||
|
|
||||||
|
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", redLoc);
|
||||||
|
result.put("header", headers.toString());
|
||||||
|
return result.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String str) {
|
||||||
|
super.init(context, "http://tvcms.ikan6.vip/api.php/gctvapi.vod");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,482 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class If101 extends Spider {
|
||||||
|
private static final String siteUrl = "https://oulevod.tv";
|
||||||
|
private static final String siteHost = "oulevod.tv";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/index.php/vod/type/id/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/index.php/vod/detail/id/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/index.php/vod/play/id/(\\d+)/sid/(\\d+)/nid/(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"if101\":{\"sh\":\"高清蓝光\",\"sn\":0,\"pu\":\"\",\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"1\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"冒险\",\"v\":\"6\"},{\"n\":\"剧情\",\"v\":\"7\"},{\"n\":\"动作\",\"v\":\"8\"},{\"n\":\"动画电影\",\"v\":\"9\"},{\"n\":\"同性\",\"v\":\"10\"},{\"n\":\"喜剧\",\"v\":\"11\"},{\"n\":\"奇幻\",\"v\":\"12\"},{\"n\":\"恐怖\",\"v\":\"20\"},{\"n\":\"悬疑\",\"v\":\"21\"},{\"n\":\"惊悚\",\"v\":\"22\"},{\"n\":\"战争\",\"v\":\"23\"},{\"n\":\"歌舞\",\"v\":\"24\"},{\"n\":\"灾难\",\"v\":\"25\"},{\"n\":\"爱情\",\"v\":\"26\"},{\"n\":\"犯罪\",\"v\":\"27\"},{\"n\":\"科幻\",\"v\":\"28\"},{\"n\":\"经典\",\"v\":\"29\"},{\"n\":\"网络电影\",\"v\":\"30\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"枪战\",\"v\":\"枪战\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"微电影\",\"v\":\"微电影\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"农村\",\"v\":\"农村\"},{\"n\":\"儿童\",\"v\":\"儿童\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"version\",\"name\":\"版本\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"高清版\",\"v\":\"高清版\"},{\"n\":\"剧场版\",\"v\":\"剧场版\"},{\"n\":\"抢先版\",\"v\":\"抢先版\"},{\"n\":\"OVA\",\"v\":\"OVA\"},{\"n\":\"TV\",\"v\":\"TV\"},{\"n\":\"影院版\",\"v\":\"影院版\"}]},{\"key\":\"state\",\"name\":\"资源\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"正片\",\"v\":\"正片\"},{\"n\":\"预告片\",\"v\":\"预告片\"},{\"n\":\"花絮\",\"v\":\"花絮\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"欧美剧\",\"v\":\"13\"},{\"n\":\"日剧\",\"v\":\"14\"},{\"n\":\"韩剧\",\"v\":\"15\"},{\"n\":\"国产剧\",\"v\":\"16\"},{\"n\":\"泰剧\",\"v\":\"31\"},{\"n\":\"港剧\",\"v\":\"32\"},{\"n\":\"台剧\",\"v\":\"33\"},{\"n\":\"新马剧\",\"v\":\"34\"},{\"n\":\"其它剧\",\"v\":\"35\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"version\",\"name\":\"版本\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"高清版\",\"v\":\"高清版\"},{\"n\":\"剧场版\",\"v\":\"剧场版\"},{\"n\":\"抢先版\",\"v\":\"抢先版\"},{\"n\":\"OVA\",\"v\":\"OVA\"},{\"n\":\"TV\",\"v\":\"TV\"},{\"n\":\"影院版\",\"v\":\"影院版\"}]},{\"key\":\"state\",\"name\":\"资源\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"正片\",\"v\":\"正片\"},{\"n\":\"预告片\",\"v\":\"预告片\"},{\"n\":\"花絮\",\"v\":\"花絮\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"欧美动漫\",\"v\":\"36\"},{\"n\":\"日本动漫\",\"v\":\"37\"},{\"n\":\"韩国动漫\",\"v\":\"38\"},{\"n\":\"国产动漫\",\"v\":\"39\"},{\"n\":\"新马泰动漫\",\"v\":\"40\"},{\"n\":\"港台动漫\",\"v\":\"41\"},{\"n\":\"其他动漫\",\"v\":\"42\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"旅游\",\"v\":\"旅游\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"游戏互动\",\"v\":\"游戏互动\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"求职\",\"v\":\"求职\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"欧美综艺\",\"v\":\"43\"},{\"n\":\"日本综艺\",\"v\":\"44\"},{\"n\":\"韩国综艺\",\"v\":\"45\"},{\"n\":\"国产综艺\",\"v\":\"46\"},{\"n\":\"新马泰综艺\",\"v\":\"47\"},{\"n\":\"港台综艺\",\"v\":\"48\"},{\"n\":\"其他综艺\",\"v\":\"49\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"version\",\"name\":\"版本\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"TV版\",\"v\":\"TV版\"},{\"n\":\"电影版\",\"v\":\"电影版\"},{\"n\":\"OVA版\",\"v\":\"OVA版\"},{\"n\":\"真人版\",\"v\":\"真人版\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"50\":[{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"51\":[{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Host", siteHost);
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("div.conch-nav div ul li a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = name.equals("电影") ||
|
||||||
|
name.equals("电视剧") ||
|
||||||
|
name.equals("动漫") ||
|
||||||
|
name.equals("综艺") ||
|
||||||
|
name.equals("纪录片") ||
|
||||||
|
name.equals("体育");
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("ul.hl-vod-list").get(0);
|
||||||
|
Elements list = homeList.select("li.hl-list-item");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst("div.hl-item-title a").text();
|
||||||
|
String cover = vod.selectFirst(".hl-item-thumb").attr("data-original");
|
||||||
|
String remark = vod.selectFirst(".hl-pic-text span").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst("div.hl-item-title a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/index.php/vod/show/id/";
|
||||||
|
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||||
|
url += extend.get("tid");
|
||||||
|
} else {
|
||||||
|
url += tid;
|
||||||
|
}
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url += "/page/" + pg + ".html";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select("ul.hl-page-wrap");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("li a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
String span = pageInfo.select("li a.active").text();
|
||||||
|
String wy = doc.select("ul.hl-page-wrap li a").last().attr("href");
|
||||||
|
if (page == -1) {
|
||||||
|
page = Integer.parseInt(span);
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
Matcher matcher = regexPage.matcher(wy);
|
||||||
|
if (matcher.find()) {
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("li.hl-list-item");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst("div.hl-item-title a").text();
|
||||||
|
String cover = vod.selectFirst(".hl-item-thumb").attr("data-original");
|
||||||
|
String remark = vod.selectFirst(".hl-pic-text span").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst("div.hl-item-title a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 24);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 24);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/index.php/vod/detail/id/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
String vid = doc.selectFirst("a.digg_link").attr("data-id");
|
||||||
|
|
||||||
|
String cover = doc.selectFirst("div.hl-dc-pic span").attr("data-original");
|
||||||
|
String title = doc.selectFirst("h2.hl-dc-title").text();
|
||||||
|
String desc = doc.selectFirst("span.hl-content-text em").text();
|
||||||
|
String category = "", area = "", year = "", director = "", actor = "", remark = "";
|
||||||
|
Elements span_text_muted = doc.select("li.hl-col-xs-12 em");
|
||||||
|
for (int i = 0; i < span_text_muted.size() - 2; i++) {
|
||||||
|
Element text = span_text_muted.get(i);
|
||||||
|
String info = text.text();
|
||||||
|
if (info.contains("类型")) {
|
||||||
|
try {
|
||||||
|
category = text.parent().select("a").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
category = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("年份")) {
|
||||||
|
try {
|
||||||
|
year = text.parent().text().split(":")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
year = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("地区")) {
|
||||||
|
try {
|
||||||
|
area = text.parent().text().split(":")[1];
|
||||||
|
} catch (Exception e) {
|
||||||
|
area = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("上映")) {
|
||||||
|
try {
|
||||||
|
remark = text.text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
remark = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("导演")) {
|
||||||
|
try {
|
||||||
|
director = text.parent().select("a").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
director = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("主演")) {
|
||||||
|
try {
|
||||||
|
actor = text.parent().select("a").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
actor = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vodList.put("vod_id", vid);
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.hl-plays-from a");
|
||||||
|
Elements sourceList = doc.select("div.hl-list-wrap");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.text();
|
||||||
|
sourceName = sourceName.replaceAll("[^\u4E00-\u9FA5]", "");
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = flag;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "/sid/" + matcher.group(2) + "/nid/" + matcher.group(3);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + "/index.php/vod/play/id/" + id + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) { // 取直链
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
String videoUrl = player.getString("url");
|
||||||
|
String playUrl = pCfg.getString("pu");
|
||||||
|
result.put("parse", pCfg.getInt("sn"));
|
||||||
|
result.put("playUrl", playUrl);
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
result.put("header", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||||
|
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (searchResult.getInt("total") > 0) {
|
||||||
|
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||||
|
for (int i = 0; i < lists.length(); i++) {
|
||||||
|
JSONObject vod = lists.getJSONObject(i);
|
||||||
|
String id = vod.getString("id");
|
||||||
|
String title = vod.getString("name");
|
||||||
|
String cover = vod.getString("pic");
|
||||||
|
if (title.contains(key)) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", "");
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||||
|
if (pattern == null)
|
||||||
|
return src;
|
||||||
|
try {
|
||||||
|
Matcher matcher = pattern.matcher(src);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).trim();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.demo.MainActivity;
|
||||||
|
|
||||||
|
public class Init {
|
||||||
|
|
||||||
|
|
||||||
|
public static void init(Context context) {
|
||||||
|
SpiderDebug.log("自定义爬虫代码加载成功!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,681 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Base64;
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class Kuaikan extends Spider {
|
||||||
|
private static String Cb;
|
||||||
|
private static long QH;
|
||||||
|
private static String dW;
|
||||||
|
private HashMap<String, ArrayList<String>> Ji = new HashMap<>();
|
||||||
|
|
||||||
|
private void Q() {
|
||||||
|
if (System.currentTimeMillis() > QH) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("bf70a456195ae394184b2e0b1b471cae1000300001dc431681b806089dac1153fb13960f87" + currentTimeMillis + "notice");
|
||||||
|
jSONObject.put("appId", "1000300001");
|
||||||
|
jSONObject.put("sign", f);
|
||||||
|
jSONObject.put("timestamp", currentTimeMillis);
|
||||||
|
String O = Decrypt("bf70a456195ae394", "184b2e0b1b471cae", jSONObject.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", "bf70a456195ae394184b2e0b1b471cae");
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("body", O);
|
||||||
|
jSONObject2.put("ticket", tg);
|
||||||
|
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "http://ctlook.facaishiyi.com/api/v1/user/login.do", jSONObject2.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject3 = new JSONObject(str);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject3.getString("ticket"));
|
||||||
|
JSONObject jSONObject4 = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject3.getString("body")));
|
||||||
|
long unused = Kuaikan.QH = jSONObject4.getLong("duration") * 1000;
|
||||||
|
String unused2 = Kuaikan.Cb = jSONObject4.getString("data");
|
||||||
|
Kuaikan.this.Uf();
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Uf() {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("1000300001dc431681b806089dac1153fb13960f8700" + dW + currentTimeMillis + "notice");
|
||||||
|
jSONObject.put("adv", 0);
|
||||||
|
jSONObject.put("appId", "1000300001");
|
||||||
|
jSONObject.put("nav", 0);
|
||||||
|
jSONObject.put("sign", f);
|
||||||
|
jSONObject.put("timestamp", currentTimeMillis);
|
||||||
|
jSONObject.put("umId", dW);
|
||||||
|
String O = Decrypt(Cb.substring(0, 16), Cb.substring(16, 32), jSONObject.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Cb);
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("body", O);
|
||||||
|
jSONObject2.put("ticket", tg);
|
||||||
|
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "http://ctlook.facaishiyi.com/api/v1/user/config.do", jSONObject2.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.1
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject3 = new JSONObject(str);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject3.getString("ticket"));
|
||||||
|
JSONArray jSONArray = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject3.getString("body"))).getJSONObject("data").getJSONArray("newAnalysis");
|
||||||
|
Kuaikan.this.Ji.clear();
|
||||||
|
for (int i = 0; i < jSONArray.length(); i++) {
|
||||||
|
JSONObject jSONObject4 = jSONArray.getJSONObject(i);
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
Kuaikan.this.Ji.put(jSONObject4.getString("id"), arrayList);
|
||||||
|
JSONArray jSONArray2 = jSONObject4.getJSONArray("analyses");
|
||||||
|
for (int i2 = 0; i2 < jSONArray2.length(); i2++) {
|
||||||
|
arrayList.add(jSONArray2.getJSONObject(i2).getString("url"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, String> j(long j) {
|
||||||
|
HashMap<String, String> hashMap = new HashMap<>();
|
||||||
|
hashMap.put("appId", "1000300001");
|
||||||
|
hashMap.put("version", "4");
|
||||||
|
hashMap.put("timestamp", j + "");
|
||||||
|
hashMap.put("token", f("1000300001dc431681b806089dac1153fb13960f874" + j + "notice"));
|
||||||
|
hashMap.put("User-Agent", "okhttp/5.0.0-alpha.2");
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
String Decrypt(String str, String str2, String str3) {
|
||||||
|
try {
|
||||||
|
SecretKeySpec secretKeySpec = new SecretKeySpec(str.getBytes(), "AES");
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
cipher.init(1, secretKeySpec, new IvParameterSpec(str2.getBytes()));
|
||||||
|
return Base64.encodeToString(cipher.doFinal(str3.getBytes()), 2);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String UO(String str, String str2, String str3) {
|
||||||
|
try {
|
||||||
|
SecretKeySpec secretKeySpec = new SecretKeySpec(str.getBytes(), "AES");
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
cipher.init(2, secretKeySpec, new IvParameterSpec(str2.getBytes()));
|
||||||
|
return new String(cipher.doFinal(Base64.decode(str3, 0)), "UTF-8");
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String categoryContent(String str, final String str2, boolean z, HashMap<String, String> hashMap) {
|
||||||
|
try {
|
||||||
|
Q();
|
||||||
|
int parseInt = hashMap.containsKey("areaId") ? Integer.parseInt(hashMap.get("areaId")) : 0;
|
||||||
|
int parseInt2 = hashMap.containsKey("tagId") ? Integer.parseInt(hashMap.get("tagId")) : 0;
|
||||||
|
int parseInt3 = hashMap.containsKey("yearId") ? Integer.parseInt(hashMap.get("yearId")) : 0;
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("1000300001dc431681b806089dac1153fb13960f87" + str2 + 18 + str + parseInt2 + parseInt + parseInt3 + currentTimeMillis + "notice");
|
||||||
|
jSONObject.put("appId", "1000300001");
|
||||||
|
jSONObject.put("typeId", str);
|
||||||
|
jSONObject.put("areaId", parseInt);
|
||||||
|
jSONObject.put("tagId", parseInt2);
|
||||||
|
jSONObject.put("yearId", parseInt3);
|
||||||
|
jSONObject.put("page", Integer.parseInt(str2));
|
||||||
|
jSONObject.put("pageSize", 18);
|
||||||
|
jSONObject.put("sign", f);
|
||||||
|
jSONObject.put("timestamp", currentTimeMillis);
|
||||||
|
String O = Decrypt(Cb.substring(0, 16), Cb.substring(16, 32), jSONObject.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Cb);
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("body", O);
|
||||||
|
jSONObject2.put("ticket", tg);
|
||||||
|
final JSONObject jSONObject3 = new JSONObject();
|
||||||
|
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "http://ctlook.facaishiyi.com/api/v1/search/video.do", jSONObject2.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.5
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str3) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject4 = new JSONObject(str3);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject4.getString("ticket"));
|
||||||
|
JSONObject jSONObject5 = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject4.getString("body")));
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
JSONArray jSONArray2 = jSONObject5.getJSONArray("results");
|
||||||
|
for (int i = 0; i < jSONArray2.length(); i++) {
|
||||||
|
JSONObject jSONObject6 = jSONArray2.getJSONObject(i);
|
||||||
|
JSONObject jSONObject7 = new JSONObject();
|
||||||
|
jSONObject7.put("vod_id", jSONObject6.getString("id"));
|
||||||
|
jSONObject7.put("vod_name", jSONObject6.getString("name"));
|
||||||
|
jSONObject7.put("vod_pic", jSONObject6.getString("pic"));
|
||||||
|
jSONObject7.put("vod_remarks", jSONObject6.getString("progress"));
|
||||||
|
jSONArray.put(jSONObject7);
|
||||||
|
}
|
||||||
|
jSONObject3.put("page", Integer.parseInt(str2));
|
||||||
|
int i2 = jSONObject5.getInt("count");
|
||||||
|
int i3 = 20;
|
||||||
|
jSONObject3.put("pagecount", i2 % i3 == 0 ? i2 / i3 : (i2 / i3) + 1);
|
||||||
|
jSONObject3.put("limit", i3);
|
||||||
|
jSONObject3.put("total", i2);
|
||||||
|
jSONObject3.put("list", jSONArray);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return jSONObject3.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String detailContent(final List<String> list) {
|
||||||
|
try {
|
||||||
|
Q();
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("1000300001dc431681b806089dac1153fb13960f87" + list.get(0) + currentTimeMillis + "notice");
|
||||||
|
jSONObject.put("appId", "1000300001");
|
||||||
|
jSONObject.put("id", list.get(0));
|
||||||
|
jSONObject.put("sign", f);
|
||||||
|
jSONObject.put("timestamp", currentTimeMillis);
|
||||||
|
String O = Decrypt(Cb.substring(0, 16), Cb.substring(16, 32), jSONObject.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Cb);
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("body", O);
|
||||||
|
jSONObject2.put("ticket", tg);
|
||||||
|
final JSONObject jSONObject3 = new JSONObject();
|
||||||
|
OkHttpClient QH2 = OkHttpUtil.defaultClient();
|
||||||
|
OkHttpUtil.postJson(QH2, "http://ctlook.facaishiyi.com/api/v1/video/play/" + list.get(0) + ".do ", jSONObject2.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.6
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject4 = new JSONObject(str);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject4.getString("ticket"));
|
||||||
|
JSONObject jSONObject5 = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject4.getString("body"))).getJSONObject("data");
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
JSONObject jSONObject6 = new JSONObject();
|
||||||
|
jSONObject6.put("vod_id", jSONObject5.getString("id"));
|
||||||
|
jSONObject6.put("vod_name", jSONObject5.getString("name"));
|
||||||
|
jSONObject6.put("vod_pic", jSONObject5.getString("pic"));
|
||||||
|
jSONObject6.put("vod_year", jSONObject5.getString("year"));
|
||||||
|
jSONObject6.put("vod_remarks", jSONObject5.getString("progress"));
|
||||||
|
jSONObject6.put("vod_actor", jSONObject5.getString("actor"));
|
||||||
|
jSONObject6.put("vod_director", jSONObject5.getString("director"));
|
||||||
|
jSONObject6.put("vod_content", jSONObject5.getString("content").trim());
|
||||||
|
JSONArray jSONArray2 = new JSONArray(Kuaikan.this.UO("5551e2a82a21a9a1", "a586c5236206a2cb", jSONObject5.getString("newPlayback")));
|
||||||
|
LinkedHashMap linkedHashMap = new LinkedHashMap();
|
||||||
|
for (int i = 0; i < jSONArray2.length(); i++) {
|
||||||
|
JSONObject jSONObject7 = jSONArray2.getJSONObject(i);
|
||||||
|
String string = jSONObject7.getString("name");
|
||||||
|
String string2 = jSONObject7.getString("id");
|
||||||
|
JSONArray jSONArray3 = jSONObject7.getJSONArray("episodes");
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
for (int i2 = 0; i2 < jSONArray3.length(); i2++) {
|
||||||
|
JSONObject jSONObject8 = jSONArray3.getJSONObject(i2);
|
||||||
|
String string3 = jSONObject8.getString("title");
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(string3);
|
||||||
|
sb.append("|");
|
||||||
|
sb.append((String) list.get(0));
|
||||||
|
sb.append("|");
|
||||||
|
sb.append(string2);
|
||||||
|
sb.append("|");
|
||||||
|
sb.append(jSONObject8.getString("url"));
|
||||||
|
String encodeToString = Base64.encodeToString(sb.toString().getBytes("UTF-8"), 10);
|
||||||
|
arrayList.add(string3 + "$" + encodeToString);
|
||||||
|
}
|
||||||
|
linkedHashMap.put(string, TextUtils.join("#", arrayList));
|
||||||
|
}
|
||||||
|
String join = TextUtils.join("$$$", linkedHashMap.keySet());
|
||||||
|
String join2 = TextUtils.join("$$$", linkedHashMap.values());
|
||||||
|
jSONObject6.put("vod_play_from", join);
|
||||||
|
jSONObject6.put("vod_play_url", join2);
|
||||||
|
jSONArray.put(jSONObject6);
|
||||||
|
jSONObject3.put("list", jSONArray);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return jSONObject3.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String f(String str) {
|
||||||
|
try {
|
||||||
|
byte[] digest = MessageDigest.getInstance("MD5").digest(str.getBytes());
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte b : digest) {
|
||||||
|
String hexString = Integer.toHexString(b & 255);
|
||||||
|
if (hexString.length() < 2) {
|
||||||
|
sb.append(0);
|
||||||
|
}
|
||||||
|
sb.append(hexString);
|
||||||
|
}
|
||||||
|
return sb.toString().toLowerCase();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String homeContent(boolean z) {
|
||||||
|
try {
|
||||||
|
Q();
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("1000300001dc431681b806089dac1153fb13960f87" + currentTimeMillis + "notice");
|
||||||
|
jSONObject.put("appId", "1000300001");
|
||||||
|
jSONObject.put("sign", f);
|
||||||
|
jSONObject.put("timestamp", currentTimeMillis);
|
||||||
|
String O = Decrypt(Cb.substring(0, 16), Cb.substring(16, 32), jSONObject.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Cb);
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("body", O);
|
||||||
|
jSONObject2.put("ticket", tg);
|
||||||
|
final JSONObject jSONObject3 = new JSONObject();
|
||||||
|
final JSONArray jSONArray = new JSONArray();
|
||||||
|
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "http://ctlook.facaishiyi.com/api/v1/user/genres.do", jSONObject2.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.3
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject4 = new JSONObject(str);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject4.getString("ticket"));
|
||||||
|
JSONArray jSONArray2 = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject4.getString("body"))).getJSONArray("genres");
|
||||||
|
for (int i = 0; i < jSONArray2.length(); i++) {
|
||||||
|
JSONObject jSONObject5 = jSONArray2.getJSONObject(i);
|
||||||
|
String string = jSONObject5.getString("name");
|
||||||
|
final int i2 = jSONObject5.getInt("typeId");
|
||||||
|
if (i2 > 0) {
|
||||||
|
JSONObject jSONObject6 = new JSONObject();
|
||||||
|
jSONObject6.put("type_id", i2 + "");
|
||||||
|
jSONObject6.put("type_name", string);
|
||||||
|
jSONArray.put(jSONObject6);
|
||||||
|
JSONObject jSONObject7 = new JSONObject();
|
||||||
|
long currentTimeMillis2 = System.currentTimeMillis() / 1000;
|
||||||
|
Kuaikan kuaikan = Kuaikan.this;
|
||||||
|
String f2 = kuaikan.f("1000300001dc431681b806089dac1153fb13960f87" + i2 + currentTimeMillis2 + "notice");
|
||||||
|
jSONObject7.put("appId", "1000300001");
|
||||||
|
jSONObject7.put("tid", i2);
|
||||||
|
jSONObject7.put("sign", f2);
|
||||||
|
jSONObject7.put("timestamp", currentTimeMillis2);
|
||||||
|
String O2 = Kuaikan.this.Decrypt(Kuaikan.Cb.substring(0, 16), Kuaikan.Cb.substring(16, 32), jSONObject7.toString());
|
||||||
|
String tg2 = Kuaikan.this.tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Kuaikan.Cb);
|
||||||
|
JSONObject jSONObject8 = new JSONObject();
|
||||||
|
jSONObject8.put("body", O2);
|
||||||
|
jSONObject8.put("ticket", tg2);
|
||||||
|
new JSONArray();
|
||||||
|
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "http://ctlook.facaishiyi.com/api/v1/search/category.do", jSONObject8.toString(), Kuaikan.this.j(currentTimeMillis2), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.3.1
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str2) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject9 = new JSONObject(str2);
|
||||||
|
String lX2 = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject9.getString("ticket"));
|
||||||
|
JSONObject jSONObject10 = new JSONObject(Kuaikan.this.UO(lX2.substring(0, 16), lX2.substring(16, 32), jSONObject9.getString("body")));
|
||||||
|
JSONArray jSONArray3 = jSONObject10.getJSONArray("areas");
|
||||||
|
JSONArray jSONArray4 = jSONObject10.getJSONArray("years");
|
||||||
|
JSONArray jSONArray5 = jSONObject10.getJSONArray("tags");
|
||||||
|
JSONArray jSONArray6 = new JSONArray();
|
||||||
|
JSONObject jSONObject11 = new JSONObject();
|
||||||
|
jSONObject11.put("key", "tagId");
|
||||||
|
jSONObject11.put("name", "类型");
|
||||||
|
JSONArray jSONArray7 = new JSONArray();
|
||||||
|
for (int i3 = 0; i3 < jSONArray5.length(); i3++) {
|
||||||
|
JSONObject jSONObject12 = jSONArray5.getJSONObject(i3);
|
||||||
|
JSONObject jSONObject13 = new JSONObject();
|
||||||
|
jSONObject13.put("n", jSONObject12.getString("name"));
|
||||||
|
jSONObject13.put("v", jSONObject12.getString("id"));
|
||||||
|
jSONArray7.put(jSONObject13);
|
||||||
|
}
|
||||||
|
jSONObject11.put("value", jSONArray7);
|
||||||
|
jSONArray6.put(jSONObject11);
|
||||||
|
JSONObject jSONObject14 = new JSONObject();
|
||||||
|
jSONObject14.put("key", "areaId");
|
||||||
|
jSONObject14.put("name", "地区");
|
||||||
|
JSONArray jSONArray8 = new JSONArray();
|
||||||
|
for (int i4 = 0; i4 < jSONArray3.length(); i4++) {
|
||||||
|
JSONObject jSONObject15 = jSONArray3.getJSONObject(i4);
|
||||||
|
JSONObject jSONObject16 = new JSONObject();
|
||||||
|
jSONObject16.put("n", jSONObject15.getString("name"));
|
||||||
|
jSONObject16.put("v", jSONObject15.getString("id"));
|
||||||
|
jSONArray8.put(jSONObject16);
|
||||||
|
}
|
||||||
|
jSONObject14.put("value", jSONArray8);
|
||||||
|
jSONArray6.put(jSONObject14);
|
||||||
|
JSONObject jSONObject17 = new JSONObject();
|
||||||
|
jSONObject17.put("key", "yearId");
|
||||||
|
jSONObject17.put("name", "年份");
|
||||||
|
JSONArray jSONArray9 = new JSONArray();
|
||||||
|
for (int i5 = 0; i5 < jSONArray4.length(); i5++) {
|
||||||
|
JSONObject jSONObject18 = jSONArray4.getJSONObject(i5);
|
||||||
|
JSONObject jSONObject19 = new JSONObject();
|
||||||
|
jSONObject19.put("n", jSONObject18.getString("name"));
|
||||||
|
jSONObject19.put("v", jSONObject18.getString("id"));
|
||||||
|
jSONArray9.put(jSONObject19);
|
||||||
|
}
|
||||||
|
jSONObject17.put("value", jSONArray9);
|
||||||
|
jSONArray6.put(jSONObject17);
|
||||||
|
jSONObject3.put(i2 + "", jSONArray6);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
JSONObject jSONObject4 = new JSONObject();
|
||||||
|
jSONObject4.put("class", jSONArray);
|
||||||
|
if (z) {
|
||||||
|
jSONObject4.put("filters", jSONObject3);
|
||||||
|
}
|
||||||
|
return jSONObject4.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
Q();
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("1000300001dc431681b806089dac1153fb13960f87115" + currentTimeMillis + "notice");
|
||||||
|
jSONObject.put("appId", "1000300001");
|
||||||
|
jSONObject.put("id", 115);
|
||||||
|
jSONObject.put("sign", f);
|
||||||
|
jSONObject.put("timestamp", currentTimeMillis);
|
||||||
|
String O = Decrypt(Cb.substring(0, 16), Cb.substring(16, 32), jSONObject.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Cb);
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("body", O);
|
||||||
|
jSONObject2.put("ticket", tg);
|
||||||
|
final JSONArray jSONArray = new JSONArray();
|
||||||
|
OkHttpClient QH2 = OkHttpUtil.defaultClient();
|
||||||
|
OkHttpUtil.postJson(QH2, "http://ctlook.facaishiyi.com/api/v1/user/genre/115.do", jSONObject2.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.4
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject3 = new JSONObject(str);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject3.getString("ticket"));
|
||||||
|
JSONArray jSONArray2 = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject3.getString("body"))).getJSONArray("subGenres");
|
||||||
|
for (int i = 0; i < jSONArray2.length(); i++) {
|
||||||
|
if (jSONArray2.getJSONObject(i).getInt("template") == 1) {
|
||||||
|
JSONArray jSONArray3 = jSONArray2.getJSONObject(i).getJSONArray("video");
|
||||||
|
for (int i2 = 0; i2 < jSONArray3.length(); i2++) {
|
||||||
|
JSONObject jSONObject4 = jSONArray3.getJSONObject(i2);
|
||||||
|
JSONObject jSONObject5 = new JSONObject();
|
||||||
|
jSONObject5.put("vod_id", jSONObject4.getString("id"));
|
||||||
|
jSONObject5.put("vod_name", jSONObject4.getString("name"));
|
||||||
|
jSONObject5.put("vod_pic", jSONObject4.getString("pic"));
|
||||||
|
jSONObject5.put("vod_remarks", jSONObject4.getString("progress"));
|
||||||
|
jSONArray.put(jSONObject5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
JSONObject jSONObject3 = new JSONObject();
|
||||||
|
jSONObject3.put("list", jSONArray);
|
||||||
|
return jSONObject3.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Context context, String str) {
|
||||||
|
Kuaikan.super.init(context, str);
|
||||||
|
SharedPreferences sharedPreferences = context.getSharedPreferences("spider_Kuaikan", 0);
|
||||||
|
try {
|
||||||
|
String string = sharedPreferences.getString("umId", null);
|
||||||
|
dW = string;
|
||||||
|
if (string != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
if (dW != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dW = f(UUID.randomUUID().toString()).toLowerCase();
|
||||||
|
sharedPreferences.edit().putString("umId", dW).commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
String lX(String str, String str2) {
|
||||||
|
int i = 0;
|
||||||
|
try {
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||||
|
cipher.init(2, (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode(str, 0))));
|
||||||
|
byte[] decode = Base64.decode(str2, 0);
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
if (decode.length <= 256) {
|
||||||
|
byteArrayOutputStream.write(cipher.doFinal(decode));
|
||||||
|
} else {
|
||||||
|
int length = decode.length;
|
||||||
|
while (i < length) {
|
||||||
|
int i2 = i + 256;
|
||||||
|
byteArrayOutputStream.write(cipher.doFinal(decode, i, i2 > length ? length - i : 256));
|
||||||
|
i = i2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byteArrayOutputStream.flush();
|
||||||
|
byteArrayOutputStream.close();
|
||||||
|
return new String(byteArrayOutputStream.toByteArray(), "UTF-8");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
try {
|
||||||
|
Q();
|
||||||
|
String[] split = new String(Base64.decode(str2, 10), "UTF-8").split("\\|");
|
||||||
|
ArrayList<String> arrayList = this.Ji.get(split[2]);
|
||||||
|
final JSONObject jSONObject = new JSONObject();
|
||||||
|
if (arrayList != null && arrayList.size() > 0) {
|
||||||
|
Iterator<String> it = arrayList.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
String next = it.next();
|
||||||
|
if (jSONObject.has("url")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("1000300001dc431681b806089dac1153fb13960f87" + split[1] + split[0] + split[3] + currentTimeMillis + "notice");
|
||||||
|
jSONObject2.put("appId", "1000300001");
|
||||||
|
jSONObject2.put("id", split[1]);
|
||||||
|
jSONObject2.put("title", split[0]);
|
||||||
|
jSONObject2.put("url", split[3]);
|
||||||
|
jSONObject2.put("sign", f);
|
||||||
|
jSONObject2.put("timestamp", currentTimeMillis);
|
||||||
|
String O = Decrypt(Cb.substring(0, 16), Cb.substring(16, 32), jSONObject2.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Cb);
|
||||||
|
JSONObject jSONObject3 = new JSONObject();
|
||||||
|
jSONObject3.put("body", O);
|
||||||
|
jSONObject3.put("ticket", tg);
|
||||||
|
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), next, jSONObject3.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.7
|
||||||
|
@Override // com.github.catvod.spider.merge.OKCallBack
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str3) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject4 = new JSONObject(str3);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject4.getString("ticket"));
|
||||||
|
JSONObject jSONObject5 = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject4.getString("body")));
|
||||||
|
if (jSONObject5.optString("msg", "").equals("success") && jSONObject5.optInt("code", -1) == 0) {
|
||||||
|
jSONObject.put("parse", 0);
|
||||||
|
jSONObject.put("header", "");
|
||||||
|
jSONObject.put("playUrl", "");
|
||||||
|
jSONObject.put("url", jSONObject5.getString("url"));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (jSONObject.has("url")) {
|
||||||
|
return jSONObject.toString();
|
||||||
|
}
|
||||||
|
if (!Misc.isVideoFormat(split[3])) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
jSONObject.put("parse", 0);
|
||||||
|
jSONObject.put("header", "");
|
||||||
|
jSONObject.put("playUrl", "");
|
||||||
|
jSONObject.put("url", split[3]);
|
||||||
|
return jSONObject.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String searchContent(String str, boolean z) {
|
||||||
|
try {
|
||||||
|
Q();
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
long currentTimeMillis = System.currentTimeMillis() / 1000;
|
||||||
|
String f = f("1000300001dc431681b806089dac1153fb13960f87112" + str + currentTimeMillis + "notice");
|
||||||
|
jSONObject.put("appId", "1000300001");
|
||||||
|
jSONObject.put("keyword", str);
|
||||||
|
jSONObject.put("page", 1);
|
||||||
|
jSONObject.put("pageSize", 12);
|
||||||
|
jSONObject.put("sign", f);
|
||||||
|
jSONObject.put("timestamp", currentTimeMillis);
|
||||||
|
String O = Decrypt(Cb.substring(0, 16), Cb.substring(16, 32), jSONObject.toString());
|
||||||
|
String tg = tg("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDitX/rWP6WWc3h\nDzUcfD8Hbw79yCB7rz18GEkjDapjlUVIa3P8FEQFoOchu7N+vdK6HQNsl2Bql4lv\nWOYuzRWNbLGQ7mNtMca28iCuPHck0AcJzOs9F6qruPL73eY7Ai7yvzs2IfEdyXSz\nHP/yXgEOi5ZEBfsBZEPMJw6vfHJVueuD/lh/LkoJ/gXEKMCM/pkIzGpBPd2TsIg8\nZdvOGMPy+MOnJb1Qfe0y3QQdc5VPVdZFWoWsM9RAenHmE3d1THb+uNZZZcnM1tV7\nxYgBbIhgHtXAZnWDWDRBM3xJPR3O9dfBHHt/tbyrZrSwK1IgwFgqfYm/tRbmp4y/\n1DhIF6mDAgMBAAECggEAIzDjS2gEFNiZ0a6nouVSb1f47sHq8OgR1jp619seMNkR\n6Rzs4xtON8VzO1REl47lsAgi6O9SgxlEtykIiglBqDNQGNw4SNHqM6nAEuvF3sv/\n27CYb2JGFuPdq+UVAOHk4b93dH6uS95ipA8DV97psRVP3P1EqkGjGISTjf/2S4IG\n10Q0UhP4xxiRS2iCtaIq0fbvnrChqYRlYQYpkkRCCH+Q4FNKquSsqmWyCu5yfeQM\nMek+aT9KgvmCh05UCeqC1x7xPtSneNbpJpLD5zW8CcG7EYFDtIP8b9BPDlud47ZH\n5Y4/wyQQFHHLOaniTJVvEJZ7cIoXy2gOhvgcHpNryQKBgQDxNNtXnCfVK0JYNhnU\n5WCOX9NeW9Q79HldhTM5/EqsjA5H21j5S7A/duBSRfX7iou1hyXaa2p+J7rxF9sj\nNlwHPsKhprskxXaHJ7qU84gSmwORsTQQPmtTsizGwVsM330+Q2ZROaSEfDoUqH9+\nKBKs6K+FOldcTOrCZ+ILk8werwKBgQDwnQUrKATzRThVdD6Hcgt/F/SAizDmvtiT\nVvRcGkiV3EtB5Rx8zFNJ9GWrqSAArwIxTWgfYCYsvpUjbJW02Mg0Ufj2+YhjT713\nO9yViwUq996St9eLwGQO5FDMD8FYi7bRAiZEAeAeIEeveDRsNK15++8VVJVo7b2l\nzcapp5k3bQKBgQDSiJNHRhqSet6+xgIIDGoZ+1Qv0TFPX5UrZt8OpsK7FshEOhXQ\nCxt8WZN03HHXK9fEC4GjwwxBrwYB+BOjCYiMHmCd3j0M3HoXgDrgViyYKMuVuDk8\nUG83r5ZbqVuCwfO8i/HbxddueEvtyiD2CZ47ZCIHxKOKAe0K4Mex2UBaKwKBgQDi\nrEouOelP9Kn5dyVhHENQXBTu9DIBb1FAnO5fxjMTWxFa5qhLuYHNbfxKF24atsRu\nBepNhJryFCkT0jvGv2L8Ry0wHiwqwvhO14obJ3ia3iBEQAVDlt+sV9L2KvGOpTB4\n/nlmIA4u02I1IBziw02aWYkGo0SOMUo0ZQL+2PEykQKBgAV1uqiJlWuA9uPdFFJP\nZPL2YoOuTWdWfIwIb/UdsbUuTckCgqPIqUPi3HhiVSunOgcO7HWK3GD3j8k4XEbW\nG4y+Ik0lLrWzBl728tZe1GENzTf8aapElHlUfFSM4OlrTRBsbMOsQBcJNh7QbyoZ\nBHiZZTbRUY6xUR4DGYkCOksF", Cb);
|
||||||
|
JSONObject jSONObject2 = new JSONObject();
|
||||||
|
jSONObject2.put("body", O);
|
||||||
|
jSONObject2.put("ticket", tg);
|
||||||
|
final JSONObject jSONObject3 = new JSONObject();
|
||||||
|
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "http://ctlook.facaishiyi.com/api/v1/search/page.do", jSONObject2.toString(), j(currentTimeMillis), new OKCallBack.OKCallBackString() { // from class: com.github.catvod.spider.Kuaikan.8
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str2) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject4 = new JSONObject(str2);
|
||||||
|
String lX = Kuaikan.this.lX("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiYJ5UFjeEgeUi5ynLKhj5EMF0\n3sawTyAKoPbfUCSZZQ5QdrHhrINggrYxDtB/TWXoqSF+BJP85F0vq8B6gOqFWhK/\n1PIKe2wKlRRuZSOdUzK/3vzRHmR3J3KGrvNzvwARH8gg8xZjbsalc/gBkcVxSxGd\n8j8rJ4QhOSFh9F8B2wIDAQAB", jSONObject4.getString("ticket"));
|
||||||
|
JSONObject jSONObject5 = new JSONObject(Kuaikan.this.UO(lX.substring(0, 16), lX.substring(16, 32), jSONObject4.getString("body")));
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
JSONArray jSONArray2 = jSONObject5.getJSONArray("results");
|
||||||
|
for (int i = 0; i < jSONArray2.length(); i++) {
|
||||||
|
JSONObject jSONObject6 = jSONArray2.getJSONObject(i);
|
||||||
|
JSONObject jSONObject7 = new JSONObject();
|
||||||
|
jSONObject7.put("vod_id", jSONObject6.getString("id"));
|
||||||
|
jSONObject7.put("vod_name", jSONObject6.getString("name"));
|
||||||
|
jSONObject7.put("vod_pic", jSONObject6.getString("pic"));
|
||||||
|
jSONArray.put(jSONObject7);
|
||||||
|
}
|
||||||
|
jSONObject3.put("list", jSONArray);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return jSONObject3.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String tg(String str, String str2) {
|
||||||
|
int i = 0;
|
||||||
|
try {
|
||||||
|
PrivateKey generatePrivate = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(str, 0)));
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||||
|
cipher.init(1, generatePrivate);
|
||||||
|
byte[] bytes = str2.getBytes();
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
if (bytes.length <= 256) {
|
||||||
|
byteArrayOutputStream.write(cipher.doFinal(bytes));
|
||||||
|
} else {
|
||||||
|
int length = bytes.length;
|
||||||
|
while (i < bytes.length) {
|
||||||
|
int i2 = i + 256;
|
||||||
|
byteArrayOutputStream.write(cipher.doFinal(bytes, i, i2 > length ? length - i : 256));
|
||||||
|
i = i2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byteArrayOutputStream.flush();
|
||||||
|
byteArrayOutputStream.close();
|
||||||
|
return Base64.encodeToString(byteArrayOutputStream.toByteArray(), 2);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,370 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author: @SDL
|
||||||
|
*/
|
||||||
|
public class Kunyu77 extends Spider {
|
||||||
|
private static final String siteUrl = "http://api.kunyu77.com";
|
||||||
|
|
||||||
|
private String uAgent = "Dalvik/2.1.0 (Linux; U; Android " + Build.VERSION.RELEASE + "; " + Build.MODEL + " Build/" + Build.ID + ")";
|
||||||
|
|
||||||
|
private HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("user-agent", uAgent);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/api.php/provide/filter";
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject jsonObject = new JSONObject(decryptResponse(content)).getJSONObject("data");
|
||||||
|
Iterator<String> keys = jsonObject.keys();
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
JSONObject filterConfig = new JSONObject();
|
||||||
|
JSONArray extendsAll = null;
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String typeId = keys.next();
|
||||||
|
String typeName = jsonObject.getJSONArray(typeId).getJSONObject(0).getString("cat");
|
||||||
|
JSONObject newCls = new JSONObject();
|
||||||
|
newCls.put("type_id", typeId);
|
||||||
|
newCls.put("type_name", typeName);
|
||||||
|
classes.put(newCls);
|
||||||
|
try {
|
||||||
|
if (extendsAll == null) {
|
||||||
|
String filterUrl = siteUrl + "/api.php/provide/searchFilter?type_id=0&pagenum=1&pagesize=1";
|
||||||
|
String filterContent = OkHttpUtil.string(filterUrl, getHeaders(filterUrl));
|
||||||
|
JSONObject filterObj = new JSONObject(filterContent).getJSONObject("data").getJSONObject("conditions");
|
||||||
|
extendsAll = new JSONArray();
|
||||||
|
// 年份
|
||||||
|
JSONObject newTypeExtend = new JSONObject();
|
||||||
|
newTypeExtend.put("key", "year");
|
||||||
|
newTypeExtend.put("name", "年份");
|
||||||
|
JSONArray newTypeExtendKV = new JSONArray();
|
||||||
|
JSONObject kv = new JSONObject();
|
||||||
|
kv.put("n", "全部");
|
||||||
|
kv.put("v", "");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "2022");
|
||||||
|
kv.put("v", "2022");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "2021");
|
||||||
|
kv.put("v", "2021");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
JSONArray years = filterObj.getJSONArray("y");
|
||||||
|
for (int j = 0; j < years.length(); j++) {
|
||||||
|
JSONObject child = years.getJSONObject(j);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", child.getString("name"));
|
||||||
|
kv.put("v", child.getString("value"));
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
}
|
||||||
|
newTypeExtend.put("value", newTypeExtendKV);
|
||||||
|
extendsAll.put(newTypeExtend);
|
||||||
|
// 地区
|
||||||
|
newTypeExtend = new JSONObject();
|
||||||
|
newTypeExtend.put("key", "area");
|
||||||
|
newTypeExtend.put("name", "地区");
|
||||||
|
newTypeExtendKV = new JSONArray();
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "全部");
|
||||||
|
kv.put("v", "");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
JSONArray areas = filterObj.getJSONArray("a");
|
||||||
|
for (int j = 0; j < areas.length(); j++) {
|
||||||
|
JSONObject child = areas.getJSONObject(j);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", child.getString("name"));
|
||||||
|
kv.put("v", child.getString("value"));
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
}
|
||||||
|
newTypeExtend.put("value", newTypeExtendKV);
|
||||||
|
extendsAll.put(newTypeExtend);
|
||||||
|
// 类型
|
||||||
|
newTypeExtend = new JSONObject();
|
||||||
|
newTypeExtend.put("key", "category");
|
||||||
|
newTypeExtend.put("name", "类型");
|
||||||
|
newTypeExtendKV = new JSONArray();
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "全部");
|
||||||
|
kv.put("v", "");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
JSONArray scat = filterObj.getJSONArray("scat");
|
||||||
|
for (int j = 0; j < scat.length(); j++) {
|
||||||
|
JSONObject child = scat.getJSONObject(j);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", child.getString("name"));
|
||||||
|
kv.put("v", child.getString("value"));
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
}
|
||||||
|
newTypeExtend.put("value", newTypeExtendKV);
|
||||||
|
extendsAll.put(newTypeExtend);
|
||||||
|
}
|
||||||
|
if (extendsAll != null && extendsAll.length() > 0) {
|
||||||
|
filterConfig.put(typeId, extendsAll);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("class", classes);
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/api.php/provide/homeBlock?type_id=0";
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject jsonObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("blocks");
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject blockObj = jsonArray.getJSONObject(i);
|
||||||
|
String blockName = blockObj.getString("block_name");
|
||||||
|
if (!blockName.startsWith("热播")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
JSONArray contents = blockObj.getJSONArray("contents");
|
||||||
|
for (int j = 0; j < contents.length() && j < 3; j++) {
|
||||||
|
JSONObject vObj = contents.getJSONObject(j);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("id"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("videoCover"));
|
||||||
|
v.put("vod_remarks", vObj.getString("msg"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/api.php/provide/searchFilter?type_id=" + tid + "&pagenum=" + pg + "&pagesize=24";
|
||||||
|
Set<String> keys = extend.keySet();
|
||||||
|
for (String key : keys) {
|
||||||
|
String val = extend.get(key).trim();
|
||||||
|
if (val.length() == 0)
|
||||||
|
continue;
|
||||||
|
url += "&" + key + "=" + URLEncoder.encode(val);
|
||||||
|
}
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject dataObject = new JSONObject(decryptResponse(content)).getJSONObject("data");
|
||||||
|
JSONArray jsonArray = dataObject.getJSONArray("result");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("id"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", vObj.getString("videoCover"));
|
||||||
|
v.put("vod_remarks", vObj.getString("msg"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int limit = 24;
|
||||||
|
int page = Integer.parseInt(dataObject.getString("page"));
|
||||||
|
int total = dataObject.getInt("total");
|
||||||
|
int pageCount = dataObject.getInt("pagesize");
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", limit);
|
||||||
|
result.put("total", total);
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/api.php/provide/videoDetail?ids=" + ids.get(0);
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject dataObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONObject vObj = dataObject.getJSONObject("data");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
String title = vObj.getString("videoName");
|
||||||
|
vodAtom.put("vod_id", vObj.getString("id"));
|
||||||
|
vodAtom.put("vod_name", title);
|
||||||
|
vodAtom.put("vod_pic", vObj.getString("videoCover"));
|
||||||
|
vodAtom.put("type_name", vObj.getString("subCategory"));
|
||||||
|
vodAtom.put("vod_year", vObj.getString("year"));
|
||||||
|
vodAtom.put("vod_area", vObj.getString("area"));
|
||||||
|
vodAtom.put("vod_remarks", vObj.getString("msg"));
|
||||||
|
vodAtom.put("vod_actor", vObj.getString("actor"));
|
||||||
|
vodAtom.put("vod_director", vObj.getString("director"));
|
||||||
|
vodAtom.put("vod_content", vObj.getString("brief").trim());
|
||||||
|
|
||||||
|
url = siteUrl + "/api.php/provide/videoPlaylist?ids=" + ids.get(0);
|
||||||
|
content = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONArray episodes = new JSONObject(content).getJSONObject("data").getJSONArray("episodes");
|
||||||
|
LinkedHashMap<String, ArrayList<String>> playlist = new LinkedHashMap<>();
|
||||||
|
for (int i = 0; i < episodes.length(); i++) {
|
||||||
|
JSONArray playurls = episodes.getJSONObject(i).getJSONArray("playurls");
|
||||||
|
for (int j = 0; j < playurls.length(); j++) {
|
||||||
|
JSONObject purl = playurls.getJSONObject(j);
|
||||||
|
String from = purl.getString("playfrom");
|
||||||
|
ArrayList<String> urls = playlist.get(from);
|
||||||
|
if (urls == null) {
|
||||||
|
urls = new ArrayList<>();
|
||||||
|
playlist.put(from, urls);
|
||||||
|
}
|
||||||
|
String name = purl.getString("title").replace(title, "").trim();
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
name = (i + 1) + "";
|
||||||
|
}
|
||||||
|
String pid = purl.getString("playurl");
|
||||||
|
urls.add(name + "$" + pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String vod_play_from = TextUtils.join("$$$", playlist.keySet());
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Iterator<ArrayList<String>> iter = playlist.values().iterator();
|
||||||
|
short fromSize = (short) playlist.size();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
fromSize--;
|
||||||
|
ArrayList<String> urls = iter.next();
|
||||||
|
sb.append(TextUtils.join("#", urls));
|
||||||
|
if (fromSize > 0)
|
||||||
|
sb.append("$$$");
|
||||||
|
}
|
||||||
|
vodAtom.put("vod_play_from", vod_play_from);
|
||||||
|
vodAtom.put("vod_play_url", sb.toString());
|
||||||
|
list.put(vodAtom);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
String videoUrl = id;
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/api.php/provide/parserUrl?url=" + id;
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject dataObj = new JSONObject(decryptResponse(content)).getJSONObject("data");
|
||||||
|
JSONObject playHeader = dataObj.optJSONObject("playHeader");
|
||||||
|
String jxUrl = dataObj.getString("url");
|
||||||
|
content = OkHttpUtil.string(jxUrl, getHeaders(jxUrl));
|
||||||
|
JSONObject result = Misc.jsonParse(jxUrl, content);
|
||||||
|
if (result != null) {
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
if (playHeader != null) {
|
||||||
|
JSONObject header = result.getJSONObject("header");
|
||||||
|
Iterator<String> iter = playHeader.keys();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
String key = iter.next();
|
||||||
|
header.put(key, " " + playHeader.getString(key));
|
||||||
|
}
|
||||||
|
result.put("header", header.toString());
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (Misc.isVip(videoUrl)) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("jx", "1");
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", id);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/api.php/provide/searchVideo?searchName=" + URLEncoder.encode(key);
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
JSONObject dataObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONArray jsonArray = dataObject.getJSONArray("data");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
String title = vObj.getString("videoName");
|
||||||
|
if (!title.contains(key))
|
||||||
|
continue;
|
||||||
|
v.put("vod_id", vObj.getString("id"));
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", vObj.getString("videoCover"));
|
||||||
|
v.put("vod_remarks", vObj.getString("msg"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String decryptResponse(String src) {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,504 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Lib extends Spider {
|
||||||
|
private static final String siteUrl = "https://www.libvio.me/";
|
||||||
|
private static final String siteHost = "www.libvio.me";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/type/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/detail/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/play/(\\d+)-(\\d+)-(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("/show/(\\S+).html");
|
||||||
|
|
||||||
|
protected String ext = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"LINE405\":{\"sh\":\"LINE405\",\"pu\":\"https://sh-data-s01.chinaeast2.cloudapp.chinacloudapi.cn/lb.php?url=\",\"sn\":1,\"or\":999},\"LINE406\":{\"sh\":\"LINE406\",\"pu\":\"https://sh-data-s01.chinaeast2.cloudapp.chinacloudapi.cn/zm.php?url=\",\"sn\":1,\"or\":999},\"LINE407\":{\"sh\":\"LINE407\",\"pu\":\"https://sh-data-s01.chinaeast2.cloudapp.chinacloudapi.cn/lb.php?url=\",\"sn\":1,\"or\":999},\"LINE408\":{\"sh\":\"LINE408\",\"pu\":\"\",\"sn\":0,\"or\":999},\"p300\":{\"sh\":\"LINE300\",\"pu\":\"\",\"sn\":0,\"or\":999},\"p301\":{\"sh\":\"LINE301\",\"pu\":\"\",\"sn\":0,\"or\":999},\"line402-日语\":{\"sh\":\"LINE402\",\"pu\":\"\",\"sn\":0,\"or\":999},\"LINE400\":{\"sh\":\"LINE400\",\"pu\":\"https://sh-data-s01.chinaeast2.cloudapp.chinacloudapi.cn/lb.php?url=\",\"sn\":1,\"or\":999},\"line401\":{\"sh\":\"LINE401\",\"pu\":\"\",\"sn\":0,\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"1\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"枪战\",\"v\":\"枪战\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"微电影\",\"v\":\"微电影\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"农村\",\"v\":\"农村\"},{\"n\":\"儿童\",\"v\":\"儿童\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"泰语\",\"v\":\"泰语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印度语\",\"v\":\"印度语\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"西班牙语\",\"v\":\"西班牙语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"泰语\",\"v\":\"泰语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印度语\",\"v\":\"印度语\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"西班牙语\",\"v\":\"西班牙语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国\",\"v\":\"中国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"15\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"16\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
headers.put("Referer", siteUrl);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul.stui-header__menu li a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = name.equals("电影") ||
|
||||||
|
name.equals("剧集") ||
|
||||||
|
name.equals("动漫") ||
|
||||||
|
name.equals("日韩剧") ||
|
||||||
|
name.equals("欧美剧");
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("ul.stui-vodlist").get(0);
|
||||||
|
Elements list = homeList.select("div.stui-vodlist__box");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.select("a").attr("title");
|
||||||
|
String cover = vod.select("a").attr("data-original");
|
||||||
|
String remark = vod.select("a .pic-text").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.select("a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||||
|
urlParams[0] = tid;
|
||||||
|
urlParams[8] = pg;
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取分类数据的url
|
||||||
|
String url = siteUrl + "show/" + TextUtils.join("-", urlParams) + ".html";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select("ul.stui-page__item li");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
String name = a.text();
|
||||||
|
if (page == -1 && li.hasClass("active")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
//System.out.println("哈哈"+matcher.group(1));
|
||||||
|
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.equals("尾页")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
//System.out.println("尾页" + matcher.group(1));
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("div.stui-vodlist__box");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.select("a").attr("title");
|
||||||
|
String cover = vod.select("a").attr("data-original");
|
||||||
|
String remark = vod.select("a .pic-text").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.select("a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 48);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/detail/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
String cover = doc.select("div.stui-content__thumb a img").attr("data-original");
|
||||||
|
String title = doc.select("div.stui-content__detail h1").text();
|
||||||
|
String category = "", area = "", year = "", remark = "", director = "", actor = "", desc = "";
|
||||||
|
Elements data = doc.select("p.data");
|
||||||
|
Pattern cate = Pattern.compile("类型:(\\S+)");
|
||||||
|
category = doReplaceRegex(cate, data.get(0).text());
|
||||||
|
Pattern areas = Pattern.compile("地区:(\\S+)");
|
||||||
|
area = doReplaceRegex(areas, data.get(0).text());
|
||||||
|
Pattern years = Pattern.compile("年份:(\\S+)");
|
||||||
|
year = doReplaceRegex(years, data.get(0).text());
|
||||||
|
Pattern rms = Pattern.compile("更新:(\\S+)");
|
||||||
|
remark = doReplaceRegex(rms, data.get(3).text());
|
||||||
|
Pattern acs = Pattern.compile("主演:(\\S+)");
|
||||||
|
actor = doReplaceRegex(acs, data.get(1).text());
|
||||||
|
Pattern dis = Pattern.compile("导演:(\\S+)");
|
||||||
|
director = doReplaceRegex(dis, data.get(1).text());
|
||||||
|
|
||||||
|
desc = doc.selectFirst("span.detail-content").text().trim();
|
||||||
|
|
||||||
|
vodList.put("vod_id", ids.get(0));
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.stui-vodlist__head h3");
|
||||||
|
Elements sourceList = doc.select("ul.stui-content__playlist");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.text();
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = flag;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("li a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
//定义播放用的headers
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
headers.put("origin", " https://www.libvio.me/");
|
||||||
|
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", " */*");
|
||||||
|
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||||
|
headers.put("Accept-Encoding", " gzip, deflate");
|
||||||
|
headers.put("referer", " https://www.libvio.me/");
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + "/play/" + id + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) { // 取直链
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
if (player.getString("from").contains("LINE")) {
|
||||||
|
String videoUrl = pCfg.getString("pu") + player.getString("url");
|
||||||
|
Document docs = Jsoup.parse(OkHttpUtil.string(videoUrl, Headers()));
|
||||||
|
Pattern pattern = Pattern.compile("(?<=urls\\s=\\s').*?(?=')");
|
||||||
|
Elements allScripts = docs.select("body script");
|
||||||
|
for (int j = 0; j < allScripts.size(); j++) {
|
||||||
|
String scContents = allScripts.get(j).html().trim();
|
||||||
|
Matcher matcher = pattern.matcher(scContents);
|
||||||
|
if (matcher.find()) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
String players = matcher.group(0);
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", players);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SpiderDebug.log(url);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", url);
|
||||||
|
// result.put("header", "{\"Referer\", \"https://www.libvio.me/\"}");
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String, String> sHeaders() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
|
||||||
|
headers.put("Accept-encoding", "gzip, deflate, br");
|
||||||
|
headers.put("Accept-language", "zh-SG,zh;q=0.9,en-GB;q=0.8,en;q=0.7,zh-CN;q=0.6");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String url = "https://shitu.paodekuaiweixinqun.com/search?q=site%3Alibvio.me%2Fdetail+" + URLEncoder.encode(key);
|
||||||
|
Document docs = Jsoup.parse(OkHttpUtil.string(url, sHeaders()));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
Elements list = docs.select("div.NJo7tc div.yuRUbf");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element doc = list.get(i);
|
||||||
|
String sourceName = doc.select("div.yuRUbf a h3").text();
|
||||||
|
if (sourceName.contains(key)) {
|
||||||
|
String list1 = doc.select("div.yuRUbf a").attr("href");
|
||||||
|
Document link = Jsoup.parse(OkHttpUtil.string(list1, getHeaders(url)));
|
||||||
|
Matcher matcher = regexVid.matcher(list1);
|
||||||
|
Elements data = link.select("p.data");
|
||||||
|
if (matcher.find()) {
|
||||||
|
|
||||||
|
String group = matcher.group(1);
|
||||||
|
String cover = link.select("div.stui-content__thumb a img").attr("data-original");
|
||||||
|
String title = link.select("div.stui-content__detail h1").text();
|
||||||
|
Pattern rms = Pattern.compile("更新:(\\S+)");
|
||||||
|
String remark = doReplaceRegex(rms, data.get(3).text());
|
||||||
|
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
v.put("vod_id", group);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||||
|
if (pattern == null)
|
||||||
|
return src;
|
||||||
|
try {
|
||||||
|
Matcher matcher = pattern.matcher(src);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).trim();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,466 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
|
||||||
|
public class LiteApple extends Spider {
|
||||||
|
private static final String siteUrl = "http://ht.grelighting.cn/api.php";
|
||||||
|
|
||||||
|
private HashMap<String, String> getHeaders(String url, String data) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
if (data != null) {
|
||||||
|
String token = "";
|
||||||
|
try {
|
||||||
|
token = Base64.encodeToString(b(fakeDevice.getBytes("UTF-8"), tokenKey == null ? "XPINGGUO" : tokenKey), 2);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
int currentTimeMillis = (int) (System.currentTimeMillis() / ((long) 1000));
|
||||||
|
String hash = md5(fakeDevice + data + currentTimeMillis).substring(8, 12);
|
||||||
|
headers.put("token", token);
|
||||||
|
headers.put("hash", hash);
|
||||||
|
headers.put("timestamp", currentTimeMillis + "");
|
||||||
|
if (tokenKey == null) {
|
||||||
|
headers.put("version", "ANDROID cn.grelighting.xpg1.1.5");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
headers.put("User-Agent", "okhttp/4.9.1");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fakeDevice = null;
|
||||||
|
private String tokenKey = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
SharedPreferences sharedPreferences = context.getSharedPreferences("spider_LiteApple", Context.MODE_PRIVATE);
|
||||||
|
try {
|
||||||
|
fakeDevice = sharedPreferences.getString("didd", null);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
} finally {
|
||||||
|
if (fakeDevice == null) {
|
||||||
|
fakeDevice = fakeDid();
|
||||||
|
sharedPreferences.edit().putString("didd", fakeDevice).commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getTokenKey() {
|
||||||
|
if (tokenKey != null)
|
||||||
|
return;
|
||||||
|
String url = siteUrl + "/v2.user/tokenlogin";
|
||||||
|
OkHttpUtil.post(OkHttpUtil.defaultClient(), url, null, getHeaders(url, "ANDROID cn.grelighting.xpg1.1.5"), new OKCallBack.OKCallBackString() {
|
||||||
|
@Override
|
||||||
|
protected void onFailure(Call call, Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResponse(String response) {
|
||||||
|
try {
|
||||||
|
tokenKey = new JSONObject(response).getJSONObject("data").getString("user_title");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
getTokenKey();
|
||||||
|
String url = siteUrl + "/v2.vod/androidtypes";
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url, null));
|
||||||
|
JSONObject jsonObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONArray jsonArray = jsonObject.getJSONArray("data");
|
||||||
|
|
||||||
|
JSONObject filterConfig = new JSONObject();
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject jObj = jsonArray.getJSONObject(i);
|
||||||
|
String typeName = jObj.getString("type_name");
|
||||||
|
String typeId = jObj.getString("type_id");
|
||||||
|
JSONObject newCls = new JSONObject();
|
||||||
|
newCls.put("type_id", typeId);
|
||||||
|
newCls.put("type_name", typeName);
|
||||||
|
classes.put(newCls);
|
||||||
|
|
||||||
|
JSONArray clses = jObj.getJSONArray("classes");
|
||||||
|
JSONArray areas = jObj.getJSONArray("areas");
|
||||||
|
JSONArray years = jObj.getJSONArray("years");
|
||||||
|
|
||||||
|
JSONArray extendsAll = new JSONArray();
|
||||||
|
// 类型
|
||||||
|
JSONObject newTypeExtend;
|
||||||
|
JSONArray newTypeExtendKV;
|
||||||
|
JSONObject kv;
|
||||||
|
newTypeExtend = new JSONObject();
|
||||||
|
newTypeExtend.put("key", "class");
|
||||||
|
newTypeExtend.put("name", "类型");
|
||||||
|
newTypeExtendKV = new JSONArray();
|
||||||
|
for (int j = 0; j < clses.length(); j++) {
|
||||||
|
String v = clses.getString(j);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", v);
|
||||||
|
kv.put("v", v);
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
}
|
||||||
|
newTypeExtend.put("value", newTypeExtendKV);
|
||||||
|
extendsAll.put(newTypeExtend);
|
||||||
|
// 地区
|
||||||
|
newTypeExtend = new JSONObject();
|
||||||
|
newTypeExtend.put("key", "area");
|
||||||
|
newTypeExtend.put("name", "地区");
|
||||||
|
newTypeExtendKV = new JSONArray();
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "全部");
|
||||||
|
kv.put("v", "");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
for (int j = 0; j < areas.length(); j++) {
|
||||||
|
String area = areas.getString(j);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", area);
|
||||||
|
kv.put("v", area);
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
}
|
||||||
|
newTypeExtend.put("value", newTypeExtendKV);
|
||||||
|
extendsAll.put(newTypeExtend);
|
||||||
|
// 年份
|
||||||
|
newTypeExtend = new JSONObject();
|
||||||
|
newTypeExtend.put("key", "year");
|
||||||
|
newTypeExtend.put("name", "年份");
|
||||||
|
newTypeExtendKV = new JSONArray();
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "全部");
|
||||||
|
kv.put("v", "");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
for (int j = 0; j < years.length(); j++) {
|
||||||
|
String year = years.getString(j);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", year);
|
||||||
|
kv.put("v", year);
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
}
|
||||||
|
newTypeExtend.put("value", newTypeExtendKV);
|
||||||
|
extendsAll.put(newTypeExtend);
|
||||||
|
filterConfig.put(typeId, extendsAll);
|
||||||
|
// 排序
|
||||||
|
newTypeExtend = new JSONObject();
|
||||||
|
newTypeExtend.put("key", "sortby");
|
||||||
|
newTypeExtend.put("name", "排序");
|
||||||
|
newTypeExtendKV = new JSONArray();
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "时间");
|
||||||
|
kv.put("v", "updatetime");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "人气");
|
||||||
|
kv.put("v", "hits");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
kv = new JSONObject();
|
||||||
|
kv.put("n", "评分");
|
||||||
|
kv.put("v", "score");
|
||||||
|
newTypeExtendKV.put(kv);
|
||||||
|
newTypeExtend.put("value", newTypeExtendKV);
|
||||||
|
extendsAll.put(newTypeExtend);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("class", classes);
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int id = 1; id < 5; id++) {
|
||||||
|
if (videos.length() > 30)
|
||||||
|
break;
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/v2.main/androidhome";
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url, null));
|
||||||
|
JSONObject jsonObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONArray jsonArraySub = jsonArray.getJSONObject(i).getJSONArray("list");
|
||||||
|
for (int j = 0; j < jsonArraySub.length() && j < 4; j++) {
|
||||||
|
JSONObject vObj = jsonArraySub.getJSONObject(j);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("id"));
|
||||||
|
v.put("vod_name", vObj.getString("name"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("updateInfo"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
getTokenKey();
|
||||||
|
String area = extend.containsKey("area") ? extend.get("area") : "";
|
||||||
|
String year = extend.containsKey("year") ? extend.get("year") : "";
|
||||||
|
String url = siteUrl + "/v2.vod/androidfilter?page=" + pg + "&type=" + tid;
|
||||||
|
Set<String> keys = extend.keySet();
|
||||||
|
for (String key : keys) {
|
||||||
|
String val = extend.get(key).trim();
|
||||||
|
if (val.length() == 0)
|
||||||
|
continue;
|
||||||
|
url += "&" + key + "=" + URLEncoder.encode(val);
|
||||||
|
}
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url, area + year));
|
||||||
|
JSONObject dataObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONArray jsonArray = dataObject.getJSONArray("data");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("id"));
|
||||||
|
v.put("vod_name", vObj.getString("name"));
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("updateInfo"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int limit = 20;
|
||||||
|
int page = Integer.parseInt(pg);
|
||||||
|
result.put("page", page);
|
||||||
|
int pageCount = videos.length() == limit ? page + 1 : page;
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", limit);
|
||||||
|
result.put("total", Integer.MAX_VALUE);
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/v2.vod/androiddetail?vod_id=" + ids.get(0);
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url, ids.get(0)));
|
||||||
|
JSONObject dataObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONObject vObj = dataObject.getJSONObject("data");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
vodAtom.put("vod_id", vObj.getString("id"));
|
||||||
|
vodAtom.put("vod_name", vObj.getString("name"));
|
||||||
|
vodAtom.put("vod_pic", vObj.getString("pic"));
|
||||||
|
vodAtom.put("type_name", vObj.getString("className"));
|
||||||
|
vodAtom.put("vod_year", vObj.getString("year"));
|
||||||
|
vodAtom.put("vod_area", vObj.getString("area"));
|
||||||
|
vodAtom.put("vod_remarks", vObj.getString("updateInfo"));
|
||||||
|
vodAtom.put("vod_actor", vObj.getString("actor"));
|
||||||
|
vodAtom.put("vod_content", vObj.getString("content").trim());
|
||||||
|
|
||||||
|
ArrayList<String> playUrls = new ArrayList<>();
|
||||||
|
|
||||||
|
JSONArray urls = vObj.getJSONArray("urls");
|
||||||
|
for (int i = 0; i < urls.length(); i++) {
|
||||||
|
JSONObject u = urls.getJSONObject(i);
|
||||||
|
playUrls.add(u.getString("key") + "$" + u.getString("url"));
|
||||||
|
}
|
||||||
|
|
||||||
|
vodAtom.put("vod_play_from", "LiteApple");
|
||||||
|
vodAtom.put("vod_play_url", TextUtils.join("#", playUrls));
|
||||||
|
list.put(vodAtom);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
if (Misc.isVideoFormat(id)) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("header", "");
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", id);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
getTokenKey();
|
||||||
|
String url = siteUrl + "/v2.vod/androidsearch?page=1&wd=" + URLEncoder.encode(key);
|
||||||
|
String content = OkHttpUtil.string(url, getHeaders(url, key));
|
||||||
|
JSONObject dataObject = new JSONObject(decryptResponse(content));
|
||||||
|
JSONArray jsonArray = dataObject.getJSONArray("data");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
String title = vObj.getString("name");
|
||||||
|
if (!title.contains(key))
|
||||||
|
continue;
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", vObj.getString("id"));
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", vObj.getString("pic"));
|
||||||
|
v.put("vod_remarks", vObj.getString("updateInfo"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String decryptResponse(String src) {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] a(String str) {
|
||||||
|
byte[] bytes = str.getBytes();
|
||||||
|
byte[] bArr = new byte[333];
|
||||||
|
for (int i9 = 0; i9 < 333; i9++) {
|
||||||
|
bArr[i9] = (byte) i9;
|
||||||
|
}
|
||||||
|
if (bytes.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int i10 = 0;
|
||||||
|
int i11 = 0;
|
||||||
|
for (int i12 = 0; i12 < 333; i12++) {
|
||||||
|
i11 = (((bytes[i10] & 255) + (bArr[i12] & 255)) + i11) % 333;
|
||||||
|
byte b = bArr[i12];
|
||||||
|
bArr[i12] = bArr[i11];
|
||||||
|
bArr[i11] = b;
|
||||||
|
i10 = (i10 + 1) % bytes.length;
|
||||||
|
}
|
||||||
|
return bArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] b(byte[] bArr, String str) {
|
||||||
|
byte[] a = a(str);
|
||||||
|
byte[] bArr2 = new byte[bArr.length];
|
||||||
|
int i9 = 0;
|
||||||
|
int i10 = 0;
|
||||||
|
for (int i11 = 0; i11 < bArr.length; i11++) {
|
||||||
|
i9 = (i9 + 1) % 333;
|
||||||
|
i10 = ((a[i9] & 255) + i10) % 333;
|
||||||
|
byte b = a[i9];
|
||||||
|
a[i9] = a[i10];
|
||||||
|
a[i10] = b;
|
||||||
|
bArr2[i11] = (byte) (a[((a[i9] & 255) + (a[i10] & 255)) % 333] ^ bArr[i11]);
|
||||||
|
}
|
||||||
|
return bArr2;
|
||||||
|
}
|
||||||
|
|
||||||
|
String randomString(int length) {
|
||||||
|
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456";
|
||||||
|
Random random = new Random();
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int number = random.nextInt(str.length());
|
||||||
|
sb.append(str.charAt(number));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String randomMACAddress() {
|
||||||
|
Random rand = new Random();
|
||||||
|
byte[] macAddr = new byte[6];
|
||||||
|
rand.nextBytes(macAddr);
|
||||||
|
macAddr[0] = (byte) (macAddr[0] & (byte) 254); //zeroing last 2 bytes to make it unicast and locally adminstrated
|
||||||
|
StringBuilder sb = new StringBuilder(18);
|
||||||
|
for (byte b : macAddr) {
|
||||||
|
sb.append(String.format("%02X", b));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String fakeDid() {
|
||||||
|
String i = "";
|
||||||
|
String f = "";
|
||||||
|
String d = "N/A";
|
||||||
|
try {
|
||||||
|
d = Build.class.getField("SERIAL").get((Object) null).toString();
|
||||||
|
} catch (Exception unused) {
|
||||||
|
}
|
||||||
|
String e = "";
|
||||||
|
try {
|
||||||
|
e = (String) Class.forName("android.os.SystemProperties").getDeclaredMethod("get", new Class[]{String.class}).invoke((Object) null, new Object[]{"ro.build.fingerprint"});
|
||||||
|
} catch (Exception unused) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return (((((((((("" + i) + "||") + f) + "||") + randomMACAddress()) + "||") + randomString(16)) + "||") + d) + "||") + e;
|
||||||
|
}
|
||||||
|
|
||||||
|
String md5(String str) {
|
||||||
|
try {
|
||||||
|
MessageDigest instance = MessageDigest.getInstance("MD5");
|
||||||
|
instance.update(str.getBytes());
|
||||||
|
return new BigInteger(1, instance.digest()).toString(16);
|
||||||
|
} catch (Exception e9) {
|
||||||
|
e9.printStackTrace();
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,503 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Nfyun extends Spider {
|
||||||
|
private static final String siteUrl = "https://yanaifei.cn";
|
||||||
|
private static final String siteHost = "yanaifei.cn";
|
||||||
|
private static Pattern pic = Pattern.compile("(?<=url=).*");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/vod/type/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/vod/detail/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/vod/play/(\\d+)-(\\d+)-(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("/vod/show/(\\S+).html");
|
||||||
|
|
||||||
|
protected String ext = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"VIP\":{\"sh\":\"VIP\",\"pu\":\"https://yanaifei.cn/player/?url=\",\"sn\":0,\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"1\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"1\"},{\"n\":\"动作片\",\"v\":\"6\"},{\"n\":\"喜剧片\",\"v\":\"7\"},{\"n\":\"爱情片\",\"v\":\"8\"},{\"n\":\"科幻片\",\"v\":\"9\"},{\"n\":\"恐怖片\",\"v\":\"10\"},{\"n\":\"剧情片\",\"v\":\"11\"},{\"n\":\"战争片\",\"v\":\"12\"},{\"n\":\"动画片\",\"v\":\"32\"}]},{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"枪战\",\"v\":\"枪战\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"微电影\",\"v\":\"微电影\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"农村\",\"v\":\"农村\"},{\"n\":\"儿童\",\"v\":\"儿童\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"普通话\",\"v\":\"普通话\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"2\"},{\"n\":\"国产剧\",\"v\":\"13\"},{\"n\":\"港台剧\",\"v\":\"14\"},{\"n\":\"日韩剧\",\"v\":\"15\"},{\"n\":\"欧美剧\",\"v\":\"16\"},{\"n\":\"泰国剧\",\"v\":\"20\"}]},{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"普通话\",\"v\":\"普通话\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"3\"},{\"n\":\"大陆综艺\",\"v\":\"22\"},{\"n\":\"港台综艺\",\"v\":\"23\"},{\"n\":\"日韩综艺\",\"v\":\"24\"},{\"n\":\"欧美综艺\",\"v\":\"25\"}]},{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"旅游\",\"v\":\"旅游\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"游戏互动\",\"v\":\"游戏互动\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"求职\",\"v\":\"求职\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"普通话\",\"v\":\"普通话\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"4\"},{\"n\":\"大陆动漫\",\"v\":\"26\"},{\"n\":\"港台动漫\",\"v\":\"27\"},{\"n\":\"日韩动漫\",\"v\":\"28\"},{\"n\":\"欧美动漫\",\"v\":\"29\"}]},{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"普通话\",\"v\":\"普通话\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":5,\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"},{\"n\":\"0-9\",\"v\":\"0-9\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
headers.put("Referer", siteUrl);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
Pattern redL = Pattern.compile("(?<=location.href =\").*?(?=\")");
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
/* Elements X = A.select("script");
|
||||||
|
String url = "";
|
||||||
|
for (int i = 0; i < X.size(); i++) {
|
||||||
|
String finalUrl = X.get(i).html().trim();
|
||||||
|
Matcher matcher3 = redL.matcher(finalUrl);
|
||||||
|
if (matcher3.find()) {
|
||||||
|
url = siteUrl + matcher3.group(0);
|
||||||
|
} else {
|
||||||
|
url = siteUrl;
|
||||||
|
}
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url))); */
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul.navbar-items li a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.attr("title");
|
||||||
|
boolean show = name.equals("电影") ||
|
||||||
|
name.equals("连续剧") ||
|
||||||
|
name.equals("综艺") ||
|
||||||
|
name.equals("动漫");
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("div.module").get(0);
|
||||||
|
Elements list = homeList.select("div.module-main div.module-items a");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int j = 0; j < list.size(); j++) {
|
||||||
|
Element vod = list.get(j);
|
||||||
|
String title = vod.attr("title");
|
||||||
|
String cover = FixUrl(pic, vod.select("div.module-item-pic img").attr("data-original"));
|
||||||
|
String remark = vod.select("div.module-item-note").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||||
|
urlParams[0] = tid;
|
||||||
|
urlParams[8] = pg;
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取分类数据的url
|
||||||
|
String url = siteUrl + "/vod/show/" + TextUtils.join("-", urlParams) + ".html";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select("div[id=page]");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
String span = doc.select("span.page-current").text();
|
||||||
|
String wy = doc.select("div[id=page] a").last().attr("href");
|
||||||
|
if (page == -1) {
|
||||||
|
page = Integer.parseInt(span);
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
Matcher matcher = regexPage.matcher(wy);
|
||||||
|
if (matcher.find()) {
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("div.module-main div.module-items a");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.attr("title");
|
||||||
|
String cover = FixUrl(pic, vod.select("div.module-item-pic img").attr("data-original"));
|
||||||
|
String remark = vod.select("div.module-item-note").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 48);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/vod/detail/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
String cover = FixUrl(pic, doc.selectFirst("div.module-info-poster div div img").attr("data-original"));
|
||||||
|
String title = doc.selectFirst("div.module-info-heading h1").text();
|
||||||
|
|
||||||
|
String category = "", area = "", year = "", director = "", actor = "", remark = "", desc = "";
|
||||||
|
|
||||||
|
category = doc.select("div.module-info-tag-link").get(2).text();
|
||||||
|
year = doc.select("div.module-info-tag-link a").get(0).text();
|
||||||
|
area = doc.select("div.module-info-tag-link a").get(1).text();
|
||||||
|
desc = doc.select("div.module-info-introduction-content p").text();
|
||||||
|
|
||||||
|
Elements span_text_muted = doc.select("div.module-info-item span");
|
||||||
|
for (int i = 0; i < span_text_muted.size() - 2; i++) {
|
||||||
|
Element Spantext = span_text_muted.get(i);
|
||||||
|
String info = Spantext.text();
|
||||||
|
if (info.contains("更新:")) {
|
||||||
|
try {
|
||||||
|
remark = Spantext.parent().select("div").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
remark = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("导演:")) {
|
||||||
|
try {
|
||||||
|
director = Spantext.parent().select("div a").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
director = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("主演:")) {
|
||||||
|
try {
|
||||||
|
actor = Spantext.parent().select("div a").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
actor = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vodList.put("vod_id", ids.get(0));
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.module-tab-items-box div span");
|
||||||
|
Elements sourceList = doc.select("div.module-play-list");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.text();
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = flag;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("div a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||||
|
String vodName = vod.select("span").text();
|
||||||
|
vodItems.add(vodName + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
//定义播放用的headers
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
//headers.put("Host", " cokemv.co");
|
||||||
|
headers.put("origin", siteUrl);
|
||||||
|
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", " */*");
|
||||||
|
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||||
|
headers.put("Accept-Encoding", " gzip, deflate");
|
||||||
|
|
||||||
|
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + "/vod/play/" + id + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) { // 取直链
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
String videoUrl = pCfg.getString("pu") + player.getString("url");
|
||||||
|
Document docs = Jsoup.parse(OkHttpUtil.string(videoUrl, getHeaders(videoUrl)));
|
||||||
|
Pattern pattern = Pattern.compile("(?<=url\"\\S\").*?(?=\")");
|
||||||
|
Elements allScripts = docs.select("body script");
|
||||||
|
for (int j = 0; j < allScripts.size(); j++) {
|
||||||
|
String scContents = allScripts.get(j).html().trim();
|
||||||
|
Matcher matcher = pattern.matcher(scContents);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String players = matcher.group(0);
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", players);
|
||||||
|
result.put("header", headers.toString());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||||
|
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (searchResult.getInt("total") > 0) {
|
||||||
|
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||||
|
for (int i = 0; i < lists.length(); i++) {
|
||||||
|
JSONObject vod = lists.getJSONObject(i);
|
||||||
|
String id = vod.getString("id");
|
||||||
|
String title = vod.getString("name");
|
||||||
|
String cover = vod.getString("pic");
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", "");
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String FixUrl(Pattern pattern, String src) {
|
||||||
|
if (pattern == null)
|
||||||
|
return src;
|
||||||
|
try {
|
||||||
|
Matcher matcher = pattern.matcher(src);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(0).trim();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,503 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Olevod extends Spider {
|
||||||
|
private static final String siteUrl = "https://olevod.com";
|
||||||
|
private static final String siteHost = "olevod.com";
|
||||||
|
|
||||||
|
|
||||||
|
boolean pron = false;
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/index.php/vod/type/id/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/index.php/vod/detail/id/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/index.php/vod/play/id/(\\d+)/sid/(\\d+)/nid/(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
if (extend != null && extend.trim().equals("ojbkporn")) {
|
||||||
|
pron = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"plyr\":{\"sh\":\"欧乐官方播放器\",\"sn\":0,\"pu\":\"\",\"or\":999},\"openplayer\":{\"sh\":\"欧乐影院\",\"sn\":0,\"pu\":\"\",\"or\":999},\"videojs\":{\"sh\":\"欧乐直播播放\",\"sn\":0,\"pu\":\"\",\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"1\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"动作片\",\"v\":\"101\"},{\"n\":\"喜剧片\",\"v\":\"102\"},{\"n\":\"爱情片\",\"v\":\"103\"},{\"n\":\"科幻片\",\"v\":\"104\"},{\"n\":\"恐怖片\",\"v\":\"105\"},{\"n\":\"剧情片\",\"v\":\"106\"},{\"n\":\"战争片\",\"v\":\"107\"},{\"n\":\"动画片\",\"v\":\"108\"},{\"n\":\"悬疑片\",\"v\":\"109\"},{\"n\":\"惊悚片\",\"v\":\"110\"},{\"n\":\"纪录片\",\"v\":\"111\"},{\"n\":\"奇幻片\",\"v\":\"112\"},{\"n\":\"犯罪片\",\"v\":\"113\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"2\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产剧\",\"v\":\"202\"},{\"n\":\"欧美剧\",\"v\":\"201\"},{\"n\":\"港台剧\",\"v\":\"203\"},{\"n\":\"日韩剧\",\"v\":\"204\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"3\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"真人秀\",\"v\":\"305\"},{\"n\":\"音乐\",\"v\":\"302\"},{\"n\":\"搞笑\",\"v\":\"304\"},{\"n\":\"家庭\",\"v\":\"301\"},{\"n\":\"曲艺\",\"v\":\"303\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"4\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"日本\",\"v\":\"401\"},{\"n\":\"国产\",\"v\":\"402\"},{\"n\":\"欧美\",\"v\":\"403\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"5\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"AV女优\",\"v\":\"505\"},{\"n\":\"日韩\",\"v\":\"502\"},{\"n\":\"欧美\",\"v\":\"501\"},{\"n\":\"动漫\",\"v\":\"503\"},{\"n\":\"国产\",\"v\":\"504\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Host", siteHost);
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul.top_nav li a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = name.equals("电影") ||
|
||||||
|
name.equals("连续剧") ||
|
||||||
|
name.equals("动漫") ||
|
||||||
|
name.equals("综艺") ||
|
||||||
|
name.equals("午夜影院");
|
||||||
|
|
||||||
|
if (name.equals("午夜影院") && !pron) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("div.cbox1").get(0);
|
||||||
|
Elements list = homeList.select("ul.vodlist li.vodlist_item");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst("a.vodlist_thumb").attr("title");
|
||||||
|
String cover = siteUrl + vod.selectFirst("a.vodlist_thumb").attr("data-original");
|
||||||
|
String remark = "";
|
||||||
|
try {
|
||||||
|
remark = vod.select("span.pic_text em").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
remark = vod.select("span.text_dy").get(0).text();
|
||||||
|
}
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst("a.vodlist_thumb").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/index.php/vod/show/id/";
|
||||||
|
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||||
|
url += extend.get("tid");
|
||||||
|
} else {
|
||||||
|
url += tid;
|
||||||
|
}
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url += "/page/" + pg + ".html";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select("ul.page");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("li a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
String span = pageInfo.select("li.active a").text();
|
||||||
|
String wy = doc.select("ul.page li a").last().attr("href");
|
||||||
|
if (page == -1) {
|
||||||
|
page = Integer.parseInt(span);
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
Matcher matcher = regexPage.matcher(wy);
|
||||||
|
if (matcher.find()) {
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("ul.vodlist li.vodlist_item");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst("a.vodlist_thumb").attr("title");
|
||||||
|
String cover = siteUrl + vod.selectFirst("a.vodlist_thumb").attr("data-original");
|
||||||
|
String remark = "";
|
||||||
|
try {
|
||||||
|
remark = vod.select("span.pic_text em").text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
remark = vod.select("span.text_dy").get(0).text();
|
||||||
|
}
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst("a.vodlist_thumb").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 20);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 20);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/index.php/vod/detail/id/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
String vid = doc.selectFirst("a.digg_link").attr("data-id");
|
||||||
|
|
||||||
|
String cover = siteUrl + doc.selectFirst("div.content_thumb a").attr("data-original");
|
||||||
|
String title = doc.selectFirst("div.content_thumb a").attr("title");
|
||||||
|
String desc = doc.selectFirst("div.context span").text();
|
||||||
|
String category = "", area = "", year = "", director = "", actor = "", remark = "";
|
||||||
|
remark = doc.select("span.data_style").text();
|
||||||
|
Elements span_text_muted = doc.select("li.data span");
|
||||||
|
for (int i = 0; i < span_text_muted.size() - 2; i++) {
|
||||||
|
Element text = span_text_muted.get(i);
|
||||||
|
String info = text.text();
|
||||||
|
if (info.contains("类型")) {
|
||||||
|
try {
|
||||||
|
category = text.parent().select("a").get(2).text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
category = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("年份")) {
|
||||||
|
try {
|
||||||
|
year = text.parent().select("a").get(0).text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
year = "";
|
||||||
|
}
|
||||||
|
} else if (info.contains("地区")) {
|
||||||
|
try {
|
||||||
|
area = text.parent().select("a").get(1).text();
|
||||||
|
} catch (Exception e) {
|
||||||
|
area = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<String> actors = new ArrayList<>();
|
||||||
|
Elements aa = doc.select("li.data").get(3).select("a");
|
||||||
|
for (int j = 0; j < aa.size(); j++) {
|
||||||
|
actors.add(aa.get(j).text());
|
||||||
|
}
|
||||||
|
actor = TextUtils.join(",", actors);
|
||||||
|
List<String> directors = new ArrayList<>();
|
||||||
|
Elements bb = doc.select("li.data").get(2).select("a");
|
||||||
|
for (int j = 0; j < bb.size(); j++) {
|
||||||
|
directors.add(bb.get(j).text());
|
||||||
|
}
|
||||||
|
director = TextUtils.join(",", directors);
|
||||||
|
|
||||||
|
|
||||||
|
vodList.put("vod_id", vid);
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.play_source_tab a");
|
||||||
|
Elements sourceList = doc.select("div.playlist_full");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.attr("alt");
|
||||||
|
sourceName = sourceName.replaceAll("[^\u4E00-\u9FA5]", "");
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = flag;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "/sid/" + matcher.group(2) + "/nid/" + matcher.group(3);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + "/index.php/vod/play/id/" + id + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) { // 取直链
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
String videoUrl = player.getString("url");
|
||||||
|
String playUrl = pCfg.getString("pu");
|
||||||
|
result.put("parse", pCfg.getInt("sn"));
|
||||||
|
result.put("playUrl", playUrl);
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
result.put("header", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||||
|
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (searchResult.getInt("total") > 0) {
|
||||||
|
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||||
|
for (int i = 0; i < lists.length(); i++) {
|
||||||
|
JSONObject vod = lists.getJSONObject(i);
|
||||||
|
String id = vod.getString("id");
|
||||||
|
String title = vod.getString("name");
|
||||||
|
String cover = vod.getString("pic");
|
||||||
|
if (title.contains(key)) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", "");
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||||
|
if (pattern == null)
|
||||||
|
return src;
|
||||||
|
try {
|
||||||
|
Matcher matcher = pattern.matcher(src);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).trim();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.live.TxtSubscribe;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Proxy extends Spider {
|
||||||
|
|
||||||
|
public static int localPort = -1;
|
||||||
|
|
||||||
|
static void adjustLocalPort() {
|
||||||
|
if (localPort > 0)
|
||||||
|
return;
|
||||||
|
int port = 9978;
|
||||||
|
while (port < 10000) {
|
||||||
|
String resp = OkHttpUtil.string("http://127.0.0.1:" + port + "/proxy?do=ck", null);
|
||||||
|
if (resp.equals("ok")) {
|
||||||
|
SpiderDebug.log("Found local server port " + port);
|
||||||
|
localPort = port;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
port++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String localProxyUrl() {
|
||||||
|
adjustLocalPort();
|
||||||
|
return "http://127.0.0.1:" + Proxy.localPort + "/proxy";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] proxy(Map<String, String> params) {
|
||||||
|
try {
|
||||||
|
String what = params.get("do");
|
||||||
|
if (what.equals("live")) {
|
||||||
|
String type = params.get("type");
|
||||||
|
if (type.equals("txt")) {
|
||||||
|
String ext = params.get("ext");
|
||||||
|
if (!ext.startsWith("http")) {
|
||||||
|
ext = new String(Base64.decode(ext, Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");
|
||||||
|
}
|
||||||
|
return TxtSubscribe.load(ext);
|
||||||
|
}
|
||||||
|
} else if (what.equals("ck")) {
|
||||||
|
Object[] result = new Object[3];
|
||||||
|
result[0] = 200;
|
||||||
|
result[1] = "text/plain; charset=utf-8";
|
||||||
|
ByteArrayInputStream baos = new ByteArrayInputStream("ok".getBytes("UTF-8"));
|
||||||
|
result[2] = baos;
|
||||||
|
return result;
|
||||||
|
} else if (what.equals("push")) {
|
||||||
|
return PushAgent.vod(params);
|
||||||
|
} else if (what.equals("czspp")) {
|
||||||
|
return Czsapp.loadsub(params.get("url"));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,656 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.UrlQuerySanitizer;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
|
public class PushAgent extends Spider {
|
||||||
|
|
||||||
|
private static String j = "";
|
||||||
|
private static long StopRefresh;
|
||||||
|
private static final Map<String, String> l = new HashMap();
|
||||||
|
private static final Map<String, Long> q = new HashMap();
|
||||||
|
private static final Map<String, Map<String, String>> dizz = new HashMap();
|
||||||
|
private static final ReentrantLock ReentrantLock = new ReentrantLock();
|
||||||
|
private static final long n = 0;
|
||||||
|
private static final String SiteUrl = "https://api.aliyundrive.com";
|
||||||
|
private static final Pattern AliPLink = Pattern.compile("(https://www.aliyundrive.com/s/[^\"]+)");
|
||||||
|
public static Pattern Folder = Pattern.compile("www.aliyundrive.com/s/([^/]+)(/folder/([^/]+))?");
|
||||||
|
public static String Token;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
if (extend.startsWith("http")) {
|
||||||
|
Token = OkHttpUtil.string(extend, null);
|
||||||
|
} else {
|
||||||
|
Token = extend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static long Time() {
|
||||||
|
return (System.currentTimeMillis() / 1000) + n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] ProxyMedia(Map<String, String> map) {
|
||||||
|
try {
|
||||||
|
String ShareId = map.get("share_id");
|
||||||
|
String FileId = map.get("file_id");
|
||||||
|
String MediaId = map.get("media_id");
|
||||||
|
String Token = getShareTk(ShareId, "");
|
||||||
|
ReentrantLock.lock();
|
||||||
|
String str4 = dizz.get(FileId).get(MediaId);
|
||||||
|
UrlQuerySanitizer urlQuerySanitizer = new UrlQuerySanitizer(str4);
|
||||||
|
Long l2 = new Long(urlQuerySanitizer.getValue("x-oss-expires"));
|
||||||
|
long longValue = l2.longValue();
|
||||||
|
if (longValue - Time() <= 60) {
|
||||||
|
VideoDetail(ShareId, Token, FileId);
|
||||||
|
Map<String, Map<String, String>> map3 = dizz;
|
||||||
|
str4 = map3.get(FileId).get(MediaId);
|
||||||
|
}
|
||||||
|
ReentrantLock.unlock();
|
||||||
|
new HashMap();
|
||||||
|
OKCallBack.OKCallBackDefault abVar = new OKCallBack.OKCallBackDefault() {
|
||||||
|
public void onResponse(Response response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OkHttpClient YM = OkHttpUtil.defaultClient();
|
||||||
|
HashMap<String, String> t = Headers();
|
||||||
|
OkHttpUtil.get(YM, str4, null, t, abVar);
|
||||||
|
ResponseBody body = abVar.getResult().body();
|
||||||
|
return new Object[]{200, "video/MP2T", body.byteStream()};
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] vod(Map<String, String> map) {
|
||||||
|
String str = map.get("type");
|
||||||
|
if (str.equals("m3u8")) {
|
||||||
|
return getFile(map);
|
||||||
|
}
|
||||||
|
if (str.equals("media")) {
|
||||||
|
return ProxyMedia(map);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Object[] getFile(Map<String, String> map) {
|
||||||
|
try {
|
||||||
|
String ShareId = map.get("share_id");
|
||||||
|
String ShareTK = getShareTk(ShareId, "");
|
||||||
|
return new Object[]{200, "application/octet-stream", new ByteArrayInputStream(VideoDetail(ShareId, ShareTK, map.get("file_id")).getBytes())};
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String Post(String str, String str2, Map<String, String> map) {
|
||||||
|
OKCallBack.OKCallBackString acVar = new OKCallBack.OKCallBackString() {
|
||||||
|
|
||||||
|
public void onResponse(String r) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OkHttpClient YM = OkHttpUtil.defaultClient();
|
||||||
|
OkHttpUtil.postJson(YM, str, str2, map, acVar);
|
||||||
|
return acVar.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized String getShareTk(String str, String str2) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
long b = Time();
|
||||||
|
Map<String, String> map = l;
|
||||||
|
String str3 = map.get(str);
|
||||||
|
Long l2 = q.get(str);
|
||||||
|
if (!TextUtils.isEmpty(str3)) {
|
||||||
|
if (l2 - b > 600) {
|
||||||
|
return str3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
jSONObject.put("share_id", str);
|
||||||
|
jSONObject.put("share_pwd", str2);
|
||||||
|
String jSONObject2 = jSONObject.toString();
|
||||||
|
JSONObject jSONObject3 = new JSONObject(Post("https://api.aliyundrive.com/v2/share_link/get_share_token", jSONObject2, Headers()));
|
||||||
|
String string = jSONObject3.getString("share_token");
|
||||||
|
Long valueOf = Long.valueOf(b + jSONObject3.getLong("expires_in"));
|
||||||
|
Map<String, Long> map2 = q;
|
||||||
|
map2.put(str, valueOf);
|
||||||
|
Map<String, String> map3 = l;
|
||||||
|
map3.put(str, string);
|
||||||
|
return string;
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36");
|
||||||
|
headers.put("Referer", "https://www.aliyundrive.com/");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HashMap<String, String> sHeaders() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void refreshTk() {
|
||||||
|
long b = Time();
|
||||||
|
String str = j;
|
||||||
|
if (str.isEmpty() || StopRefresh - b <= 600) {
|
||||||
|
try {
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
jSONObject.put("refresh_token", Token);
|
||||||
|
String jSONObject2 = jSONObject.toString();
|
||||||
|
HashMap<String, String> t = Headers();
|
||||||
|
JSONObject jSONObject3 = new JSONObject(Post("https://api.aliyundrive.com/token/refresh", jSONObject2, t));
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String string = jSONObject3.getString("token_type");
|
||||||
|
sb.append(string);
|
||||||
|
sb.append(" ");
|
||||||
|
String string2 = jSONObject3.getString("access_token");
|
||||||
|
sb.append(string2);
|
||||||
|
j = sb.toString();
|
||||||
|
long j2 = jSONObject3.getLong("expires_in");
|
||||||
|
StopRefresh = b + j2;
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String VideoDetail(String shareid, String token, String fileid) {
|
||||||
|
int i;
|
||||||
|
try {
|
||||||
|
String url = SiteUrl + "/v2/file/get_share_link_video_preview_play_info";
|
||||||
|
JSONObject Data = new JSONObject();
|
||||||
|
Data.put("share_id", shareid);
|
||||||
|
Data.put("category", "live_transcoding");
|
||||||
|
Data.put("file_id", fileid);
|
||||||
|
Data.put("template_id", "");
|
||||||
|
HashMap<String, String> headers = Headers();
|
||||||
|
headers.put("x-share-token", token);
|
||||||
|
String str5 = j;
|
||||||
|
headers.put("authorization", str5);
|
||||||
|
String jSONObject2 = Data.toString();
|
||||||
|
JSONObject jSONObject3 = new JSONObject(Post(url, jSONObject2, headers));
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
arrayList.add("FHD");
|
||||||
|
arrayList.add("HD");
|
||||||
|
arrayList.add("SD");
|
||||||
|
JSONObject jSONObject4 = jSONObject3.getJSONObject("video_preview_play_info");
|
||||||
|
JSONArray jSONArray = jSONObject4.getJSONArray("live_transcoding_task_list");
|
||||||
|
Iterator it = arrayList.iterator();
|
||||||
|
String objectUrl = "";
|
||||||
|
while (true) {
|
||||||
|
boolean hasNext = it.hasNext();
|
||||||
|
i = 0;
|
||||||
|
if (!hasNext) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String str7 = (String) it.next();
|
||||||
|
if (!objectUrl.isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
if (i < jSONArray.length()) {
|
||||||
|
JSONObject jSONObject5 = jSONArray.getJSONObject(i);
|
||||||
|
String string = jSONObject5.getString("template_id");
|
||||||
|
if (string.equals(str7)) {
|
||||||
|
objectUrl = jSONObject5.getString("url");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TextUtils.isEmpty(objectUrl)) {
|
||||||
|
JSONObject jSONObject6 = jSONArray.getJSONObject(0);
|
||||||
|
objectUrl = jSONObject6.getString("url");
|
||||||
|
}
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
HashMap<String, String> header = Headers();
|
||||||
|
OkHttpUtil.stringNoRedirect(objectUrl, header, hashMap);
|
||||||
|
String d = OkHttpUtil.getRedirectLocation(hashMap);
|
||||||
|
String i2 = OkHttpUtil.string(d, Headers());
|
||||||
|
String substring = d.substring(0, d.lastIndexOf("/")) + "/";
|
||||||
|
ArrayList arrayList2 = new ArrayList();
|
||||||
|
HashMap hashMap2 = new HashMap();
|
||||||
|
String[] split = i2.split("\n");
|
||||||
|
int length = split.length;
|
||||||
|
int i3 = 0;
|
||||||
|
while (i < length) {
|
||||||
|
String str8 = split[i];
|
||||||
|
if (str8.contains("x-oss-expires")) {
|
||||||
|
i3++;
|
||||||
|
String sb6 = substring + str8;
|
||||||
|
String sb8 = "" + i3;
|
||||||
|
hashMap2.put(sb8, sb6);
|
||||||
|
str8 = Proxy.localProxyUrl() + "?do=push&type=media&share_id=" + shareid + "&file_id=" + fileid + "&media_id=" + i3;
|
||||||
|
}
|
||||||
|
arrayList2.add(str8);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dizz.put(fileid, hashMap2);
|
||||||
|
return TextUtils.join("\n", arrayList2);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void listFiles(Map<String, String> map, String str, String str2, String str3) {
|
||||||
|
String str4;
|
||||||
|
try {
|
||||||
|
String str5 = "https://api.aliyundrive.com/adrive/v3/file/list";
|
||||||
|
HashMap<String, String> Y2 = Headers();
|
||||||
|
Y2.put("x-share-token", str2);
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
jSONObject.put("image_thumbnail_process", "image/resize,w_160/format,jpeg");
|
||||||
|
jSONObject.put("image_url_process", "image/resize,w_1920/format,jpeg");
|
||||||
|
jSONObject.put("limit", 200);
|
||||||
|
jSONObject.put("order_by", "updated_at");
|
||||||
|
jSONObject.put("order_direction", "DESC");
|
||||||
|
jSONObject.put("parent_file_id", str3);
|
||||||
|
jSONObject.put("share_id", str);
|
||||||
|
jSONObject.put("video_thumbnail_process", "video/snapshot,t_1000,f_jpg,ar_auto,w_300");
|
||||||
|
String str6 = "";
|
||||||
|
ArrayList<String> arrayList = new ArrayList();
|
||||||
|
for (int i = 1; i <= 50 && (i < 2 || !TextUtils.isEmpty(str6)); i++) {
|
||||||
|
jSONObject.put("marker", str6);
|
||||||
|
JSONObject jSONObject2 = new JSONObject(Post(str5, jSONObject.toString(), Y2));
|
||||||
|
JSONArray jSONArray = jSONObject2.getJSONArray("items");
|
||||||
|
int i2 = 0;
|
||||||
|
while (i2 < jSONArray.length()) {
|
||||||
|
JSONObject jSONObject3 = jSONArray.getJSONObject(i2);
|
||||||
|
if (jSONObject3.getString("type").equals("folder")) {
|
||||||
|
arrayList.add(jSONObject3.getString("file_id"));
|
||||||
|
str4 = str5;
|
||||||
|
} else {
|
||||||
|
str4 = str5;
|
||||||
|
if (jSONObject3.getString("mime_type").contains("video")) {
|
||||||
|
String replace = jSONObject3.getString("name").replace("#", "_").replace("$", "_");
|
||||||
|
if (replace.length() > 20) {
|
||||||
|
replace = replace.substring(0, 10) + "..." + replace.substring(replace.length() - 10);
|
||||||
|
}
|
||||||
|
String fileIds = jSONObject3.getString("file_id");
|
||||||
|
map.put(replace, str + "+" + str2 + "+" + fileIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i2++;
|
||||||
|
str5 = str4;
|
||||||
|
}
|
||||||
|
str6 = jSONObject2.getString("next_marker");
|
||||||
|
}
|
||||||
|
for (String str7 : arrayList) {
|
||||||
|
try {
|
||||||
|
listFiles(map, str, str2, str7);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAliContent(List<String> list) {
|
||||||
|
String str;
|
||||||
|
try {
|
||||||
|
String url = list.get(0).trim();
|
||||||
|
Pattern pattern = Folder;
|
||||||
|
Matcher matcher = pattern.matcher(url);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String group = matcher.group(1);
|
||||||
|
if (matcher.groupCount() == 3) {
|
||||||
|
str = matcher.group(3);
|
||||||
|
} else {
|
||||||
|
str = "";
|
||||||
|
}
|
||||||
|
String AnonymousUrl = SiteUrl + "/adrive/v3/share_link/get_share_by_anonymous";
|
||||||
|
JSONObject Data = new JSONObject();
|
||||||
|
Data.put("share_id", group);
|
||||||
|
HashMap<String, String> headers = Headers();
|
||||||
|
JSONObject jSONObject3 = new JSONObject(Post(AnonymousUrl, Data.toString(), headers));
|
||||||
|
JSONArray jSONArray = jSONObject3.getJSONArray("file_infos");
|
||||||
|
if (jSONArray.length() == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
JSONObject jSONObject4 = null;
|
||||||
|
boolean isEmpty = TextUtils.isEmpty(str);
|
||||||
|
if (!isEmpty) {
|
||||||
|
int i = 0;
|
||||||
|
while (true) {
|
||||||
|
if (i >= jSONArray.length()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JSONObject jSONObject5 = jSONArray.getJSONObject(i);
|
||||||
|
String string = jSONObject5.getString("file_id");
|
||||||
|
String string2 = jSONObject5.getString("file_id");
|
||||||
|
if (string.equals(string2)) {
|
||||||
|
jSONObject4 = jSONObject5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (jSONObject4 == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jSONObject4 = jSONArray.getJSONObject(0);
|
||||||
|
str = jSONObject4.getString("file_id");
|
||||||
|
}
|
||||||
|
JSONObject jSONObject6 = new JSONObject();
|
||||||
|
jSONObject6.put("vod_id", url);
|
||||||
|
String string3 = jSONObject3.getString("share_name");
|
||||||
|
jSONObject6.put("vod_name", string3);
|
||||||
|
jSONObject6.put("vod_pic", jSONObject3.getString("avatar"));
|
||||||
|
jSONObject6.put("vod_content", url);
|
||||||
|
jSONObject6.put("vod_play_from", "AliYun");
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
String string4 = jSONObject4.getString("type");
|
||||||
|
if (!string4.equals("folder")) {
|
||||||
|
String string5 = jSONObject4.getString("type");
|
||||||
|
if (string5.equals("file")) {
|
||||||
|
String string6 = jSONObject4.getString("category");
|
||||||
|
if (string6.equals("video")) {
|
||||||
|
str = "root";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String s = getShareTk(group, "");
|
||||||
|
Map<String, String> hashMap = new HashMap<>();
|
||||||
|
listFiles(hashMap, group, s, str);
|
||||||
|
ArrayList arrayList2 = new ArrayList(hashMap.keySet());
|
||||||
|
Collections.sort(arrayList2);
|
||||||
|
Iterator it = arrayList2.iterator();
|
||||||
|
while (true) {
|
||||||
|
if (!it.hasNext()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String str3 = (String) it.next();
|
||||||
|
String sb4 = str3 + "$" + hashMap.get(str3);
|
||||||
|
arrayList.add(sb4);
|
||||||
|
}
|
||||||
|
ArrayList arrayList3 = new ArrayList();
|
||||||
|
for (int i2 = 0; i2 < 4; i2++) {
|
||||||
|
String join = TextUtils.join("#", arrayList);
|
||||||
|
arrayList3.add(join);
|
||||||
|
}
|
||||||
|
String join2 = TextUtils.join("$$$", arrayList3);
|
||||||
|
jSONObject6.put("vod_play_url", join2);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray jSONArray2 = new JSONArray();
|
||||||
|
jSONArray2.put(jSONObject6);
|
||||||
|
result.put("list", jSONArray2);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> list) {
|
||||||
|
try {
|
||||||
|
String url = list.get(0);
|
||||||
|
Pattern pattern = Folder;
|
||||||
|
Pattern pattern2 = AliPLink;
|
||||||
|
Matcher matcher2 = pattern2.matcher(url);
|
||||||
|
Matcher matcher = pattern.matcher(url);
|
||||||
|
if (Misc.isVip(url) && !url.contains("qq.com") && !url.contains("mgtv.com")) {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, null));
|
||||||
|
String VodName = doc.select("head > title").text();
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray lists = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
vodAtom.put("vod_id", url);
|
||||||
|
vodAtom.put("vod_name", VodName);
|
||||||
|
vodAtom.put("vod_pic", "https://img.zcool.cn/community/0123545c74c5aea801213f261297df.png");
|
||||||
|
vodAtom.put("type_name", "官源");
|
||||||
|
vodAtom.put("vod_year", "");
|
||||||
|
vodAtom.put("vod_area", "");
|
||||||
|
vodAtom.put("vod_remarks", "");
|
||||||
|
vodAtom.put("vod_actor", "");
|
||||||
|
vodAtom.put("vod_director", "");
|
||||||
|
vodAtom.put("vod_content", "");
|
||||||
|
vodAtom.put("vod_play_from", "jx");
|
||||||
|
vodAtom.put("vod_play_url", "立即播放$" + url);
|
||||||
|
lists.put(vodAtom);
|
||||||
|
result.put("list", lists);
|
||||||
|
return result.toString();
|
||||||
|
} else if (Misc.isVip(url) && url.contains("qq.com")) {
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray lists = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, sHeaders()));
|
||||||
|
String VodName = doc.select("head > title").text();
|
||||||
|
Elements playListA = doc.select("div.episode-list-rect__item");
|
||||||
|
if (!playListA.isEmpty()) {
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
String a = vod.select("div").attr("data-vid");
|
||||||
|
String b = vod.select("div").attr("data-cid");
|
||||||
|
String id = "https://v.qq.com/x/cover/" + b + "/" + a;
|
||||||
|
String name = vod.select("div span").text();
|
||||||
|
vodItems.add(name + "$" + id);
|
||||||
|
}
|
||||||
|
String playList = TextUtils.join("#", vodItems);
|
||||||
|
vodAtom.put("vod_play_url", playList);
|
||||||
|
} else {
|
||||||
|
vodAtom.put("vod_play_url", "立即播放$" + url);
|
||||||
|
}
|
||||||
|
vodAtom.put("vod_id", url);
|
||||||
|
vodAtom.put("vod_name", VodName);
|
||||||
|
vodAtom.put("vod_pic", "https://img2.baidu.com/it/u=2655029475,2190949369&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=593");
|
||||||
|
vodAtom.put("type_name", "腾讯TV");
|
||||||
|
vodAtom.put("vod_year", "");
|
||||||
|
vodAtom.put("vod_area", "");
|
||||||
|
vodAtom.put("vod_remarks", "");
|
||||||
|
vodAtom.put("vod_actor", "");
|
||||||
|
vodAtom.put("vod_director", "");
|
||||||
|
vodAtom.put("vod_content", url);
|
||||||
|
vodAtom.put("vod_play_from", "jx");
|
||||||
|
lists.put(vodAtom);
|
||||||
|
result.put("list", lists);
|
||||||
|
return result.toString();
|
||||||
|
} else if (Misc.isVip(url) && url.contains("mgtv.com")) {
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray lists = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
Pattern mgtv = Pattern.compile("https://\\S+mgtv.com/b/(\\d+)/(\\d+).html.*");
|
||||||
|
Matcher mgtv1 = mgtv.matcher(url);
|
||||||
|
String VodNames = "";
|
||||||
|
if (mgtv1.find()) {
|
||||||
|
String Ep = "https://pcweb.api.mgtv.com/episode/list?video_id=" + mgtv1.group(2);
|
||||||
|
JSONObject Data = new JSONObject(OkHttpUtil.string(Ep, Headers()));
|
||||||
|
VodNames = Data.getJSONObject("data").getJSONObject("info").getString("title");
|
||||||
|
JSONArray a = new JSONArray(Data.getJSONObject("data").getString("list"));
|
||||||
|
if (a.length() > 0) {
|
||||||
|
for (int i = 0; i < a.length(); i++) {
|
||||||
|
JSONObject jObj = a.getJSONObject(i);
|
||||||
|
if (jObj.getString("isIntact").equals("1")) {
|
||||||
|
String VodName = jObj.getString("t4");
|
||||||
|
String id = jObj.getString("video_id");
|
||||||
|
String VodId = "https://www.mgtv.com/b/" + mgtv1.group(1) + "/" + id + ".html";
|
||||||
|
vodItems.add(VodName + "$" + VodId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String playList = TextUtils.join("#", vodItems);
|
||||||
|
vodAtom.put("vod_play_url", playList);
|
||||||
|
} else {
|
||||||
|
vodAtom.put("vod_play_url", "立即播放$" + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vodAtom.put("vod_id", url);
|
||||||
|
vodAtom.put("vod_name", VodNames);
|
||||||
|
vodAtom.put("vod_pic", "https://img2.baidu.com/it/u=2562822927,704100654&fm=253&fmt=auto&app=138&f=JPEG?w=600&h=380");
|
||||||
|
vodAtom.put("type_name", "芒果TV");
|
||||||
|
vodAtom.put("vod_year", "");
|
||||||
|
vodAtom.put("vod_area", "");
|
||||||
|
vodAtom.put("vod_remarks", "");
|
||||||
|
vodAtom.put("vod_actor", "");
|
||||||
|
vodAtom.put("vod_director", "");
|
||||||
|
vodAtom.put("vod_content", url);
|
||||||
|
vodAtom.put("vod_play_from", "jx");
|
||||||
|
lists.put(vodAtom);
|
||||||
|
result.put("list", lists);
|
||||||
|
return result.toString();
|
||||||
|
} else if (Misc.isVideoFormat(url)) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray lists = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
vodAtom.put("vod_id", url);
|
||||||
|
vodAtom.put("vod_name", url);
|
||||||
|
vodAtom.put("vod_pic", "https://img.zcool.cn/community/0123545c74c5aea801213f261297df.png");
|
||||||
|
vodAtom.put("type_name", "直连");
|
||||||
|
vodAtom.put("vod_play_from", "player");
|
||||||
|
vodAtom.put("vod_play_url", "立即播放$" + url);
|
||||||
|
lists.put(vodAtom);
|
||||||
|
result.put("list", lists);
|
||||||
|
return result.toString();
|
||||||
|
} else if (url.startsWith("magnet")) {
|
||||||
|
String VodName = url;
|
||||||
|
if (url.length() > 100) {
|
||||||
|
VodName = url.substring(0, 30) + "..." + url.substring(url.length() - 10);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray lists = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
vodAtom.put("vod_id", url);
|
||||||
|
vodAtom.put("vod_name", VodName);
|
||||||
|
vodAtom.put("vod_pic", "https://img2.baidu.com/it/u=1609185522,4130752057&fm=253&f=JPEG");
|
||||||
|
vodAtom.put("type_name", "磁力");
|
||||||
|
vodAtom.put("vod_play_from", "磁力测试");
|
||||||
|
vodAtom.put("vod_play_url", "立即播放$" + url);
|
||||||
|
lists.put(vodAtom);
|
||||||
|
result.put("list", lists);
|
||||||
|
return result.toString();
|
||||||
|
} else if (url.startsWith("http") && (matcher2.find())) {
|
||||||
|
return getAliContent(list);
|
||||||
|
} else if (url.startsWith("http") && (!matcher.find()) && (!matcher2.find())) {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, null));
|
||||||
|
String VodName = doc.select("head > title").text();
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray lists = new JSONArray();
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
vodAtom.put("vod_id", url);
|
||||||
|
vodAtom.put("vod_name", VodName);
|
||||||
|
vodAtom.put("vod_pic", "https://pic.rmb.bdstatic.com/bjh/1d0b02d0f57f0a42201f92caba5107ed.jpeg");
|
||||||
|
vodAtom.put("type_name", "嗅探");
|
||||||
|
vodAtom.put("vod_content", url);
|
||||||
|
vodAtom.put("vod_play_from", "嗅探");
|
||||||
|
vodAtom.put("vod_play_url", "立即播放嗅探$" + url);
|
||||||
|
lists.put(vodAtom);
|
||||||
|
result.put("list", lists);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
switch (flag) {
|
||||||
|
case "jx": {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("jx", "1");
|
||||||
|
result.put("url", id);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
case "player": {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", id);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
case "嗅探": {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", id);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
case "AliYun":
|
||||||
|
refreshTk();
|
||||||
|
String[] split = id.split("\\+");
|
||||||
|
String str3 = split[0];
|
||||||
|
String str5 = split[2];
|
||||||
|
String url = Proxy.localProxyUrl() + "?do=push&type=m3u8&share_id=" + str3 + "&file_id=" + str5;
|
||||||
|
JSONObject jSONObject = new JSONObject();
|
||||||
|
jSONObject.put("parse", "0");
|
||||||
|
jSONObject.put("playUrl", "");
|
||||||
|
jSONObject.put("url", url);
|
||||||
|
jSONObject.put("header", "");
|
||||||
|
return jSONObject.toString();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,345 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
|
public class SP360 extends Spider {
|
||||||
|
protected JSONObject ext = null;
|
||||||
|
private static final String SiteHost = "https://api.web.360kan.com/v1/rank?cat=1";
|
||||||
|
private static final String SiteFilter = "https://api.web.360kan.com/v1/filter/list";
|
||||||
|
private static final String SiteDetail = "https://api.web.360kan.com/v1/detail";
|
||||||
|
private static final String SiteSearch = "https://api.so.360kan.com/index?force_v=1&kw=%s&from=&pageno=1&v_ap=1&tab=all";
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
ext = new JSONObject("{\"classes\":[{\"type_name\":\"电影\",\"type_id\":\"1\"},{\"type_name\":\"电视剧\",\"type_id\":\"2\"},{\"type_name\":\"综艺\",\"type_id\":\"3\"},{\"type_name\":\"动漫\",\"type_id\":\"4\"}],\"filter\":{\"1\":[{\"key\":\"cat\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"纪录\",\"v\":\"纪录\"},{\"n\":\"传记\",\"v\":\"传记\"},{\"n\":\"歌舞\",\"v\":\"歌舞\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"伦理\",\"v\":\"伦理\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年代\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"更早\",\"v\":\"lt_year\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"大陆\"},{\"n\":\"中国香港\",\"v\":\"香港\"},{\"n\":\"中国台湾\",\"v\":\"台湾\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"rank\",\"name\":\"排序\",\"value\":[{\"n\":\"最近热映\",\"v\":\"rankhot\"},{\"n\":\"最近上映\",\"v\":\"ranklatest\"},{\"n\":\"最受好评\",\"v\":\"rankpoint\"}]}],\"2\":[{\"key\":\"cat\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"言情\",\"v\":\"言情\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"伦理\",\"v\":\"伦理\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"都市\",\"v\":\"都市\"},{\"n\":\"偶像\",\"v\":\"偶像\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"军事\",\"v\":\"军事\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"神话\",\"v\":\"神话\"},{\"n\":\"谍战\",\"v\":\"谍战\"},{\"n\":\"青春\",\"v\":\"青春剧\"},{\"n\":\"家庭\",\"v\":\"家庭剧\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"其他\",\"v\":\"其他\"},{\"n\":\"全部\",\"v\":\"\"}]},{\"key\":\"year\",\"name\":\"年代\",\"value\":[{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"更早\",\"v\":\"lt_year\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"中国香港\",\"v\":\"香港\"},{\"n\":\"中国台湾\",\"v\":\"台湾\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"}]},{\"key\":\"rank\",\"name\":\"排序\",\"value\":[{\"n\":\"最近热映\",\"v\":\"rankhot\"},{\"n\":\"最近上映\",\"v\":\"ranklatest\"},{\"n\":\"最受好评\",\"v\":\"rankpoint\"}]}],\"3\":[{\"key\":\"cat\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"脱口秀\",\"v\":\"脱口秀\"},{\"n\":\"真人秀\",\"v\":\"真人秀\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"八卦\",\"v\":\"八卦\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"晚会\",\"v\":\"晚会\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"职场\",\"v\":\"职场\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"时尚\",\"v\":\"时尚\"},{\"n\":\"游戏\",\"v\":\"游戏\"},{\"n\":\"少儿\",\"v\":\"少儿\"},{\"n\":\"体育\",\"v\":\"体育\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"科教\",\"v\":\"科教\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"歌舞\",\"v\":\"歌舞\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"汽车\",\"v\":\"汽车\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"大陆\"},{\"n\":\"中国香港\",\"v\":\"香港\"},{\"n\":\"中国台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":\"rank\",\"name\":\"排序\",\"value\":[{\"n\":\"最近热映\",\"v\":\"rankhot\"},{\"n\":\"最近上映\",\"v\":\"ranklatest\"}]}],\"4\":[{\"key\":\"cat\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"美少女\",\"v\":\"美少女\"},{\"n\":\"魔幻\",\"v\":\"魔幻\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"少儿\",\"v\":\"少儿\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"恋爱\",\"v\":\"恋爱\"},{\"n\":\"治愈\",\"v\":\"治愈\"},{\"n\":\"幻想\",\"v\":\"幻想\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动物\",\"v\":\"动物\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"儿歌\",\"v\":\"儿歌\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"怪物\",\"v\":\"怪物\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"童话\",\"v\":\"童话\"},{\"n\":\"竞技\",\"v\":\"竞技\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"友情\",\"v\":\"友情\"},{\"n\":\"真人版\",\"v\":\"真人版\"},{\"n\":\"电影版\",\"v\":\"电影版\"},{\"n\":\"OVA版\",\"v\":\"OVA版\"},{\"n\":\"TV版\",\"v\":\"TV版\"},{\"n\":\"新番动画\",\"v\":\"新番动画\"},{\"n\":\"完结动画\",\"v\":\"完结动画\"}]},{\"key\":\"year\",\"name\":\"年代\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"更早\",\"v\":\"更早\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"大陆\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"}]},{\"key\":\"rank\",\"name\":\"排序\",\"value\":[{\"n\":\"最近热映\",\"v\":\"rankhot\"},{\"n\":\"最近上映\",\"v\":\"ranklatest\"}]}]}}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
String cover;
|
||||||
|
String remark;
|
||||||
|
try {
|
||||||
|
String url = SiteFilter + "?catid=" + tid + "&pageno=" + pg;
|
||||||
|
Set<String> keys = extend.keySet();
|
||||||
|
for (String key : keys) {
|
||||||
|
String val = extend.get(key).trim();
|
||||||
|
if (val.length() == 0)
|
||||||
|
continue;
|
||||||
|
url += "&" + key + "=" + URLEncoder.encode(val);
|
||||||
|
}
|
||||||
|
String content = OkHttpUtil.string(url, Headers());
|
||||||
|
JSONObject dataObject = new JSONObject(content).getJSONObject("data");
|
||||||
|
JSONArray jsonArray = dataObject.getJSONArray("movies");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
cover = vObj.getString("cover");
|
||||||
|
if (vObj.has("upinfo")) {
|
||||||
|
remark = vObj.getString("upinfo");
|
||||||
|
v.put("vod_id", tid + "_" + vObj.getString("id"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", "https:" + cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
} else {
|
||||||
|
v.put("vod_id", tid + "_" + vObj.getString("id"));
|
||||||
|
v.put("vod_name", vObj.getString("title"));
|
||||||
|
v.put("vod_pic", "https:" + cover);
|
||||||
|
v.put("vod_remarks", "");
|
||||||
|
}
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int limit = 24;
|
||||||
|
int page = Integer.parseInt(dataObject.getString("current_page"));
|
||||||
|
int total = dataObject.getInt("total");
|
||||||
|
int pageCount = total % limit == 0 ? (total / limit) : (total / limit + 1);
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", limit);
|
||||||
|
result.put("total", total);
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
Iterator it;
|
||||||
|
String str;
|
||||||
|
String str2;
|
||||||
|
Exception e2;
|
||||||
|
ArrayList arrayList = new ArrayList();
|
||||||
|
Exception e3;
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
try {
|
||||||
|
String[] split = ids.get(0).split("_");
|
||||||
|
String format = String.format("%s?cat=%s&id=%s", SiteDetail, split[0], split[1]);
|
||||||
|
JSONObject jSONObject6 = new JSONObject(OkHttpUtil.string(format, Headers())).getJSONObject("data");
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
JSONObject list = new JSONObject();
|
||||||
|
jSONArray.put(list);
|
||||||
|
result.put("list", jSONArray);
|
||||||
|
list.put("vod_id", split[0] + "_" + jSONObject6.optString("ent_id"));
|
||||||
|
list.put("vod_name", jSONObject6.optString("title"));
|
||||||
|
list.put("vod_pic", jSONObject6.optString("cdncover"));
|
||||||
|
JSONArray optJSONArray = jSONObject6.optJSONArray("moviecategory");
|
||||||
|
ArrayList arrayList2 = new ArrayList();
|
||||||
|
for (int i = 0; i < optJSONArray.length(); i++) {
|
||||||
|
arrayList2.add(optJSONArray.getString(i));
|
||||||
|
}
|
||||||
|
list.put("type_name", TextUtils.join("/", arrayList2));
|
||||||
|
list.put("vod_year", jSONObject6.optString("pubdate"));
|
||||||
|
JSONArray optJSONArray2 = jSONObject6.optJSONArray("area");
|
||||||
|
ArrayList arrayList3 = new ArrayList();
|
||||||
|
for (int i2 = 0; i2 < optJSONArray2.length(); i2++) {
|
||||||
|
arrayList3.add(optJSONArray2.getString(i2));
|
||||||
|
}
|
||||||
|
list.put("vod_area", TextUtils.join("/", arrayList3));
|
||||||
|
list.put("vod_remarks", jSONObject6.optString("doubanscore"));
|
||||||
|
JSONArray optJSONArray3 = jSONObject6.optJSONArray("actor");
|
||||||
|
ArrayList arrayList4 = new ArrayList();
|
||||||
|
for (int i3 = 0; i3 < optJSONArray3.length(); i3++) {
|
||||||
|
arrayList4.add(optJSONArray3.getString(i3));
|
||||||
|
}
|
||||||
|
list.put("vod_actor", TextUtils.join("/", arrayList4));
|
||||||
|
JSONArray optJSONArray4 = jSONObject6.optJSONArray("director");
|
||||||
|
ArrayList arrayList5 = new ArrayList();
|
||||||
|
for (int i4 = 0; i4 < optJSONArray4.length(); i4++) {
|
||||||
|
arrayList5.add(optJSONArray4.getString(i4));
|
||||||
|
}
|
||||||
|
list.put("vod_director", TextUtils.join("/", arrayList5));
|
||||||
|
list.put("vod_content", jSONObject6.optString("description"));
|
||||||
|
JSONArray optJSONArray5 = jSONObject6.optJSONArray("playlink_sites");
|
||||||
|
ArrayList<String> arrayList6 = new ArrayList();
|
||||||
|
for (int i5 = 0; i5 < optJSONArray5.length(); i5++) {
|
||||||
|
arrayList6.add(optJSONArray5.getString(i5));
|
||||||
|
}
|
||||||
|
list.put("vod_play_from", TextUtils.join("$$$", arrayList6));
|
||||||
|
JSONObject optJSONObject = jSONObject6.optJSONObject("playlinksdetail");
|
||||||
|
JSONObject optJSONObject2 = jSONObject6.optJSONObject("allepidetail");
|
||||||
|
JSONArray optJSONArray6 = jSONObject6.optJSONArray("defaultepisode");
|
||||||
|
JSONObject optJSONObject3 = jSONObject6.optJSONObject("allupinfo");
|
||||||
|
String str7 = "vod_play_url";
|
||||||
|
if (optJSONArray6 != null) {
|
||||||
|
ArrayList arrayList7 = new ArrayList();
|
||||||
|
for (int i6 = 0; i6 < optJSONArray6.length(); i6++) {
|
||||||
|
try {
|
||||||
|
URL url2 = new URL(optJSONArray6.getJSONObject(i6).optString("url"));
|
||||||
|
arrayList7.add(optJSONArray6.getJSONObject(i6).optString("sort") + "$" + (url2.getProtocol() + "://" + url2.getHost() + url2.getPath()));
|
||||||
|
} catch (Exception e4) {
|
||||||
|
SpiderDebug.log(e4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.put(str7, TextUtils.join("#", arrayList7));
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
if (optJSONObject2 == null) {
|
||||||
|
ArrayList arrayList8 = new ArrayList();
|
||||||
|
for (String str8 : arrayList6) {
|
||||||
|
try {
|
||||||
|
URL url3 = new URL(optJSONObject.getJSONObject(str8).optString("default_url"));
|
||||||
|
arrayList8.add(optJSONObject.getJSONObject(str8).optString("sort") + "$" + (url3.getProtocol() + "://" + url3.getHost() + url3.getPath()));
|
||||||
|
} catch (Exception e5) {
|
||||||
|
SpiderDebug.log(e5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.put(str7, TextUtils.join("$$$", arrayList8));
|
||||||
|
} else {
|
||||||
|
ArrayList videos = new ArrayList();
|
||||||
|
Iterator it2 = arrayList6.iterator();
|
||||||
|
while (it2.hasNext()) {
|
||||||
|
String str9 = (String) it2.next();
|
||||||
|
int parseInt = Integer.parseInt(optJSONObject3.optString(str9, "0"));
|
||||||
|
if (parseInt > 50 || parseInt == 0) {
|
||||||
|
it = it2;
|
||||||
|
str = format + "&start=1&end=50&site=" + str9;
|
||||||
|
} else {
|
||||||
|
StringBuilder sb2 = new StringBuilder();
|
||||||
|
sb2.append(format);
|
||||||
|
it = it2;
|
||||||
|
sb2.append("&start=1&end=");
|
||||||
|
sb2.append(parseInt);
|
||||||
|
sb2.append("&site=");
|
||||||
|
sb2.append(str9);
|
||||||
|
str = sb2.toString();
|
||||||
|
}
|
||||||
|
JSONObject optJSONObject4 = new JSONObject(OkHttpUtil.string(str, Headers())).getJSONObject("data").optJSONObject("allepidetail");
|
||||||
|
ArrayList arrayList10 = new ArrayList();
|
||||||
|
JSONArray jSONArray2 = optJSONObject4.getJSONArray(str9);
|
||||||
|
int i7 = 0;
|
||||||
|
while (true) {
|
||||||
|
str2 = str7;
|
||||||
|
if (i7 >= jSONArray2.length()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String url5 = jSONArray2.getJSONObject(i7).optString("url");
|
||||||
|
arrayList = videos;
|
||||||
|
arrayList10.add(jSONArray2.getJSONObject(i7).optString("playlink_num") + "$" + url5);
|
||||||
|
} catch (Exception e7) {
|
||||||
|
e3 = e7;
|
||||||
|
SpiderDebug.log(e3);
|
||||||
|
i7++;
|
||||||
|
}
|
||||||
|
i7++;
|
||||||
|
str7 = str2;
|
||||||
|
videos = arrayList;
|
||||||
|
}
|
||||||
|
ArrayList arrayList11 = videos;
|
||||||
|
if (parseInt >= jSONArray2.length()) {
|
||||||
|
int i8 = 51;
|
||||||
|
while (i8 < parseInt) {
|
||||||
|
int i9 = i8 + 49;
|
||||||
|
if (i9 > parseInt) {
|
||||||
|
i9 = parseInt;
|
||||||
|
}
|
||||||
|
JSONObject optJSONObject5 = new JSONObject(OkHttpUtil.string(String.format("%s?cat=%s&id=%s&start=%s&end=%s&site=%s", SiteDetail, split[0], split[1], Integer.valueOf(i8), Integer.valueOf(i9), str9), Headers())).optJSONObject("data");
|
||||||
|
if (optJSONObject5 == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JSONArray jSONArray3 = optJSONObject5.getJSONObject("allepidetail").getJSONArray(str9);
|
||||||
|
int i10 = 0;
|
||||||
|
while (i10 < jSONArray3.length()) {
|
||||||
|
try {
|
||||||
|
String url4 = jSONArray3.getJSONObject(i10).optString("url");
|
||||||
|
try {
|
||||||
|
arrayList10.add(jSONArray3.getJSONObject(i10).optString("playlink_num") + "$" + url4);
|
||||||
|
} catch (Exception e8) {
|
||||||
|
e2 = e8;
|
||||||
|
SpiderDebug.log(e2);
|
||||||
|
i10++;
|
||||||
|
}
|
||||||
|
} catch (Exception e9) {
|
||||||
|
}
|
||||||
|
i10++;
|
||||||
|
}
|
||||||
|
i8 = i9 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arrayList11.add(TextUtils.join("#", arrayList10));
|
||||||
|
videos = arrayList11;
|
||||||
|
it2 = it;
|
||||||
|
str7 = str2;
|
||||||
|
}
|
||||||
|
list.put(str7, TextUtils.join("$$$", videos));
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e10) {
|
||||||
|
SpiderDebug.log(e10);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
JSONObject results = new JSONObject();
|
||||||
|
try {
|
||||||
|
results.put("class", ext.getJSONArray("classes"));
|
||||||
|
if (filter) {
|
||||||
|
results.put("filters", ext.getJSONObject("filter"));
|
||||||
|
}
|
||||||
|
} catch (JSONException e2) {
|
||||||
|
SpiderDebug.log(e2);
|
||||||
|
}
|
||||||
|
return results.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
JSONObject list = new JSONObject();
|
||||||
|
try {
|
||||||
|
String str = SiteHost;
|
||||||
|
String i = OkHttpUtil.string(str, new HashMap());
|
||||||
|
SpiderDebug.log("响应请求:" + str);
|
||||||
|
JSONArray optJSONArray = new JSONObject(i).optJSONArray("data");
|
||||||
|
JSONArray jSONArray = new JSONArray();
|
||||||
|
for (int j = 0; j < optJSONArray.length(); j++) {
|
||||||
|
JSONObject jSONObject2 = optJSONArray.getJSONObject(j);
|
||||||
|
JSONObject VideoAtom = new JSONObject();
|
||||||
|
VideoAtom.put("vod_id", jSONObject2.optString("cat") + "_" + jSONObject2.optString("ent_id"));
|
||||||
|
VideoAtom.put("vod_name", jSONObject2.optString("title"));
|
||||||
|
VideoAtom.put("vod_pic", jSONObject2.optString("cover"));
|
||||||
|
VideoAtom.put("vod_remarks", jSONObject2.optString("upinfo"));
|
||||||
|
jSONArray.put(VideoAtom);
|
||||||
|
}
|
||||||
|
list.put("list", jSONArray);
|
||||||
|
} catch (Exception e2) {
|
||||||
|
SpiderDebug.log(e2);
|
||||||
|
}
|
||||||
|
return list.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
try {
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("url", str2);
|
||||||
|
result.put("jx", "1");
|
||||||
|
result.put("playUrl", "");
|
||||||
|
} catch (Exception e2) {
|
||||||
|
SpiderDebug.log(e2);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String str, boolean filter) {
|
||||||
|
JSONObject optJSONObject;
|
||||||
|
JSONObject list = new JSONObject();
|
||||||
|
try {
|
||||||
|
JSONObject optJSONObject2 = new JSONObject(OkHttpUtil.string(String.format(SiteSearch, str), Headers())).optJSONObject("data");
|
||||||
|
if (!(optJSONObject2 == null || (optJSONObject = optJSONObject2.optJSONObject("longData")) == null)) {
|
||||||
|
JSONArray jSONArray = optJSONObject.getJSONArray("rows");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
list.put("list", videos);
|
||||||
|
for (int i = 0; i < jSONArray.length(); i++) {
|
||||||
|
JSONObject Obj = jSONArray.getJSONObject(i);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", Obj.optString("cat_id") + "_" + Obj.optString("en_id"));
|
||||||
|
v.put("vod_name", Obj.optString("titleTxt"));
|
||||||
|
v.put("vod_pic", Obj.optString("cover"));
|
||||||
|
v.put("vod_remarks", Obj.optString("score"));
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e2) {
|
||||||
|
SpiderDebug.log(e2);
|
||||||
|
}
|
||||||
|
return list.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,514 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 神马影院
|
||||||
|
* <p>
|
||||||
|
* Author: baddychen
|
||||||
|
*/
|
||||||
|
public class Smdyy extends Spider {
|
||||||
|
private static final String siteUrl = "https://www.smdyy.cc";
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/list/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/kan/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/play/(\\d+)-(\\d+)-(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("/show/(\\S+).html");
|
||||||
|
|
||||||
|
protected String ext = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"duoduozy\":{\"show\":\"高清线路\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"sohu\":{\"show\":\"优选7\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"qq\":{\"show\":\"优选3\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"bilibili\":{\"show\":\"bilibili\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"youku\":{\"show\":\"优选1\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"qiyi\":{\"show\":\"优选2\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"letv\":{\"show\":\"优选6\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"xigua\":{\"show\":\"西瓜视频\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"mgtv\":{\"show\":\"优选4\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"tkm3u8\":{\"show\":\"备用\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"},\"pptv\":{\"show\":\"优选5\",\"or\":999,\"ps\":\"0\",\"parse\":\"https://player.6080kan.cc/player/play.php?url=\"}}");
|
||||||
|
filterConfig = new JSONObject("{\"1\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"1\"},{\"n\":\"动作片\",\"v\":\"6\"},{\"n\":\"喜剧片\",\"v\":\"7\"},{\"n\":\"爱情片\",\"v\":\"8\"},{\"n\":\"科幻片\",\"v\":\"9\"},{\"n\":\"恐怖片\",\"v\":\"10\"},{\"n\":\"剧情片\",\"v\":\"11\"},{\"n\":\"战争片\",\"v\":\"12\"},{\"n\":\"犯罪片\",\"v\":\"20\"},{\"n\":\"惊悚片\",\"v\":\"21\"},{\"n\":\"冒险片\",\"v\":\"22\"},{\"n\":\"悬疑片\",\"v\":\"23\"},{\"n\":\"武侠片\",\"v\":\"24\"},{\"n\":\"奇幻片\",\"v\":\"25\"},{\"n\":\"纪录片\",\"v\":\"26\"},{\"n\":\"动画片\",\"v\":\"27\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"}]}],\"2\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"2\"},{\"n\":\"国产剧\",\"v\":\"13\"},{\"n\":\"港台剧\",\"v\":\"14\"},{\"n\":\"日韩剧\",\"v\":\"15\"},{\"n\":\"欧美剧\",\"v\":\"16\"},{\"n\":\"泰国剧\",\"v\":\"28\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"}]}],\"4\":[{\"key\":\"3\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"3\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
if (!TextUtils.isEmpty(url)) {
|
||||||
|
headers.put("Referer", url);
|
||||||
|
}
|
||||||
|
headers.put("Accept-Encoding", "gzip, deflate, br");
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.9");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul.stui-header__menu > li a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = true;
|
||||||
|
if (filter) {
|
||||||
|
show = name.equals("电影") ||
|
||||||
|
name.equals("电视剧") ||
|
||||||
|
name.equals("动漫");
|
||||||
|
}
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
Elements list = doc.select("div.stui-pannel div.stui-pannel__bd ul.stui-vodlist li div.stui-vodlist__box");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst(".stui-vodlist__thumb").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String title = vod.selectFirst(".stui-vodlist__thumb").attr("title");
|
||||||
|
String cover = vod.selectFirst(".stui-vodlist__thumb").attr("data-original");
|
||||||
|
String remark = vod.selectFirst("span.pic-text").text();
|
||||||
|
if (!TextUtils.isEmpty(cover) && !cover.startsWith("http")) {
|
||||||
|
cover = siteUrl + cover;
|
||||||
|
}
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||||
|
urlParams[0] = tid;
|
||||||
|
urlParams[8] = pg;
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.trim().length() == 0)
|
||||||
|
continue;
|
||||||
|
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取分类数据的url
|
||||||
|
String url = siteUrl + "/show/" + TextUtils.join("-", urlParams) + "/";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
Elements pageInfo = doc.select("ul.stui-page__item li");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
if (page == -1 && li.hasClass("active")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String wy = doc.select("ul.stui-page__item li a").last().attr("href");
|
||||||
|
Matcher matcher = regexPage.matcher(wy);
|
||||||
|
if (matcher.find()) {
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
Elements list = doc.select("ul.stui-vodlist li div.stui-vodlist__box");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst(".stui-vodlist__thumb").attr("title");
|
||||||
|
String cover = vod.selectFirst(".stui-vodlist__thumb").attr("data-original");
|
||||||
|
if (!TextUtils.isEmpty(cover) && !cover.startsWith("http")) {
|
||||||
|
cover = siteUrl + cover;
|
||||||
|
}
|
||||||
|
String remark = vod.selectFirst("span.pic-text").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst(".stui-vodlist__thumb").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 48);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String Regex(Pattern pattern, String content) {
|
||||||
|
if (pattern == null) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Matcher matcher = pattern.matcher(content);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).trim();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/kan/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
String cover = doc.selectFirst("a.pic img").attr("data-original");
|
||||||
|
if (!TextUtils.isEmpty(cover) && !cover.startsWith("http")) {
|
||||||
|
cover = siteUrl + cover;
|
||||||
|
}
|
||||||
|
String title = doc.selectFirst("div.stui-content__detail h1.title").text();
|
||||||
|
String category = "", area = "", year = "", remark = "", director = "", actor = "", desc = "";
|
||||||
|
Elements data = doc.select("p.data");
|
||||||
|
desc = doc.selectFirst("span.detail-content").text().trim();
|
||||||
|
category = Regex(Pattern.compile("类型:(\\S+)"), data.get(0).text());
|
||||||
|
area = Regex(Pattern.compile("地区:(\\S+)"), data.get(0).text());
|
||||||
|
year = Regex(Pattern.compile("年份:(\\S+)"), data.get(0).text());
|
||||||
|
actor = Regex(Pattern.compile("主演:(\\S+)"), data.get(1).text());
|
||||||
|
director = Regex(Pattern.compile("导演:(\\S+)"), data.get(1).text());
|
||||||
|
|
||||||
|
vodList.put("vod_id", ids.get(0));
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.stui-vodlist__head");
|
||||||
|
//Elements sourceList = doc.select("div.stui-vodlist__head > ul.stui-content__playlist");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.selectFirst("h3").text().trim();
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("show").equals(sourceName)) {
|
||||||
|
//sourceName = flag;
|
||||||
|
sourceName = playerConfig.getJSONObject(flag).getString("show");
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = source.select("ul.stui-content__playlist > li > a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
|
||||||
|
private final Pattern urlt = Pattern.compile("\"url\": *\"([^\"]*)\",");
|
||||||
|
private final Pattern token = Pattern.compile("\"token\": *\"([^\"]*)\"");
|
||||||
|
private final Pattern vkey = Pattern.compile("\"vkey\": *\"([^\"]*)\",");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
headers.put("Referer", " https://www.smdyy.cc/");
|
||||||
|
headers.put("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");
|
||||||
|
headers.put("Accept", " text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
|
||||||
|
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-GB;q=0.8,en-US;q=0.7,en;q=0.6");
|
||||||
|
headers.put("Accept-Encoding", " gzip, deflate");
|
||||||
|
String url = siteUrl + "/play/" + id + ".html";
|
||||||
|
Elements allScript = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url))).select("script");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) {
|
||||||
|
JSONObject player = new JSONObject(scContent.substring(scContent.indexOf('{'), scContent.lastIndexOf('}') + 1));
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
//String jxurl = "https://player.tjomet.com/lgyy/?url=" + player.getString("url");
|
||||||
|
String jxurl = pCfg.getString("parse") + player.getString("url");
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(jxurl, getHeaders(jxurl)));
|
||||||
|
Elements script = doc.select("body>script");
|
||||||
|
for (int j = 0; j < script.size(); j++) {
|
||||||
|
String Content = script.get(j).html().trim();
|
||||||
|
Matcher matcher = urlt.matcher(Content);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String urlt = matcher.group(1);
|
||||||
|
Matcher matcher1 = token.matcher(Content);
|
||||||
|
if (!matcher1.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String token = matcher1.group(1);
|
||||||
|
Matcher matcher2 = vkey.matcher(Content);
|
||||||
|
if (!matcher2.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String vkey = matcher2.group(1);
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
hashMap.put("token", token);
|
||||||
|
hashMap.put("url", urlt);
|
||||||
|
hashMap.put("vkey", vkey);
|
||||||
|
hashMap.put("sign", "smdyycc");
|
||||||
|
OkHttpUtil.post(OkHttpUtil.defaultClient(), "https://player.6080kan.cc/player/xinapi.php", hashMap, new OKCallBack.OKCallBackString() {
|
||||||
|
@Override
|
||||||
|
protected void onFailure(Call call, Exception exc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(String str) {
|
||||||
|
try {
|
||||||
|
String url = new String(Base64.decode(new JSONObject(str).getString("url").substring(8).getBytes(), 0));
|
||||||
|
result.put("url", url.substring(8, url.length() - 8));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
result.put("header", headers.toString());
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param quick 是否播放页的快捷搜索
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
if (quick)
|
||||||
|
return "";
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||||
|
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (searchResult.getInt("total") > 0) {
|
||||||
|
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||||
|
for (int i = 0; i < lists.length(); i++) {
|
||||||
|
JSONObject vod = lists.getJSONObject(i);
|
||||||
|
String id = vod.getString("id");
|
||||||
|
String title = vod.getString("name");
|
||||||
|
String cover = vod.getString("pic");
|
||||||
|
if (!TextUtils.isEmpty(cover) && !cover.startsWith("http")) {
|
||||||
|
cover = siteUrl + cover;
|
||||||
|
}
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", "");
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
|
||||||
|
public class XBiubiu extends Spider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
this.ext = extend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
String[] fenleis = getRuleVal("fenlei", "").split("#");
|
||||||
|
for (String fenlei : fenleis) {
|
||||||
|
String[] info = fenlei.split("\\$");
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_name", info[0]);
|
||||||
|
jsonObject.put("type_id", info[1]);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
return result.toString();
|
||||||
|
} catch (
|
||||||
|
Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
String ua = getRuleVal("UserW", Misc.UaWinChrome).trim();
|
||||||
|
if (ua.isEmpty())
|
||||||
|
ua = Misc.UaWinChrome;
|
||||||
|
headers.put("User-Agent", ua);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
if (getRuleVal("shouye").equals("1")) {
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
String[] fenleis = getRuleVal("fenlei", "").split("#");
|
||||||
|
for (String fenlei : fenleis) {
|
||||||
|
String[] info = fenlei.split("\\$");
|
||||||
|
JSONObject data = category(info[1], "1", false, new HashMap<>());
|
||||||
|
if (data != null) {
|
||||||
|
JSONArray vids = data.optJSONArray("list");
|
||||||
|
if (vids != null) {
|
||||||
|
for (int i = 0; i < vids.length() && i < 5; i++) {
|
||||||
|
videos.put(vids.getJSONObject(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (videos.length() >= 30)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject category(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
String webUrl = getRuleVal("url") + tid + pg + getRuleVal("houzhui");
|
||||||
|
String html = fetch(webUrl);
|
||||||
|
String parseContent = html;
|
||||||
|
boolean shifouercijiequ = getRuleVal("shifouercijiequ").equals("1");
|
||||||
|
if (shifouercijiequ) {
|
||||||
|
String jiequqian = getRuleVal("jiequqian");
|
||||||
|
String jiequhou = getRuleVal("jiequhou");
|
||||||
|
parseContent = subContent(html, jiequqian, jiequhou).get(0);
|
||||||
|
}
|
||||||
|
String jiequshuzuqian = getRuleVal("jiequshuzuqian");
|
||||||
|
String jiequshuzuhou = getRuleVal("jiequshuzuhou");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
ArrayList<String> jiequContents = subContent(parseContent, jiequshuzuqian, jiequshuzuhou);
|
||||||
|
for (int i = 0; i < jiequContents.size(); i++) {
|
||||||
|
//try {
|
||||||
|
String jiequContent = jiequContents.get(i);
|
||||||
|
String title = subContent(jiequContent, getRuleVal("biaotiqian"), getRuleVal("biaotihou")).get(0);
|
||||||
|
String pic = subContent(jiequContent, getRuleVal("tupianqian"), getRuleVal("tupianhou")).get(0);
|
||||||
|
pic = Misc.fixUrl(webUrl, pic);
|
||||||
|
String link = subContent(jiequContent, getRuleVal("lianjieqian"), getRuleVal("lianjiehou")).get(0);
|
||||||
|
//String remarks = subContent(jiequContent, getRuleVal("gengxinqian"), getRuleVal("gengxinhou")).get(0);
|
||||||
|
//String remarks = subContent(jiequContent, getRuleVal("gengxinqian"), getRuleVal("gengxinhou")).get(0).replaceAll("\\s+", "").replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "").replaceAll("[(/>)<]", "");
|
||||||
|
String mark = "";
|
||||||
|
if (!getRuleVal("gengxinqian").isEmpty() && !getRuleVal("gengxinhou").isEmpty()) {
|
||||||
|
try {
|
||||||
|
mark = subContent(jiequContent, getRuleVal("gengxinqian"), getRuleVal("gengxinhou")).get(0).replaceAll("\\s+", "").replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "").replaceAll("[(/>)<]", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", title + "$$$" + pic + "$$$" + link);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
v.put("vod_remarks", mark);
|
||||||
|
videos.put(v);
|
||||||
|
//} catch (Throwable th) {
|
||||||
|
//th.printStackTrace();
|
||||||
|
//break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("page", pg);
|
||||||
|
result.put("pagecount", Integer.MAX_VALUE);
|
||||||
|
result.put("limit", 90);
|
||||||
|
result.put("total", Integer.MAX_VALUE);
|
||||||
|
result.put("list", videos);
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
JSONObject obj = category(tid, pg, filter, extend);
|
||||||
|
return obj != null ? obj.toString() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
String[] idInfo = ids.get(0).split("\\$\\$\\$");
|
||||||
|
String webUrl = getRuleVal("url") + idInfo[2];
|
||||||
|
String html = fetch(webUrl);
|
||||||
|
String parseContent = html;
|
||||||
|
boolean bfshifouercijiequ = getRuleVal("bfshifouercijiequ").equals("1");
|
||||||
|
if (bfshifouercijiequ) {
|
||||||
|
String jiequqian = getRuleVal("bfjiequqian");
|
||||||
|
String jiequhou = getRuleVal("bfjiequhou");
|
||||||
|
parseContent = subContent(html, jiequqian, jiequhou).get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> playList = new ArrayList<>();
|
||||||
|
|
||||||
|
String jiequshuzuqian = getRuleVal("bfjiequshuzuqian");
|
||||||
|
String jiequshuzuhou = getRuleVal("bfjiequshuzuhou");
|
||||||
|
boolean bfyshifouercijiequ = getRuleVal("bfyshifouercijiequ").equals("1");
|
||||||
|
ArrayList<String> jiequContents = subContent(parseContent, jiequshuzuqian, jiequshuzuhou);
|
||||||
|
for (int i = 0; i < jiequContents.size(); i++) {
|
||||||
|
try {
|
||||||
|
String jiequContent = jiequContents.get(i);
|
||||||
|
String parseJqContent = bfyshifouercijiequ ? subContent(jiequContent, getRuleVal("bfyjiequqian"), getRuleVal("bfyjiequhou")).get(0) : jiequContent;
|
||||||
|
ArrayList<String> lastParseContents = subContent(parseJqContent, getRuleVal("bfyjiequshuzuqian"), getRuleVal("bfyjiequshuzuhou"));
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
for (int j = 0; j < lastParseContents.size(); j++) {
|
||||||
|
String title = subContent(lastParseContents.get(j), getRuleVal("bfbiaotiqian"), getRuleVal("bfbiaotihou")).get(0);
|
||||||
|
String link = subContent(lastParseContents.get(j), getRuleVal("bflianjieqian"), getRuleVal("bflianjiehou")).get(0);
|
||||||
|
vodItems.add(title + "$" + link);
|
||||||
|
}
|
||||||
|
playList.add(TextUtils.join("#", vodItems));
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String cover = idInfo[1], title = idInfo[0], area = "";
|
||||||
|
String director = "";
|
||||||
|
String actor = "";
|
||||||
|
String desc = "";
|
||||||
|
String remark = "";
|
||||||
|
String year = "";
|
||||||
|
String category = "";
|
||||||
|
|
||||||
|
if (!getRuleVal("leixinqian").isEmpty() && !getRuleVal("leixinhou").isEmpty()) {
|
||||||
|
try {
|
||||||
|
category = subContent(html, getRuleVal("leixinqian"), getRuleVal("leixinhou")).get(0).replaceAll("\\s+", "").replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "").replaceAll("[(/>)<]", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!getRuleVal("niandaiqian").isEmpty() && !getRuleVal("niandaihou").isEmpty()) {
|
||||||
|
try {
|
||||||
|
year = subContent(html, getRuleVal("niandaiqian"), getRuleVal("niandaihou")).get(0).replaceAll("\\s+", "").replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "").replaceAll("[(/>)<]", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!getRuleVal("zhuangtaiqian").isEmpty() && !getRuleVal("zhuangtaihou").isEmpty()) {
|
||||||
|
try {
|
||||||
|
remark = subContent(html, getRuleVal("zhuangtaiqian"), getRuleVal("zhuangtaihou")).get(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!getRuleVal("zhuyanqian").isEmpty() && !getRuleVal("zhuyanhou").isEmpty()) {
|
||||||
|
try {
|
||||||
|
actor = subContent(html, getRuleVal("zhuyanqian"), getRuleVal("zhuyanhou")).get(0).replaceAll("\\s+", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!getRuleVal("daoyanqian").isEmpty() && !getRuleVal("daoyanhou").isEmpty()) {
|
||||||
|
try {
|
||||||
|
director = subContent(html, getRuleVal("daoyanqian"), getRuleVal("daoyanhou")).get(0).replaceAll("\\s+", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!getRuleVal("juqingqian").isEmpty() && !getRuleVal("juqinghou").isEmpty()) {
|
||||||
|
try {
|
||||||
|
desc = subContent(html, getRuleVal("juqingqian"), getRuleVal("juqinghou")).get(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject vod = new JSONObject();
|
||||||
|
vod.put("vod_id", ids.get(0));
|
||||||
|
vod.put("vod_name", title);
|
||||||
|
vod.put("vod_pic", cover);
|
||||||
|
vod.put("type_name", category);
|
||||||
|
vod.put("vod_year", year);
|
||||||
|
vod.put("vod_area", area);
|
||||||
|
vod.put("vod_remarks", remark);
|
||||||
|
vod.put("vod_actor", actor);
|
||||||
|
vod.put("vod_director", director);
|
||||||
|
vod.put("vod_content", desc);
|
||||||
|
|
||||||
|
ArrayList<String> playFrom = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < playList.size(); i++) {
|
||||||
|
playFrom.add("播放列表" + (i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
String vod_play_from = TextUtils.join("$$$", playFrom);
|
||||||
|
String vod_play_url = TextUtils.join("$$$", playList);
|
||||||
|
vod.put("vod_play_from", vod_play_from);
|
||||||
|
vod.put("vod_play_url", vod_play_url);
|
||||||
|
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vod);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
String webUrl = getRuleVal("url") + id;
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", webUrl);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
boolean ssmoshiJson = getRuleVal("ssmoshi").equals("0");
|
||||||
|
String webUrlTmp = getRuleVal("url") + getRuleVal("sousuoqian") + key + getRuleVal("sousuohou");
|
||||||
|
String webUrl = webUrlTmp.split(";")[0];
|
||||||
|
String webContent = webUrlTmp.contains(";post") ? fetchPost(webUrl) : fetch(webUrl);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (ssmoshiJson) {
|
||||||
|
JSONObject data = new JSONObject(webContent);
|
||||||
|
JSONArray vodArray = data.getJSONArray("list");
|
||||||
|
for (int j = 0; j < vodArray.length(); j++) {
|
||||||
|
JSONObject vod = vodArray.getJSONObject(j);
|
||||||
|
String name = vod.optString(getRuleVal("jsname")).trim();
|
||||||
|
String id = vod.optString(getRuleVal("jsid")).trim();
|
||||||
|
String pic = vod.optString(getRuleVal("jspic")).trim();
|
||||||
|
pic = Misc.fixUrl(webUrl, pic);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", name + "$$$" + pic + "$$$" + getRuleVal("sousuohouzhui") + id);
|
||||||
|
v.put("vod_name", name);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
v.put("vod_remarks", "");
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String parseContent = webContent;
|
||||||
|
boolean shifouercijiequ = getRuleVal("sousuoshifouercijiequ").equals("1");
|
||||||
|
if (shifouercijiequ) {
|
||||||
|
String jiequqian = getRuleVal("ssjiequqian");
|
||||||
|
String jiequhou = getRuleVal("ssjiequhou");
|
||||||
|
parseContent = subContent(webContent, jiequqian, jiequhou).get(0);
|
||||||
|
}
|
||||||
|
String jiequshuzuqian = getRuleVal("ssjiequshuzuqian");
|
||||||
|
String jiequshuzuhou = getRuleVal("ssjiequshuzuhou");
|
||||||
|
ArrayList<String> jiequContents = subContent(parseContent, jiequshuzuqian, jiequshuzuhou);
|
||||||
|
for (int i = 0; i < jiequContents.size(); i++) {
|
||||||
|
try {
|
||||||
|
String jiequContent = jiequContents.get(i);
|
||||||
|
String title = subContent(jiequContent, getRuleVal("ssbiaotiqian"), getRuleVal("ssbiaotihou")).get(0);
|
||||||
|
String pic = subContent(jiequContent, getRuleVal("sstupianqian"), getRuleVal("sstupianhou")).get(0);
|
||||||
|
pic = Misc.fixUrl(webUrl, pic);
|
||||||
|
String link = subContent(jiequContent, getRuleVal("sslianjieqian"), getRuleVal("sslianjiehou")).get(0);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", title + "$$$" + pic + "$$$" + link);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
v.put("vod_remarks", "");
|
||||||
|
videos.put(v);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (
|
||||||
|
Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String ext = null;
|
||||||
|
protected JSONObject rule = null;
|
||||||
|
|
||||||
|
protected void fetchRule() {
|
||||||
|
if (rule == null) {
|
||||||
|
if (ext != null) {
|
||||||
|
try {
|
||||||
|
if (ext.startsWith("http")) {
|
||||||
|
String json = OkHttpUtil.string(ext, null);
|
||||||
|
rule = new JSONObject(json);
|
||||||
|
} else {
|
||||||
|
rule = new JSONObject(ext);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String fetch(String webUrl) {
|
||||||
|
SpiderDebug.log(webUrl);
|
||||||
|
return OkHttpUtil.string(webUrl, getHeaders(webUrl)).replaceAll("\r|\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String fetchPost(String webUrl) {
|
||||||
|
SpiderDebug.log(webUrl);
|
||||||
|
OKCallBack.OKCallBackString callBack = new OKCallBack.OKCallBackString() {
|
||||||
|
@Override
|
||||||
|
protected void onFailure(Call call, Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResponse(String response) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OkHttpUtil.post(OkHttpUtil.defaultClient(), webUrl, callBack);
|
||||||
|
return callBack.getResult().replaceAll("\r|\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRuleVal(String key, String defaultVal) {
|
||||||
|
String v = rule.optString(key);
|
||||||
|
if (v.isEmpty() || v.equals("空"))
|
||||||
|
return defaultVal;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRuleVal(String key) {
|
||||||
|
return getRuleVal(key, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> subContent(String content, String startFlag, String endFlag) {
|
||||||
|
ArrayList<String> result = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
Pattern pattern = Pattern.compile(startFlag + "(.*?)" + endFlag);
|
||||||
|
Matcher matcher = pattern.matcher(content);
|
||||||
|
while (matcher.find()) {
|
||||||
|
result.add(matcher.group(1));
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
th.printStackTrace();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,474 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
import com.github.catvod.xpath.XPathRule;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.seimicrawler.xpath.JXDocument;
|
||||||
|
import org.seimicrawler.xpath.JXNode;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class XPath extends Spider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
this.ext = extend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
if (rule.getCateManual().size() > 0) {
|
||||||
|
Set<String> keys = rule.getCateManual().keySet();
|
||||||
|
for (String k : keys) {
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_name", k);
|
||||||
|
jsonObject.put("type_id", rule.getCateManual().get(k));
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String webUrl = rule.getHomeUrl();
|
||||||
|
JXDocument doc = JXDocument.create(fetch(webUrl));
|
||||||
|
if (rule.getCateManual().size() == 0) {
|
||||||
|
List<JXNode> navNodes = doc.selN(rule.getCateNode());
|
||||||
|
for (int i = 0; i < navNodes.size(); i++) {
|
||||||
|
String name = navNodes.get(i).selOne(rule.getCateName()).asString().trim();
|
||||||
|
name = rule.getCateNameR(name);
|
||||||
|
String id = navNodes.get(i).selOne(rule.getCateId()).asString().trim();
|
||||||
|
id = rule.getCateIdR(id);
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getHomeVodNode().isEmpty()) {
|
||||||
|
try {
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
List<JXNode> vodNodes = doc.selN(rule.getHomeVodNode());
|
||||||
|
for (int i = 0; i < vodNodes.size(); i++) {
|
||||||
|
String name = vodNodes.get(i).selOne(rule.getHomeVodName()).asString().trim();
|
||||||
|
name = rule.getHomeVodNameR(name);
|
||||||
|
String id = vodNodes.get(i).selOne(rule.getHomeVodId()).asString().trim();
|
||||||
|
id = rule.getHomeVodIdR(id);
|
||||||
|
String pic = vodNodes.get(i).selOne(rule.getHomeVodImg()).asString().trim();
|
||||||
|
pic = rule.getHomeVodImgR(pic);
|
||||||
|
pic = Misc.fixUrl(webUrl, pic);
|
||||||
|
String mark = "";
|
||||||
|
if (!rule.getHomeVodMark().isEmpty()) {
|
||||||
|
try {
|
||||||
|
mark = vodNodes.get(i).selOne(rule.getHomeVodMark()).asString().trim();
|
||||||
|
mark = rule.getHomeVodMarkR(mark);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", name);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
v.put("vod_remarks", mark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
if (filter && rule.getFilter() != null) {
|
||||||
|
result.put("filters", rule.getFilter());
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (
|
||||||
|
Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", rule.getUa().isEmpty()
|
||||||
|
? "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36"
|
||||||
|
: rule.getUa());
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeVideoContent() {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
return rule.getCateUrl().replace("{cateId}", tid).replace("{catePg}", pg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
String webUrl = categoryUrl(tid, pg, filter, extend);
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
JXDocument doc = JXDocument.create(fetch(webUrl));
|
||||||
|
List<JXNode> vodNodes = doc.selN(rule.getCateVodNode());
|
||||||
|
for (int i = 0; i < vodNodes.size(); i++) {
|
||||||
|
String name = vodNodes.get(i).selOne(rule.getCateVodName()).asString().trim();
|
||||||
|
name = rule.getCateVodNameR(name);
|
||||||
|
String id = vodNodes.get(i).selOne(rule.getCateVodId()).asString().trim();
|
||||||
|
id = rule.getCateVodIdR(id);
|
||||||
|
String pic = vodNodes.get(i).selOne(rule.getCateVodImg()).asString().trim();
|
||||||
|
pic = rule.getCateVodImgR(pic);
|
||||||
|
pic = Misc.fixUrl(webUrl, pic);
|
||||||
|
String mark = "";
|
||||||
|
if (!rule.getCateVodMark().isEmpty()) {
|
||||||
|
try {
|
||||||
|
mark = vodNodes.get(i).selOne(rule.getCateVodMark()).asString().trim();
|
||||||
|
mark = rule.getCateVodMarkR(mark);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", name);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
v.put("vod_remarks", mark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("page", pg);
|
||||||
|
result.put("pagecount", Integer.MAX_VALUE);
|
||||||
|
result.put("limit", 90);
|
||||||
|
result.put("total", Integer.MAX_VALUE);
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void detailContentExt(String content, JSONObject vod) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
String webUrl = rule.getDetailUrl().replace("{vid}", ids.get(0));
|
||||||
|
String webContent = fetch(webUrl);
|
||||||
|
JXDocument doc = JXDocument.create(webContent);
|
||||||
|
JXNode vodNode = doc.selNOne(rule.getDetailNode());
|
||||||
|
|
||||||
|
String cover = "", title = "", desc = "", category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||||
|
|
||||||
|
title = vodNode.selOne(rule.getDetailName()).asString().trim();
|
||||||
|
title = rule.getDetailNameR(title);
|
||||||
|
|
||||||
|
cover = vodNode.selOne(rule.getDetailImg()).asString().trim();
|
||||||
|
cover = rule.getDetailImgR(cover);
|
||||||
|
cover = Misc.fixUrl(webUrl, cover);
|
||||||
|
|
||||||
|
if (!rule.getDetailCate().isEmpty()) {
|
||||||
|
try {
|
||||||
|
category = vodNode.selOne(rule.getDetailCate()).asString().trim();
|
||||||
|
category = rule.getDetailCateR(category);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailYear().isEmpty()) {
|
||||||
|
try {
|
||||||
|
year = vodNode.selOne(rule.getDetailYear()).asString().trim();
|
||||||
|
year = rule.getDetailYearR(year);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailArea().isEmpty()) {
|
||||||
|
try {
|
||||||
|
area = vodNode.selOne(rule.getDetailArea()).asString().trim();
|
||||||
|
area = rule.getDetailAreaR(area);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailMark().isEmpty()) {
|
||||||
|
try {
|
||||||
|
remark = vodNode.selOne(rule.getDetailMark()).asString().trim();
|
||||||
|
remark = rule.getDetailMarkR(remark);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailActor().isEmpty()) {
|
||||||
|
try {
|
||||||
|
actor = vodNode.selOne(rule.getDetailActor()).asString().trim();
|
||||||
|
actor = rule.getDetailActorR(actor);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailDirector().isEmpty()) {
|
||||||
|
try {
|
||||||
|
director = vodNode.selOne(rule.getDetailDirector()).asString().trim();
|
||||||
|
director = rule.getDetailDirectorR(director);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailDesc().isEmpty()) {
|
||||||
|
try {
|
||||||
|
desc = vodNode.selOne(rule.getDetailDesc()).asString().trim();
|
||||||
|
desc = rule.getDetailDescR(desc);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject vod = new JSONObject();
|
||||||
|
vod.put("vod_id", ids.get(0));
|
||||||
|
vod.put("vod_name", title);
|
||||||
|
vod.put("vod_pic", cover);
|
||||||
|
vod.put("type_name", category);
|
||||||
|
vod.put("vod_year", year);
|
||||||
|
vod.put("vod_area", area);
|
||||||
|
vod.put("vod_remarks", remark);
|
||||||
|
vod.put("vod_actor", actor);
|
||||||
|
vod.put("vod_director", director);
|
||||||
|
vod.put("vod_content", desc);
|
||||||
|
|
||||||
|
ArrayList<String> playFrom = new ArrayList<>();
|
||||||
|
|
||||||
|
List<JXNode> fromNodes = doc.selN(rule.getDetailFromNode());
|
||||||
|
for (int i = 0; i < fromNodes.size(); i++) {
|
||||||
|
String name = fromNodes.get(i).selOne(rule.getDetailFromName()).asString().trim();
|
||||||
|
name = rule.getDetailFromNameR(name);
|
||||||
|
playFrom.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> playList = new ArrayList<>();
|
||||||
|
List<JXNode> urlListNodes = doc.selN(rule.getDetailUrlNode());
|
||||||
|
for (int i = 0; i < urlListNodes.size(); i++) {
|
||||||
|
List<JXNode> urlNodes = urlListNodes.get(i).sel(rule.getDetailUrlSubNode());
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
for (int j = 0; j < urlNodes.size(); j++) {
|
||||||
|
String name = urlNodes.get(j).selOne(rule.getDetailUrlName()).asString().trim();
|
||||||
|
name = rule.getDetailUrlNameR(name);
|
||||||
|
String id = urlNodes.get(j).selOne(rule.getDetailUrlId()).asString().trim();
|
||||||
|
id = rule.getDetailUrlIdR(id);
|
||||||
|
vodItems.add(name + "$" + id);
|
||||||
|
}
|
||||||
|
// 排除播放列表为空的播放源
|
||||||
|
if (vodItems.size() == 0 && playFrom.size() > i) {
|
||||||
|
playFrom.set(i, "");
|
||||||
|
}
|
||||||
|
playList.add(TextUtils.join("#", vodItems));
|
||||||
|
}
|
||||||
|
// 排除播放列表为空的播放源
|
||||||
|
for (int i = playFrom.size() - 1; i >= 0; i--) {
|
||||||
|
if (playFrom.get(i).isEmpty())
|
||||||
|
playFrom.remove(i);
|
||||||
|
}
|
||||||
|
for (int i = playList.size() - 1; i >= 0; i--) {
|
||||||
|
if (playList.get(i).isEmpty())
|
||||||
|
playList.remove(i);
|
||||||
|
}
|
||||||
|
for (int i = playList.size() - 1; i >= 0; i--) {
|
||||||
|
if (i >= playFrom.size())
|
||||||
|
playList.remove(i);
|
||||||
|
}
|
||||||
|
String vod_play_from = TextUtils.join("$$$", playFrom);
|
||||||
|
String vod_play_url = TextUtils.join("$$$", playList);
|
||||||
|
vod.put("vod_play_from", vod_play_from);
|
||||||
|
vod.put("vod_play_url", vod_play_url);
|
||||||
|
|
||||||
|
detailContentExt(webContent, vod);
|
||||||
|
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vod);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
|
||||||
|
SpiderDebug.log(webUrl);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
if (!rule.getPlayUa().isEmpty()) {
|
||||||
|
result.put("ua", rule.getPlayUa());
|
||||||
|
}
|
||||||
|
result.put("url", webUrl);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
fetchRule();
|
||||||
|
if (rule.getSearchUrl().isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String webUrl = rule.getSearchUrl().replace("{wd}", URLEncoder.encode(key));
|
||||||
|
String webContent = fetch(webUrl);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
// add maccms suggest search api support
|
||||||
|
if (rule.getSearchVodNode().startsWith("json:")) {
|
||||||
|
String[] node = rule.getSearchVodNode().substring(5).split(">");
|
||||||
|
JSONObject data = new JSONObject(webContent);
|
||||||
|
for (int i = 0; i < node.length; i++) {
|
||||||
|
if (i == node.length - 1) {
|
||||||
|
JSONArray vodArray = data.getJSONArray(node[i]);
|
||||||
|
for (int j = 0; j < vodArray.length(); j++) {
|
||||||
|
JSONObject vod = vodArray.getJSONObject(j);
|
||||||
|
String name = vod.optString(rule.getSearchVodName()).trim();
|
||||||
|
name = rule.getSearchVodNameR(name);
|
||||||
|
String id = vod.optString(rule.getSearchVodId()).trim();
|
||||||
|
id = rule.getSearchVodIdR(id);
|
||||||
|
String pic = vod.optString(rule.getSearchVodImg()).trim();
|
||||||
|
pic = rule.getSearchVodImgR(pic);
|
||||||
|
pic = Misc.fixUrl(webUrl, pic);
|
||||||
|
String mark = vod.optString(rule.getSearchVodMark()).trim();
|
||||||
|
mark = rule.getSearchVodMarkR(mark);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", name);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
v.put("vod_remarks", mark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data = data.getJSONObject(node[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
JXDocument doc = JXDocument.create(webContent);
|
||||||
|
List<JXNode> vodNodes = doc.selN(rule.getSearchVodNode());
|
||||||
|
for (int i = 0; i < vodNodes.size(); i++) {
|
||||||
|
String name = vodNodes.get(i).selOne(rule.getSearchVodName()).asString().trim();
|
||||||
|
name = rule.getSearchVodNameR(name);
|
||||||
|
String id = vodNodes.get(i).selOne(rule.getSearchVodId()).asString().trim();
|
||||||
|
id = rule.getSearchVodIdR(id);
|
||||||
|
String pic = vodNodes.get(i).selOne(rule.getSearchVodImg()).asString().trim();
|
||||||
|
pic = rule.getSearchVodImgR(pic);
|
||||||
|
pic = Misc.fixUrl(webUrl, pic);
|
||||||
|
String mark = "";
|
||||||
|
if (!rule.getCateVodMark().isEmpty()) {
|
||||||
|
try {
|
||||||
|
mark = vodNodes.get(i).selOne(rule.getSearchVodMark()).asString().trim();
|
||||||
|
mark = rule.getSearchVodMarkR(mark);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", name);
|
||||||
|
v.put("vod_pic", pic);
|
||||||
|
v.put("vod_remarks", mark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (
|
||||||
|
Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean manualVideoCheck() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] videoFormatList = new String[]{".m3u8", ".mp4", ".mpeg", ".flv"};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVideoFormat(String url) {
|
||||||
|
url = url.toLowerCase();
|
||||||
|
if (url.contains("=http") || url.contains("=https") || url.contains("=https%3a%2f") || url.contains("=http%3a%2f")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String format : videoFormatList) {
|
||||||
|
if (url.contains(format)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String ext = null;
|
||||||
|
protected XPathRule rule = null;
|
||||||
|
|
||||||
|
protected void fetchRule() {
|
||||||
|
if (rule == null) {
|
||||||
|
if (ext != null) {
|
||||||
|
if (ext.startsWith("http")) {
|
||||||
|
String json = OkHttpUtil.string(ext, null);
|
||||||
|
rule = XPathRule.fromJson(json);
|
||||||
|
loadRuleExt(json);
|
||||||
|
} else {
|
||||||
|
rule = XPathRule.fromJson(ext);
|
||||||
|
loadRuleExt(ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadRuleExt(String json) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String fetch(String webUrl) {
|
||||||
|
SpiderDebug.log(webUrl);
|
||||||
|
return OkHttpUtil.string(webUrl, getHeaders(webUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class XPathFilter extends XPath {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadRuleExt(String json) {
|
||||||
|
super.loadRuleExt(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
String cateUrl = rule.getCateUrl();
|
||||||
|
if (filter && extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cateUrl = cateUrl.replace("{cateId}", tid).replace("{catePg}", pg);
|
||||||
|
Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(cateUrl);
|
||||||
|
while (m.find()) {
|
||||||
|
String n = m.group(0).replace("{", "").replace("}", "");
|
||||||
|
cateUrl = cateUrl.replace(m.group(0), "").replace("/" + n + "/", "");
|
||||||
|
}
|
||||||
|
return cateUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class XPathMac extends XPath {
|
||||||
|
// 尝试分析直连
|
||||||
|
private boolean decodePlayUrl;
|
||||||
|
// 尝试匹配官源标识以调用应用配置中的解析列表
|
||||||
|
private boolean decodeVipFlag;
|
||||||
|
// 播放器配置js
|
||||||
|
private String playerConfigJs = "";
|
||||||
|
// 播放器配置js取值正则
|
||||||
|
private String playerConfigJsRegex = "[\\W|\\S|.]*?MacPlayerConfig.player_list[\\W|\\S|.]*?=([\\W|\\S|.]*?),MacPlayerConfig.downer_list";
|
||||||
|
// 站点里播放源对应的真实官源
|
||||||
|
private HashMap<String, String> show2VipFlag = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mac cms 直连和官源调用应用内播放列表支持
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param extend
|
||||||
|
*/
|
||||||
|
public void init(Context context, String extend) {
|
||||||
|
super.init(context, extend);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadRuleExt(String json) {
|
||||||
|
try {
|
||||||
|
JSONObject jsonObj = new JSONObject(json);
|
||||||
|
decodePlayUrl = jsonObj.optBoolean("dcPlayUrl", false);
|
||||||
|
decodeVipFlag = jsonObj.optBoolean("dcVipFlag", false);
|
||||||
|
JSONObject dcShow2Vip = jsonObj.optJSONObject("dcShow2Vip");
|
||||||
|
if (dcShow2Vip != null) {
|
||||||
|
Iterator<String> keys = dcShow2Vip.keys();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String name = keys.next();
|
||||||
|
show2VipFlag.put(name.trim(), dcShow2Vip.getString(name).trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playerConfigJs = jsonObj.optString("pCfgJs").trim();
|
||||||
|
playerConfigJsRegex = jsonObj.optString("pCfgJsR", playerConfigJsRegex).trim();
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
String result = super.homeContent(filter);
|
||||||
|
if (result.length() > 0 && playerConfigJs.length() > 0) { // 尝试通过playerConfigJs获取展示和flag匹配关系
|
||||||
|
String webContent = fetch(playerConfigJs);
|
||||||
|
Matcher matcher = Pattern.compile(playerConfigJsRegex).matcher(webContent);
|
||||||
|
if (matcher.find()) {
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(matcher.group(1));
|
||||||
|
Iterator<String> keys = jsonObject.keys();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String key = keys.next();
|
||||||
|
JSONObject keyObj = jsonObject.optJSONObject(key);
|
||||||
|
if (keyObj == null)
|
||||||
|
continue;
|
||||||
|
String show = keyObj.optString("show").trim();
|
||||||
|
if (show.isEmpty())
|
||||||
|
continue;
|
||||||
|
show2VipFlag.put(show, key);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SpiderDebug.log(webContent);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
String result = super.detailContent(ids);
|
||||||
|
if (decodeVipFlag && result.length() > 0) {
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(result);
|
||||||
|
String playFrom[] = jsonObject.optJSONArray("list").getJSONObject(0).optString("vod_play_from").split("\\$\\$\\$");
|
||||||
|
if (playFrom.length > 0) {
|
||||||
|
for (int i = 0; i < playFrom.length; i++) {
|
||||||
|
if (show2VipFlag.containsKey(playFrom[i])) {
|
||||||
|
playFrom[i] = show2VipFlag.get(playFrom[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonObject.optJSONArray("list").getJSONObject(0).put("vod_play_from", TextUtils.join("$$$", playFrom));
|
||||||
|
result = jsonObject.toString();
|
||||||
|
}
|
||||||
|
} catch (Throwable th) {
|
||||||
|
SpiderDebug.log(th);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
fetchRule();
|
||||||
|
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
|
||||||
|
String videoUrl = null;
|
||||||
|
// 尝试分析直连
|
||||||
|
if (decodePlayUrl) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(fetch(webUrl));
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) {
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
String videoUrlTmp = player.getString("url");
|
||||||
|
if (player.has("encrypt")) {
|
||||||
|
int encrypt = player.getInt("encrypt");
|
||||||
|
if (encrypt == 1) {
|
||||||
|
videoUrlTmp = URLDecoder.decode(videoUrlTmp);
|
||||||
|
} else if (encrypt == 2) {
|
||||||
|
videoUrlTmp = new String(Base64.decode(videoUrlTmp, Base64.DEFAULT));
|
||||||
|
videoUrlTmp = URLDecoder.decode(videoUrlTmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
videoUrl = videoUrlTmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (videoUrl != null) {
|
||||||
|
// 适配2.0.6的调用应用内解析列表的支持, 需要配合直连分析和匹配官源解析一起使用,参考cjt影视和极品直连
|
||||||
|
if (decodeVipFlag && Misc.isVip(videoUrl)) { // 使用jx:1
|
||||||
|
try {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("jx", "1");
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
} else if (decodeVipFlag && vipFlags.contains(flag)) { // 是否使用应用内解析列表解析官源
|
||||||
|
try {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
result.put("header", "");
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果是视频直连 直接返回免解
|
||||||
|
else if (isVideoFormat(videoUrl)) {
|
||||||
|
try {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
result.put("header", "");
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上述都失败了就按默认模式走
|
||||||
|
return super.playerContent(flag, id, vipFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class XPathMacFilter extends XPathMac {
|
||||||
|
@Override
|
||||||
|
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
String cateUrl = rule.getCateUrl();
|
||||||
|
if (filter && extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cateUrl = cateUrl.replace("{cateId}", tid).replace("{catePg}", pg);
|
||||||
|
Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(cateUrl);
|
||||||
|
while (m.find()) {
|
||||||
|
String n = m.group(0).replace("{", "").replace("}", "");
|
||||||
|
cateUrl = cateUrl.replace(m.group(0), "").replace("/" + n + "/", "");
|
||||||
|
}
|
||||||
|
return cateUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.seimicrawler.xpath.JXDocument;
|
||||||
|
import org.seimicrawler.xpath.JXNode;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class XPbd extends XPath {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
String cateUrl = rule.getCateUrl();
|
||||||
|
if (filter && extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cateUrl = cateUrl.replace("{cateId}", tid).replace("{catePg}", pg);
|
||||||
|
Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(cateUrl);
|
||||||
|
while (m.find()) {
|
||||||
|
String n = m.group(0).replace("{", "").replace("}", "");
|
||||||
|
cateUrl = cateUrl.replace(m.group(0), "").replace("/" + n + "/", "");
|
||||||
|
}
|
||||||
|
return cateUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
String webUrl = rule.getDetailUrl().replace("{vid}", ids.get(0));
|
||||||
|
String webContent = fetch(webUrl);
|
||||||
|
JXDocument doc = JXDocument.create(webContent);
|
||||||
|
JXNode vodNode = doc.selNOne(rule.getDetailNode());
|
||||||
|
JSONObject vodAtom = new JSONObject();
|
||||||
|
|
||||||
|
String cover = "", title = "", desc = "", category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||||
|
|
||||||
|
title = vodNode.selOne(rule.getDetailName()).asString().trim();
|
||||||
|
title = rule.getDetailNameR(title);
|
||||||
|
|
||||||
|
cover = vodNode.selOne(rule.getDetailImg()).asString().trim();
|
||||||
|
cover = rule.getDetailImgR(cover);
|
||||||
|
cover = Misc.fixUrl(webUrl, cover);
|
||||||
|
|
||||||
|
if (!rule.getDetailCate().isEmpty()) {
|
||||||
|
try {
|
||||||
|
category = vodNode.selOne(rule.getDetailCate()).asString().trim();
|
||||||
|
category = rule.getDetailCateR(category);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailYear().isEmpty()) {
|
||||||
|
try {
|
||||||
|
year = vodNode.selOne(rule.getDetailYear()).asString().trim();
|
||||||
|
year = rule.getDetailYearR(year);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailArea().isEmpty()) {
|
||||||
|
try {
|
||||||
|
area = vodNode.selOne(rule.getDetailArea()).asString().trim();
|
||||||
|
area = rule.getDetailAreaR(area);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailMark().isEmpty()) {
|
||||||
|
try {
|
||||||
|
remark = vodNode.selOne(rule.getDetailMark()).asString().trim();
|
||||||
|
remark = rule.getDetailMarkR(remark);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailActor().isEmpty()) {
|
||||||
|
try {
|
||||||
|
actor = vodNode.selOne(rule.getDetailActor()).asString().trim();
|
||||||
|
actor = rule.getDetailActorR(actor);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailDirector().isEmpty()) {
|
||||||
|
try {
|
||||||
|
director = vodNode.selOne(rule.getDetailDirector()).asString().trim();
|
||||||
|
director = rule.getDetailDirectorR(director);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rule.getDetailDesc().isEmpty()) {
|
||||||
|
try {
|
||||||
|
desc = vodNode.selOne(rule.getDetailDesc()).asString().trim();
|
||||||
|
desc = rule.getDetailDescR(desc);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vodAtom.put("vod_name", title);
|
||||||
|
vodAtom.put("vod_pic", cover);
|
||||||
|
vodAtom.put("type_name", category);
|
||||||
|
vodAtom.put("vod_year", year);
|
||||||
|
vodAtom.put("vod_area", area);
|
||||||
|
vodAtom.put("vod_remarks", remark);
|
||||||
|
vodAtom.put("vod_actor", actor);
|
||||||
|
vodAtom.put("vod_director", director);
|
||||||
|
vodAtom.put("vod_content", desc);
|
||||||
|
|
||||||
|
List<JXNode> urlListNodes = doc.selN(rule.getDetailUrlNode());
|
||||||
|
for (int i = 0; i < urlListNodes.size(); i++) {
|
||||||
|
List<JXNode> urlNodes = urlListNodes.get(i).sel(rule.getDetailUrlSubNode());
|
||||||
|
for (int j = 0; j < urlNodes.size(); j++) {
|
||||||
|
String id = urlNodes.get(j).selOne(rule.getDetailUrlId()).asString().trim();
|
||||||
|
id = rule.getDetailUrlIdR(id);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray lists = new JSONArray();
|
||||||
|
vodAtom.put("vod_id", id);
|
||||||
|
vodAtom.put("vod_play_from", "磁力测试");
|
||||||
|
vodAtom.put("vod_play_url", "网站没资源$" + id);
|
||||||
|
lists.put(vodAtom);
|
||||||
|
result.put("list", lists);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,471 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Xiaoh extends Spider {
|
||||||
|
private static final String siteUrl = "https://www.xiaoheimi.net";
|
||||||
|
private static final String siteHost = "www.xiaoheimi.net";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/index.php/vod/type/id/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/index.php/vod/detail/id/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/index.php/vod/play/id/(\\d+)/sid/(\\d+)/nid/(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"gqy2\":{\"sh\":\"高清2\",\"sn\":0,\"pu\":\"\",\"or\":999},\"xbyy\":{\"sh\":\"高清\",\"sn\":0,\"pu\":\"\",\"or\":999},\"ysgc\":{\"sh\":\"高清源\",\"sn\":0,\"pu\":\"\",\"or\":999},\"if101\":{\"sh\":\"小宝影院\",\"sn\":0,\"pu\":\"\",\"or\":999},\"bili\":{\"sh\":\"bili\",\"sn\":0,\"pu\":\"\",\"or\":999},\"dplayer\":{\"sh\":\"DPlayer-H5播放器\",\"sn\":0,\"pu\":\"\",\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"1\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧片\",\"v\":\"喜剧片\"},{\"n\":\"冒险片\",\"v\":\"冒险片\"},{\"n\":\"剧情片\",\"v\":\"剧情片\"},{\"n\":\"动作片\",\"v\":\"动作片\"},{\"n\":\"动画电影\",\"v\":\"动画电影\"},{\"n\":\"同性片\",\"v\":\"同性片\"},{\"n\":\"奇幻片\",\"v\":\"奇幻片\"},{\"n\":\"恐怖片\",\"v\":\"恐怖片\"},{\"n\":\"悬疑片\",\"v\":\"悬疑片\"},{\"n\":\"惊悚片\",\"v\":\"惊悚片\"},{\"n\":\"歌舞片\",\"v\":\"歌舞片\"},{\"n\":\"灾难片\",\"v\":\"灾难片\"},{\"n\":\"爱情片\",\"v\":\"爱情片\"},{\"n\":\"犯罪片\",\"v\":\"犯罪片\"},{\"n\":\"科幻片\",\"v\":\"科幻片\"},{\"n\":\"经典片\",\"v\":\"经典片\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"},{\"n\":\"战争片\",\"v\":\"战争片\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"偶像\",\"v\":\"偶像\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"言情\",\"v\":\"言情\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"玄幻\",\"v\":\"玄幻\"},{\"n\":\"谍战\",\"v\":\"谍战\"},{\"n\":\"历险\",\"v\":\"历险\"},{\"n\":\"都市\",\"v\":\"都市\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"军旅\",\"v\":\"军旅\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"江湖\",\"v\":\"江湖\"},{\"n\":\"罪案\",\"v\":\"罪案\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"穿越\",\"v\":\"穿越\"},{\"n\":\"宫廷\",\"v\":\"宫廷\"},{\"n\":\"神话\",\"v\":\"神话\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"同性\",\"v\":\"同性\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"格斗\",\"v\":\"格斗\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"竞技\",\"v\":\"竞技\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"魔幻\",\"v\":\"魔幻\"},{\"n\":\"爆笑\",\"v\":\"爆笑\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"恋爱\",\"v\":\"恋爱\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"治愈\",\"v\":\"治愈\"},{\"n\":\"泡面\",\"v\":\"泡面\"},{\"n\":\"穿越\",\"v\":\"穿越\"},{\"n\":\"灵异\",\"v\":\"灵异\"},{\"n\":\"耽美\",\"v\":\"耽美\"},{\"n\":\"动画电影\",\"v\":\"动画电影\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"真人秀\",\"v\":\"真人秀\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"网综\",\"v\":\"网综\"},{\"n\":\"脱口秀\",\"v\":\"脱口秀\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"竞技\",\"v\":\"竞技\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"演唱会\",\"v\":\"演唱会\"},{\"n\":\"晚会\",\"v\":\"晚会\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"21\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"文化\",\"v\":\"文化\"},{\"n\":\"探索\",\"v\":\"探索\"},{\"n\":\"军事\",\"v\":\"军事\"},{\"n\":\"解密\",\"v\":\"解密\"},{\"n\":\"科技\",\"v\":\"科技\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"人物\",\"v\":\"人物\"},{\"n\":\"自然\",\"v\":\"自然\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"20\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Host", siteHost);
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul.nav-menu>li>a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = name.equals("电影") ||
|
||||||
|
name.equals("电视剧") ||
|
||||||
|
name.equals("动漫") ||
|
||||||
|
name.equals("综艺") ||
|
||||||
|
name.equals("纪录片") ||
|
||||||
|
name.equals("体育");
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("ul.myui-vodlist").get(1);
|
||||||
|
Elements list = homeList.select("div.myui-vodlist__box>a");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.attr("title");
|
||||||
|
String cover = vod.attr("data-original");
|
||||||
|
String remark = vod.selectFirst("span.pic-text").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/index.php/vod/show/id/";
|
||||||
|
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||||
|
url += extend.get("tid");
|
||||||
|
} else {
|
||||||
|
url += tid;
|
||||||
|
}
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url += "/page/" + pg + ".html";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select(".myui-page li a");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element a = pageInfo.get(i);
|
||||||
|
String name = a.text();
|
||||||
|
if (page == -1 && a.hasClass("btn-warm")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
page = Integer.parseInt(matcher.group(1).trim());
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.equals("尾页")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("div.myui-vodlist__box");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.selectFirst(".title").text();
|
||||||
|
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||||
|
String remark = vod.selectFirst("span.pic-text").text();
|
||||||
|
|
||||||
|
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 48);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/index.php/vod/detail/id/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
String vid = doc.selectFirst("span.mac_hits").attr("data-id");
|
||||||
|
|
||||||
|
String cover = doc.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||||
|
String title = doc.selectFirst("div.myui-content__detail h1.title").text();
|
||||||
|
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||||
|
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||||
|
Elements span_text_muted = doc.select("div.myui-content__detail span.text-muted");
|
||||||
|
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||||
|
Element text = span_text_muted.get(i);
|
||||||
|
String info = text.text();
|
||||||
|
if (info.equals("分类:")) {
|
||||||
|
category = text.nextElementSibling().text();
|
||||||
|
} else if (info.equals("年份:")) {
|
||||||
|
year = text.nextElementSibling().text();
|
||||||
|
} else if (info.equals("地区:")) {
|
||||||
|
area = text.nextElementSibling().text();
|
||||||
|
} else if (info.equals("更新:")) {
|
||||||
|
remark = text.nextElementSibling().text();
|
||||||
|
} else if (info.equals("导演:")) {
|
||||||
|
List<String> directors = new ArrayList<>();
|
||||||
|
Elements aa = text.parent().select("a");
|
||||||
|
for (int j = 0; j < aa.size(); j++) {
|
||||||
|
directors.add(aa.get(j).text());
|
||||||
|
}
|
||||||
|
director = TextUtils.join(",", directors);
|
||||||
|
} else if (info.equals("主演:")) {
|
||||||
|
List<String> actors = new ArrayList<>();
|
||||||
|
Elements aa = text.parent().select("a");
|
||||||
|
for (int j = 0; j < aa.size(); j++) {
|
||||||
|
actors.add(aa.get(j).text());
|
||||||
|
}
|
||||||
|
actor = TextUtils.join(",", actors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vodList.put("vod_id", vid);
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.myui-panel__head>ul").get(0).select("li");
|
||||||
|
Elements sourceList = doc.select("div.tab-content>div.tab-pane");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.text();
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = flag;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "/sid/" + matcher.group(2) + "/nid/" + matcher.group(3);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + "/index.php/vod/play/id/" + id + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) { // 取直链
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
String videoUrl = player.getString("url");
|
||||||
|
String playUrl = pCfg.getString("pu");
|
||||||
|
result.put("parse", pCfg.getInt("sn"));
|
||||||
|
result.put("playUrl", playUrl);
|
||||||
|
result.put("url", videoUrl);
|
||||||
|
result.put("header", "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
headers.put("Referer", siteUrl);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String url = "https://www.google.com/search?q=site%3A" + siteHost + "+" + URLEncoder.encode(key);
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, Headers()));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
Elements sourceList = doc.select("div.yuRUbf a");
|
||||||
|
for (int i = 0; i < sourceList.size(); i++) {
|
||||||
|
Element sourcess = sourceList.get(i);
|
||||||
|
String sourceName = sourcess.select("h3").text();
|
||||||
|
String list1 = sourcess.attr("href");
|
||||||
|
Matcher matcher = regexVid.matcher(list1);
|
||||||
|
if (sourceName.contains(key) && matcher.find()) {
|
||||||
|
Document ddrklink = Jsoup.parse(OkHttpUtil.string(list1, getHeaders(list1)));
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
String group = matcher.group(1);
|
||||||
|
String cover = ddrklink.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||||
|
String title = ddrklink.selectFirst("div.myui-content__detail h1.title").text();
|
||||||
|
Elements span_text_muted = ddrklink.select("div.myui-content__detail span.text-muted");
|
||||||
|
for (int j = 0; j < span_text_muted.size(); j++) {
|
||||||
|
Element text = span_text_muted.get(j);
|
||||||
|
String info = text.text();
|
||||||
|
if (info.equals("更新:")) {
|
||||||
|
String remark = text.nextElementSibling().text();
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
v.put("vod_id", group);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
|
||||||
|
import com.github.catvod.utils.Misc;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Xxys extends AppYsV2 {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSONObject getFinalVideo(String flag, ArrayList<String> parseUrls, String url) throws JSONException {
|
||||||
|
String htmlPlayUrl = "";
|
||||||
|
for (String parseUrl : parseUrls) {
|
||||||
|
if (parseUrl.isEmpty() || parseUrl.equals("null"))
|
||||||
|
continue;
|
||||||
|
String playUrl = parseUrl + url;
|
||||||
|
String content = desc(OkHttpUtil.string(playUrl, null), (byte) 4);
|
||||||
|
try {
|
||||||
|
HashMap hashMap = new HashMap();
|
||||||
|
OkHttpUtil.stringNoRedirect(playUrl, null, hashMap);
|
||||||
|
String d = OkHttpUtil.getRedirectLocation(hashMap);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", d);
|
||||||
|
return result;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
JSONObject tryJson = null;
|
||||||
|
try {
|
||||||
|
tryJson = Misc.jsonParse(url, content);
|
||||||
|
} catch (Throwable th) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (tryJson != null && tryJson.has("url") && tryJson.has("header")) {
|
||||||
|
tryJson.put("header", tryJson.getJSONObject("header").toString());
|
||||||
|
return tryJson;
|
||||||
|
}
|
||||||
|
if (content.contains("<html")) {
|
||||||
|
boolean sniffer = false;
|
||||||
|
for (Pattern p : htmlVideoKeyMatch) {
|
||||||
|
if (p.matcher(content).find()) {
|
||||||
|
sniffer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sniffer) {
|
||||||
|
htmlPlayUrl = parseUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!htmlPlayUrl.isEmpty()) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("parse", 1);
|
||||||
|
result.put("playUrl", htmlPlayUrl);
|
||||||
|
result.put("url", url);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, String str) {
|
||||||
|
super.init(context, "http://tvht.lanrentk.cc/api.php/iptv/vod");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
public class Zhaozy extends Spider {
|
||||||
|
private static final Pattern aliyun = Pattern.compile("(https://www.aliyundrive.com/s/[^\"]+)");
|
||||||
|
private PushAgent pushAgent;
|
||||||
|
|
||||||
|
public String detailContent(List<String> list) {
|
||||||
|
try {
|
||||||
|
Pattern pattern = aliyun;
|
||||||
|
if (pattern.matcher(list.get(0)).find()) {
|
||||||
|
return pushAgent.detailContent(list);
|
||||||
|
}
|
||||||
|
Matcher matcher = pattern.matcher(OkHttpUtil.string("https://zhaoziyuan.me/" + list.get(0), null));
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
list.set(0, matcher.group(1));
|
||||||
|
return pushAgent.detailContent(list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Context context, String str) {
|
||||||
|
super.init(context, str);
|
||||||
|
pushAgent = new PushAgent();
|
||||||
|
pushAgent.init(context, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String playerContent(String str, String str2, List<String> list) {
|
||||||
|
return pushAgent.playerContent(str, str2, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String, String> sHeaders() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
|
||||||
|
headers.put("Accept-encoding", "gzip, deflate, br");
|
||||||
|
headers.put("Accept-language", "zh-SG,zh;q=0.9,en-GB;q=0.8,en;q=0.7,zh-CN;q=0.6");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pattern regexVid = Pattern.compile("(\\S+)");
|
||||||
|
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String url = "https://zhaoziyuan.me/so?filename=" + URLEncoder.encode(key);
|
||||||
|
Document docs = Jsoup.parse(OkHttpUtil.string(url, null));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
Elements list = docs.select("div.li_con div.news_text");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element doc = list.get(i);
|
||||||
|
String sourceName = doc.select("div.news_text a h3").text();
|
||||||
|
if (sourceName.contains(key)) {
|
||||||
|
String list1 = doc.select("div.news_text a").attr("href");
|
||||||
|
Matcher matcher = regexVid.matcher(list1);
|
||||||
|
if (matcher.find()) {
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
String group = matcher.group(1);
|
||||||
|
String cover = "https://inews.gtimg.com/newsapp_bt/0/13263837859/1000";
|
||||||
|
String remark = doc.select("div.news_text a p").text();
|
||||||
|
|
||||||
|
v.put("vod_name", sourceName);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
v.put("vod_id", group);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,486 @@
|
|||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.Spider;
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Zxzj extends Spider {
|
||||||
|
private static final String siteUrl = "https://zxzj.vip/";
|
||||||
|
/**
|
||||||
|
* 播放源配置
|
||||||
|
*/
|
||||||
|
private JSONObject playerConfig;
|
||||||
|
/**
|
||||||
|
* 筛选配置
|
||||||
|
*/
|
||||||
|
private JSONObject filterConfig;
|
||||||
|
private Pattern regexCategory = Pattern.compile("/list/(\\d+).html");
|
||||||
|
private Pattern regexVid = Pattern.compile("/detail/(\\d+).html");
|
||||||
|
private Pattern regexPlay = Pattern.compile("/video/(\\d+)-(\\d+)-(\\d+).html");
|
||||||
|
private Pattern regexPage = Pattern.compile("/vodshow/(\\S+).html");
|
||||||
|
|
||||||
|
protected String ext = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
super.init(context);
|
||||||
|
try {
|
||||||
|
playerConfig = new JSONObject("{\"dpp\":{\"sh\":\"DP播放\",\"pu\":\"https://jx.zxzj.vip/dplayer.php?url=\",\"sn\":1,\"or\":999}}");
|
||||||
|
filterConfig = new JSONObject("{\"1\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"情色\",\"v\":\"情色\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"泰语\",\"v\":\"泰语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印度语\",\"v\":\"印度语\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"西班牙语\",\"v\":\"西班牙语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"法语\",\"v\":\"法语\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"6\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"1\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产\",\"v\":\"国产\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"4\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"5\":[{\"key\":\"3\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"11\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"2\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static HashMap<String, String> Headers() {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||||
|
headers.put("Referer", siteUrl);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 爬虫headers
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected HashMap<String, String> getHeaders(String url) {
|
||||||
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("method", "GET");
|
||||||
|
headers.put("Upgrade-Insecure-Requests", "1");
|
||||||
|
headers.put("DNT", "1");
|
||||||
|
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类数据 + 首页最近更新视频列表数据
|
||||||
|
*
|
||||||
|
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String homeContent(boolean filter) {
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||||
|
// 分类节点
|
||||||
|
Elements elements = doc.select("ul.stui-header__menu li a");
|
||||||
|
JSONArray classes = new JSONArray();
|
||||||
|
for (Element ele : elements) {
|
||||||
|
String name = ele.text();
|
||||||
|
boolean show = name.equals("电影") ||
|
||||||
|
name.equals("美剧") ||
|
||||||
|
name.equals("韩剧") ||
|
||||||
|
name.equals("日剧") ||
|
||||||
|
name.equals("泰剧") ||
|
||||||
|
name.equals("动漫");
|
||||||
|
if (show) {
|
||||||
|
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||||
|
if (!mather.find())
|
||||||
|
continue;
|
||||||
|
// 把分类的id和名称取出来加到列表里
|
||||||
|
String id = mather.group(1).trim();
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("type_id", id);
|
||||||
|
jsonObject.put("type_name", name);
|
||||||
|
classes.put(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
if (filter) {
|
||||||
|
result.put("filters", filterConfig);
|
||||||
|
}
|
||||||
|
result.put("class", classes);
|
||||||
|
try {
|
||||||
|
// 取首页推荐视频列表
|
||||||
|
Element homeList = doc.select("ul.stui-vodlist").get(0);
|
||||||
|
Elements list = homeList.select("div.stui-vodlist__box");
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.select("a").attr("title");
|
||||||
|
String cover = vod.select("a").attr("data-original");
|
||||||
|
String remark = vod.select("a .pic-text").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.select("a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类信息数据
|
||||||
|
*
|
||||||
|
* @param tid 分类id
|
||||||
|
* @param pg 页数
|
||||||
|
* @param filter 同homeContent方法中的filter
|
||||||
|
* @param extend 筛选参数{k:v, k1:v1}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
|
try {
|
||||||
|
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||||
|
urlParams[0] = tid;
|
||||||
|
urlParams[8] = pg;
|
||||||
|
if (extend != null && extend.size() > 0) {
|
||||||
|
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
String key = it.next();
|
||||||
|
String value = extend.get(key);
|
||||||
|
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取分类数据的url
|
||||||
|
String url = siteUrl + "vodshow/" + TextUtils.join("-", urlParams) + ".html";
|
||||||
|
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||||
|
Document doc = Jsoup.parse(html);
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
int pageCount = 0;
|
||||||
|
int page = -1;
|
||||||
|
|
||||||
|
// 取页码相关信息
|
||||||
|
Elements pageInfo = doc.select("ul.stui-page__item li");
|
||||||
|
if (pageInfo.size() == 0) {
|
||||||
|
page = Integer.parseInt(pg);
|
||||||
|
pageCount = page;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < pageInfo.size(); i++) {
|
||||||
|
Element li = pageInfo.get(i);
|
||||||
|
Element a = li.selectFirst("a");
|
||||||
|
if (a == null)
|
||||||
|
continue;
|
||||||
|
String name = a.text();
|
||||||
|
if (page == -1 && li.hasClass("active")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
//System.out.println("哈哈"+matcher.group(1));
|
||||||
|
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.equals("尾页")) {
|
||||||
|
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||||
|
if (matcher.find()) {
|
||||||
|
//System.out.println("尾页" + matcher.group(1));
|
||||||
|
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||||
|
} else {
|
||||||
|
pageCount = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
if (!html.contains("没有找到您想要的结果哦")) {
|
||||||
|
// 取当前分类页的视频列表
|
||||||
|
Elements list = doc.select("div.stui-vodlist__box");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.select("a").attr("title");
|
||||||
|
String cover = vod.select("a").attr("data-original");
|
||||||
|
String remark = vod.select("a .pic-text").text();
|
||||||
|
Matcher matcher = regexVid.matcher(vod.select("a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("page", page);
|
||||||
|
result.put("pagecount", pageCount);
|
||||||
|
result.put("limit", 48);
|
||||||
|
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||||
|
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频详情信息
|
||||||
|
*
|
||||||
|
* @param ids 视频id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String detailContent(List<String> ids) {
|
||||||
|
try {
|
||||||
|
// 视频详情url
|
||||||
|
String url = siteUrl + "/detail/" + ids.get(0) + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
JSONObject vodList = new JSONObject();
|
||||||
|
|
||||||
|
// 取基本数据
|
||||||
|
String cover = doc.select("div.stui-content__thumb a img").attr("data-original");
|
||||||
|
String title = doc.select("div.stui-content__detail h1").text();
|
||||||
|
String category = "", area = "", year = "", remark = "", director = "", actor = "", desc = "";
|
||||||
|
Elements data = doc.select("p.data");
|
||||||
|
Pattern cate = Pattern.compile("类型:(\\S+)");
|
||||||
|
category = doReplaceRegex(cate, data.get(0).text());
|
||||||
|
Pattern areas = Pattern.compile("地区:(\\S+)");
|
||||||
|
area = doReplaceRegex(areas, data.get(0).text());
|
||||||
|
Pattern years = Pattern.compile("年份:(\\S+)");
|
||||||
|
year = doReplaceRegex(years, data.get(0).text());
|
||||||
|
Pattern rms = Pattern.compile("更新:(\\S+)");
|
||||||
|
remark = doReplaceRegex(rms, data.get(3).text());
|
||||||
|
Pattern acs = Pattern.compile("主演:(\\S+)");
|
||||||
|
actor = doReplaceRegex(acs, data.get(1).text());
|
||||||
|
Pattern dis = Pattern.compile("导演:(\\S+)");
|
||||||
|
director = doReplaceRegex(dis, data.get(2).text());
|
||||||
|
|
||||||
|
desc = doc.selectFirst("span.detail-content").text().trim();
|
||||||
|
|
||||||
|
vodList.put("vod_id", ids.get(0));
|
||||||
|
vodList.put("vod_name", title);
|
||||||
|
vodList.put("vod_pic", cover);
|
||||||
|
vodList.put("type_name", category);
|
||||||
|
vodList.put("vod_year", year);
|
||||||
|
vodList.put("vod_area", area);
|
||||||
|
vodList.put("vod_remarks", remark);
|
||||||
|
vodList.put("vod_actor", actor);
|
||||||
|
vodList.put("vod_director", director);
|
||||||
|
vodList.put("vod_content", desc);
|
||||||
|
|
||||||
|
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
try {
|
||||||
|
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||||
|
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||||
|
|
||||||
|
if (sort1 == sort2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return sort1 - sort2 > 0 ? 1 : -1;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取播放列表数据
|
||||||
|
Elements sources = doc.select("div.stui-vodlist__head h3");
|
||||||
|
Elements sourceList = doc.select("ul.stui-content__playlist");
|
||||||
|
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
Element source = sources.get(i);
|
||||||
|
String sourceName = source.text();
|
||||||
|
boolean found = false;
|
||||||
|
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||||
|
String flag = it.next();
|
||||||
|
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||||
|
sourceName = flag;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
String playList = "";
|
||||||
|
Elements playListA = sourceList.get(i).select("li a");
|
||||||
|
List<String> vodItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < playListA.size(); j++) {
|
||||||
|
Element vod = playListA.get(j);
|
||||||
|
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||||
|
vodItems.add(vod.text() + "$" + playURL);
|
||||||
|
}
|
||||||
|
if (vodItems.size() > 0)
|
||||||
|
playList = TextUtils.join("#", vodItems);
|
||||||
|
|
||||||
|
if (playList.length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vod_play.put(sourceName, playList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vod_play.size() > 0) {
|
||||||
|
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||||
|
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||||
|
vodList.put("vod_play_from", vod_play_from);
|
||||||
|
vodList.put("vod_play_url", vod_play_url);
|
||||||
|
}
|
||||||
|
JSONArray list = new JSONArray();
|
||||||
|
list.put(vodList);
|
||||||
|
result.put("list", list);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频播放信息
|
||||||
|
*
|
||||||
|
* @param flag 播放源
|
||||||
|
* @param id 视频id
|
||||||
|
* @param vipFlags 所有可能需要vip解析的源
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||||
|
try {
|
||||||
|
//定义播放用的headers
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
//headers.put("Host", " cokemv.co");
|
||||||
|
headers.put("origin", " https://zxzj.vip");
|
||||||
|
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||||
|
headers.put("Accept", " */*");
|
||||||
|
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||||
|
headers.put("Accept-Encoding", " gzip, deflate");
|
||||||
|
|
||||||
|
|
||||||
|
// 播放页 url
|
||||||
|
String url = siteUrl + "/video/" + id + ".html";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
|
||||||
|
Elements allScript = doc.select("script");
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
for (int i = 0; i < allScript.size(); i++) {
|
||||||
|
String scContent = allScript.get(i).html().trim();
|
||||||
|
if (scContent.startsWith("var player_")) { // 取直链
|
||||||
|
int start = scContent.indexOf('{');
|
||||||
|
int end = scContent.lastIndexOf('}') + 1;
|
||||||
|
String json = scContent.substring(start, end);
|
||||||
|
JSONObject player = new JSONObject(json);
|
||||||
|
if (playerConfig.has(player.getString("from"))) {
|
||||||
|
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||||
|
String videoUrl = pCfg.getString("pu") + player.getString("url");
|
||||||
|
Document docs = Jsoup.parse(OkHttpUtil.string(videoUrl, getHeaders(videoUrl)));
|
||||||
|
Pattern pattern = Pattern.compile("(?<=urls\\s=\\s').*?(?=')");
|
||||||
|
Elements allScripts = docs.select("body script");
|
||||||
|
for (int j = 0; j < allScripts.size(); j++) {
|
||||||
|
String scContents = allScripts.get(j).html().trim();
|
||||||
|
Matcher matcher = pattern.matcher(scContents);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String players = matcher.group(0);
|
||||||
|
result.put("parse", 0);
|
||||||
|
result.put("playUrl", "");
|
||||||
|
result.put("url", players);
|
||||||
|
result.put("header", headers.toString());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param quick 是否播放页的快捷搜索
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String searchContent(String key, boolean quick) {
|
||||||
|
try {
|
||||||
|
String url = siteUrl + "/vodsearch/-------------.html?wd=" + URLEncoder.encode(key) + "&submit=";
|
||||||
|
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
|
||||||
|
JSONArray videos = new JSONArray();
|
||||||
|
Elements list = doc.select("div.stui-vodlist__box");
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Element vod = list.get(i);
|
||||||
|
String title = vod.select("a").attr("title");
|
||||||
|
if (title.contains(key)) {
|
||||||
|
String cover = vod.select("a").attr("data-original");
|
||||||
|
Matcher matcher = regexVid.matcher(vod.select("a").attr("href"));
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
String id = matcher.group(1);
|
||||||
|
JSONObject v = new JSONObject();
|
||||||
|
String remark = vod.select("a span.pic-text").text();
|
||||||
|
v.put("vod_id", id);
|
||||||
|
v.put("vod_name", title);
|
||||||
|
v.put("vod_pic", cover);
|
||||||
|
v.put("vod_remarks", remark);
|
||||||
|
videos.put(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("list", videos);
|
||||||
|
return result.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||||
|
if (pattern == null)
|
||||||
|
return src;
|
||||||
|
try {
|
||||||
|
Matcher matcher = pattern.matcher(src);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).trim();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package com.github.catvod.utils;
|
||||||
|
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.DESKeySpec;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
public class AES {
|
||||||
|
|
||||||
|
public static String CBC(String src, String KEY, String IV) {
|
||||||
|
try {
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
|
||||||
|
SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), "AES");
|
||||||
|
AlgorithmParameterSpec paramSpec = new IvParameterSpec(IV.getBytes());
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, keySpec, paramSpec);
|
||||||
|
return new String(cipher.doFinal(Base64.decode(src.getBytes(), 0)));
|
||||||
|
} catch (Exception exception) {
|
||||||
|
SpiderDebug.log(exception);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Cipher GetCipher(int opmode, String key) {
|
||||||
|
try {
|
||||||
|
DESKeySpec dks = new DESKeySpec(key.getBytes());
|
||||||
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||||
|
Key secretkey = keyFactory.generateSecret(dks);
|
||||||
|
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS7Padding");
|
||||||
|
cipher.init(opmode, secretkey);
|
||||||
|
return cipher;
|
||||||
|
} catch (Exception exception) {
|
||||||
|
SpiderDebug.log(exception);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String decode(String data, String key) throws Exception {
|
||||||
|
if (data == null || data.isEmpty()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] b = hex2byte(data);
|
||||||
|
Cipher cipher = GetCipher(Cipher.DECRYPT_MODE, key);
|
||||||
|
if (cipher != null){
|
||||||
|
return new String(cipher.doFinal(b), "UTF-8");
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (Exception exception) {
|
||||||
|
SpiderDebug.log(exception);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] hex2byte(String hex) throws IllegalArgumentException {
|
||||||
|
if (hex.length() % 2 != 0){
|
||||||
|
throw new IllegalArgumentException("invalid hex string");
|
||||||
|
}
|
||||||
|
char[] arr = hex.toCharArray();
|
||||||
|
byte[] b = new byte[hex.length() / 2];
|
||||||
|
for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
|
||||||
|
String swap ="" + arr[i++] + arr[i];
|
||||||
|
int byteint = Integer.parseInt(swap, 16) & 0xFF;
|
||||||
|
b[j] = new Integer(byteint).byteValue();
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encrypt(String data, String key) {
|
||||||
|
try {
|
||||||
|
byte[] data2 = data.getBytes("UTF-8");
|
||||||
|
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
|
||||||
|
byte[] result = cipher.doFinal(data2);
|
||||||
|
return bytesToHexStr(result);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
SpiderDebug.log(exception);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte数组转16进制字符串
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @return hex字符串
|
||||||
|
*/
|
||||||
|
public static String bytesToHexStr(byte[] bytes) {
|
||||||
|
StringBuilder hexStr = new StringBuilder();
|
||||||
|
for (byte b : bytes) {
|
||||||
|
String hex = Integer.toHexString(b & 0xFF);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
hex = '0' + hex;
|
||||||
|
}
|
||||||
|
hexStr.append(hex);
|
||||||
|
}
|
||||||
|
return hexStr.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.github.catvod.utils;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
public class CBC {
|
||||||
|
public static byte[] CBC(byte[] data, byte[] key, byte[] iv) {
|
||||||
|
try {
|
||||||
|
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
||||||
|
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
|
||||||
|
cipher.init(2, secretKeySpec, ivParameterSpec);
|
||||||
|
return cipher.doFinal(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package com.github.catvod.utils;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Misc {
|
||||||
|
public static boolean isVip(String url) {
|
||||||
|
// 适配2.0.6的调用应用内解析列表的支持, 需要配合直连分析一起使用,参考cjt影视和极品直连
|
||||||
|
try {
|
||||||
|
boolean isVip = false;
|
||||||
|
String host = Uri.parse(url).getHost();
|
||||||
|
String[] vipWebsites = new String[]{"iqiyi.com", "v.qq.com", "youku.com", "le.com", "tudou.com", "mgtv.com", "sohu.com", "acfun.cn", "bilibili.com", "baofeng.com", "pptv.com"};
|
||||||
|
for (int b = 0; b < vipWebsites.length; b++) {
|
||||||
|
if (host.contains(vipWebsites[b])) {
|
||||||
|
if ("iqiyi.com".equals(vipWebsites[b])) {
|
||||||
|
//爱奇艺需要特殊处理
|
||||||
|
if (url.contains("iqiyi.com/a_") || url.contains("iqiyi.com/w_") || url.contains("iqiyi.com/v_")) {
|
||||||
|
isVip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isVip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isVip;
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Pattern snifferMatch = Pattern.compile("http((?!http).){26,}?\\.(m3u8|mp4)\\?.*|http((?!http).){26,}\\.(m3u8|mp4)|http((?!http).){26,}?/m3u8\\?pt=m3u8.*|http((?!http).)*?default\\.ixigua\\.com/.*|http((?!http).)*?cdn-tos[^\\?]*|http((?!http).)*?/obj/tos[^\\?]*|http.*?/player/m3u8play\\.php\\?url=.*|http.*?/player/.*?[pP]lay\\.php\\?url=.*|http.*?/playlist/m3u8/\\?vid=.*|http.*?\\.php\\?type=m3u8&.*|http.*?/download.aspx\\?.*|http.*?/api/up_api.php\\?.*|https.*?\\.66yk\\.cn.*|http((?!http).)*?netease\\.com/file/.*");
|
||||||
|
|
||||||
|
public static boolean isVideoFormat(String url) {
|
||||||
|
if (snifferMatch.matcher(url).find()) {
|
||||||
|
if (url.contains("cdn-tos") && url.contains(".js")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String fixUrl(String base, String src) {
|
||||||
|
try {
|
||||||
|
if (src.startsWith("//")) {
|
||||||
|
Uri parse = Uri.parse(base);
|
||||||
|
src = parse.getScheme() + ":" + src;
|
||||||
|
} else if (!src.contains("://")) {
|
||||||
|
Uri parse = Uri.parse(base);
|
||||||
|
src = parse.getScheme() + "://" + parse.getHost() + src;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBlackVodUrl(String input, String url) {
|
||||||
|
if (url.contains("973973.xyz") || url.contains(".fit:"))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String UaWinChrome = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36";
|
||||||
|
|
||||||
|
public static JSONObject fixJsonVodHeader(JSONObject headers, String input, String url) throws JSONException {
|
||||||
|
if (headers == null)
|
||||||
|
headers = new JSONObject();
|
||||||
|
if (input.contains("www.mgtv.com")) {
|
||||||
|
headers.put("Referer", " ");
|
||||||
|
headers.put("User-Agent", " Mozilla/5.0");
|
||||||
|
} else if (url.contains("titan.mgtv")) {
|
||||||
|
headers.put("Referer", " ");
|
||||||
|
headers.put("User-Agent", " Mozilla/5.0");
|
||||||
|
} else if (input.contains("bilibili")) {
|
||||||
|
headers.put("Referer", " https://www.bilibili.com/");
|
||||||
|
headers.put("User-Agent", " " + Misc.UaWinChrome);
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject jsonParse(String input, String json) throws JSONException {
|
||||||
|
JSONObject jsonPlayData = new JSONObject(json);
|
||||||
|
String url;
|
||||||
|
if (jsonPlayData.has("data")) {
|
||||||
|
url = jsonPlayData.getJSONObject("data").getString("url");
|
||||||
|
} else {
|
||||||
|
url = jsonPlayData.getString("url");
|
||||||
|
}
|
||||||
|
if (url.startsWith("//")) {
|
||||||
|
url = "https:" + url;
|
||||||
|
}
|
||||||
|
if (!url.startsWith("http")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (url.equals(input)) {
|
||||||
|
if (isVip(url) || !isVideoFormat(url)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Misc.isBlackVodUrl(input, url)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject headers = new JSONObject();
|
||||||
|
String ua = jsonPlayData.optString("user-agent", "");
|
||||||
|
if (ua.trim().length() > 0) {
|
||||||
|
headers.put("User-Agent", " " + ua);
|
||||||
|
}
|
||||||
|
String referer = jsonPlayData.optString("referer", "");
|
||||||
|
if (referer.trim().length() > 0) {
|
||||||
|
headers.put("Referer", " " + referer);
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = Misc.fixJsonVodHeader(headers, input, url);
|
||||||
|
JSONObject taskResult = new JSONObject();
|
||||||
|
taskResult.put("header", headers);
|
||||||
|
taskResult.put("url", url);
|
||||||
|
return taskResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Charset CharsetUTF8 = Charset.forName("UTF-8");
|
||||||
|
public static Charset CharsetIOS8859 = Charset.forName("iso-8859-1");
|
||||||
|
|
||||||
|
public static String MD5(String src, Charset charset) {
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] bytes = md.digest(src.getBytes(charset));
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
int v = bytes[i] & 0xFF;
|
||||||
|
String hv = Integer.toHexString(v);
|
||||||
|
if (hv.length() < 2) {
|
||||||
|
sb.append(0);
|
||||||
|
}
|
||||||
|
sb.append(hv);
|
||||||
|
}
|
||||||
|
return sb.toString().toLowerCase();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package com.github.catvod.utils;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
public class SSLSocketFactoryCompat extends SSLSocketFactory {
|
||||||
|
private SSLSocketFactory defaultFactory;
|
||||||
|
// Android 5.0+ (API level21) provides reasonable default settings
|
||||||
|
// but it still allows SSLv3
|
||||||
|
// https://developer.android.com/about/versions/android-5.0-changes.html#ssl
|
||||||
|
static String protocols[] = null, cipherSuites[] = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
|
||||||
|
if (socket != null) {
|
||||||
|
/* set reasonable protocol versions */
|
||||||
|
// - enable all supported protocols (enables TLSv1.1 and TLSv1.2 on Android <5.0)
|
||||||
|
// - remove all SSL versions (especially SSLv3) because they're insecure now
|
||||||
|
List<String> protocols = new LinkedList<>();
|
||||||
|
for (String protocol : socket.getSupportedProtocols())
|
||||||
|
if (!protocol.toUpperCase().contains("SSL"))
|
||||||
|
protocols.add(protocol);
|
||||||
|
SSLSocketFactoryCompat.protocols = protocols.toArray(new String[protocols.size()]);
|
||||||
|
/* set up reasonable cipher suites */
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
// choose known secure cipher suites
|
||||||
|
List<String> allowedCiphers = Arrays.asList(
|
||||||
|
// TLS 1.2
|
||||||
|
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||||
|
"TLS_ECHDE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
// maximum interoperability
|
||||||
|
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
// additionally
|
||||||
|
"TLS_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
|
||||||
|
List<String> availableCiphers = Arrays.asList(socket.getSupportedCipherSuites());
|
||||||
|
// take all allowed ciphers that are available and put them into preferredCiphers
|
||||||
|
HashSet<String> preferredCiphers = new HashSet<>(allowedCiphers);
|
||||||
|
preferredCiphers.retainAll(availableCiphers);
|
||||||
|
/* For maximum security, preferredCiphers should *replace* enabled ciphers (thus disabling
|
||||||
|
* ciphers which are enabled by default, but have become unsecure), but I guess for
|
||||||
|
* the security level of DAVdroid and maximum compatibility, disabling of insecure
|
||||||
|
* ciphers should be a server-side task */
|
||||||
|
// add preferred ciphers to enabled ciphers
|
||||||
|
HashSet<String> enabledCiphers = preferredCiphers;
|
||||||
|
enabledCiphers.addAll(new HashSet<>(Arrays.asList(socket.getEnabledCipherSuites())));
|
||||||
|
SSLSocketFactoryCompat.cipherSuites = enabledCiphers.toArray(new String[enabledCiphers.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSLSocketFactoryCompat(X509TrustManager tm) {
|
||||||
|
try {
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
|
sslContext.init(null, (tm != null) ? new X509TrustManager[]{tm} : null, null);
|
||||||
|
defaultFactory = sslContext.getSocketFactory();
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new AssertionError(); // The system has no TLS. Just give up.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void upgradeTLS(SSLSocket ssl) {
|
||||||
|
// Android 5.0+ (API level21) provides reasonable default settings
|
||||||
|
// but it still allows SSLv3
|
||||||
|
// https://developer.android.com/about/versions/android-5.0-changes.html#ssl
|
||||||
|
if (protocols != null) {
|
||||||
|
ssl.setEnabledProtocols(protocols);
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && cipherSuites != null) {
|
||||||
|
ssl.setEnabledCipherSuites(cipherSuites);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getDefaultCipherSuites() {
|
||||||
|
return cipherSuites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSupportedCipherSuites() {
|
||||||
|
return cipherSuites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(s, host, port, autoClose);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(host, port);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(host, port, localHost, localPort);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress host, int port) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(host, port);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(address, port, localAddress, localPort);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//定义一个信任所有证书的TrustManager
|
||||||
|
public static final X509TrustManager trustAllCert = new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new java.security.cert.X509Certificate[]{};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.github.catvod.utils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
|
public class SpiderOKClient {
|
||||||
|
private static OkHttpClient noRedirectClient = null;
|
||||||
|
|
||||||
|
public static OkHttpClient noRedirectClient() {
|
||||||
|
if (noRedirectClient == null) {
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||||
|
.readTimeout(15, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(15, TimeUnit.SECONDS)
|
||||||
|
.connectTimeout(15, TimeUnit.SECONDS)
|
||||||
|
.followRedirects(false)
|
||||||
|
.followSslRedirects(false)
|
||||||
|
.retryOnConnectionFailure(true)
|
||||||
|
.sslSocketFactory(new SSLSocketFactoryCompat(SSLSocketFactoryCompat.trustAllCert), SSLSocketFactoryCompat.trustAllCert);
|
||||||
|
noRedirectClient = builder.build();
|
||||||
|
}
|
||||||
|
return noRedirectClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRedirectLocation(Map<String, List<String>> headers) {
|
||||||
|
if (headers == null)
|
||||||
|
return null;
|
||||||
|
if (headers.containsKey("location"))
|
||||||
|
return headers.get("location").get(0);
|
||||||
|
if (headers.containsKey("Location"))
|
||||||
|
return headers.get("Location").get(0);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.github.catvod.utils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
|
public class gZip {
|
||||||
|
public static String KS(byte[] bArr) throws IOException {
|
||||||
|
GZIPInputStream gZIPInputStream = new GZIPInputStream(new ByteArrayInputStream(bArr));
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
byte[] bArr2 = new byte[1024];
|
||||||
|
while (true) {
|
||||||
|
int read = gZIPInputStream.read(bArr2);
|
||||||
|
if (read == -1) {
|
||||||
|
return byteArrayOutputStream.toString("UTF-8");
|
||||||
|
}
|
||||||
|
byteArrayOutputStream.write(bArr2, 0, read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.github.catvod.utils.okhttp;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class OKCallBack<T> {
|
||||||
|
|
||||||
|
private T result = null;
|
||||||
|
|
||||||
|
public T getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setResult(T val) {
|
||||||
|
result = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onError(final Call call, final Exception e) {
|
||||||
|
onFailure(call, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onSuccess(Call call, Response response) {
|
||||||
|
T obj = onParseResponse(call, response);
|
||||||
|
setResult(obj);
|
||||||
|
onResponse(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T onParseResponse(Call call, Response response);
|
||||||
|
|
||||||
|
protected abstract void onFailure(Call call, Exception e);
|
||||||
|
|
||||||
|
protected abstract void onResponse(T response);
|
||||||
|
|
||||||
|
public static abstract class OKCallBackDefault extends OKCallBack<Response> {
|
||||||
|
@Override
|
||||||
|
public Response onParseResponse(Call call, Response response) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class OKCallBackString extends OKCallBack<String> {
|
||||||
|
@Override
|
||||||
|
public void onError(Call call, Exception e) {
|
||||||
|
setResult("");
|
||||||
|
super.onError(call, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String onParseResponse(Call call, Response response) {
|
||||||
|
try {
|
||||||
|
return response.body().string();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package com.github.catvod.utils.okhttp;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.Callback;
|
||||||
|
import okhttp3.FormBody;
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
class OKRequest {
|
||||||
|
private final String mMethodType;
|
||||||
|
private String mUrl;
|
||||||
|
private Object mTag = null;
|
||||||
|
private final Map<String, String> mParamsMap;
|
||||||
|
private final String mJsonStr;
|
||||||
|
private final Map<String, String> mHeaderMap;
|
||||||
|
private final OKCallBack mCallBack;
|
||||||
|
private okhttp3.Request mOkHttpRequest;
|
||||||
|
private okhttp3.Request.Builder mRequestBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
OKRequest(String methodType, String url, Map<String, String> paramsMap, Map<String, String> headerMap, OKCallBack callBack) {
|
||||||
|
this(methodType, url, null, paramsMap, headerMap, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
OKRequest(String methodType, String url, String jsonStr, Map<String, String> headerMap, OKCallBack callBack) {
|
||||||
|
this(methodType, url, jsonStr, null, headerMap, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OKRequest(String methodType, String url, String jsonStr, Map<String, String> paramsMap, Map<String, String> headerMap, OKCallBack callBack) {
|
||||||
|
mMethodType = methodType;
|
||||||
|
mUrl = url;
|
||||||
|
mJsonStr = jsonStr;
|
||||||
|
mParamsMap = paramsMap;
|
||||||
|
mHeaderMap = headerMap;
|
||||||
|
mCallBack = callBack;
|
||||||
|
getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(Object tag) {
|
||||||
|
mTag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getInstance() {
|
||||||
|
mRequestBuilder = new okhttp3.Request.Builder();
|
||||||
|
switch (mMethodType) {
|
||||||
|
case OkHttpUtil.METHOD_GET:
|
||||||
|
setGetParams();
|
||||||
|
break;
|
||||||
|
case OkHttpUtil.METHOD_POST:
|
||||||
|
mRequestBuilder.post(getRequestBody());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mRequestBuilder.url(mUrl);
|
||||||
|
if (mTag != null)
|
||||||
|
mRequestBuilder.tag(mTag);
|
||||||
|
if (mHeaderMap != null) {
|
||||||
|
setHeader();
|
||||||
|
}
|
||||||
|
mOkHttpRequest = mRequestBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestBody getRequestBody() {
|
||||||
|
if (!TextUtils.isEmpty(mJsonStr)) {
|
||||||
|
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||||
|
return RequestBody.create(JSON, mJsonStr);
|
||||||
|
}
|
||||||
|
FormBody.Builder formBody = new FormBody.Builder();
|
||||||
|
if (mParamsMap != null) {
|
||||||
|
for (String key : mParamsMap.keySet()) {
|
||||||
|
formBody.add(key, mParamsMap.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formBody.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setGetParams() {
|
||||||
|
if (mParamsMap != null) {
|
||||||
|
mUrl = mUrl + "?";
|
||||||
|
for (String key : mParamsMap.keySet()) {
|
||||||
|
mUrl = mUrl + key + "=" + mParamsMap.get(key) + "&";
|
||||||
|
}
|
||||||
|
mUrl = mUrl.substring(0, mUrl.length() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setHeader() {
|
||||||
|
if (mHeaderMap != null) {
|
||||||
|
for (String key : mHeaderMap.keySet()) {
|
||||||
|
mRequestBuilder.addHeader(key, mHeaderMap.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute(OkHttpClient client) {
|
||||||
|
Call call = client.newCall(mOkHttpRequest);
|
||||||
|
try {
|
||||||
|
Response response = call.execute();
|
||||||
|
if (mCallBack != null) {
|
||||||
|
mCallBack.onSuccess(call, response);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (mCallBack != null) {
|
||||||
|
mCallBack.onError(call, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void call(OkHttpClient client) {
|
||||||
|
client.newCall(mOkHttpRequest).enqueue(new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(final Call call, final IOException e) {
|
||||||
|
if (mCallBack != null) {
|
||||||
|
mCallBack.onError(call, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponse(final Call call, final Response response) throws IOException {
|
||||||
|
if (mCallBack != null) {
|
||||||
|
mCallBack.onSuccess(call, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
package com.github.catvod.utils.okhttp;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class OkHttpUtil {
|
||||||
|
|
||||||
|
public static final String METHOD_GET = "GET";
|
||||||
|
public static final String METHOD_POST = "POST";
|
||||||
|
|
||||||
|
private static final int DEFAULT_TIMEOUT = 15;
|
||||||
|
|
||||||
|
private static final Object lockO = new Object();
|
||||||
|
|
||||||
|
private static OkHttpClient defaultClient = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不自动重定向
|
||||||
|
*/
|
||||||
|
private static OkHttpClient noRedirectClient = null;
|
||||||
|
|
||||||
|
public static OkHttpClient defaultClient() {
|
||||||
|
synchronized (lockO) {
|
||||||
|
if (defaultClient == null) {
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||||
|
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.retryOnConnectionFailure(true)
|
||||||
|
.sslSocketFactory(new SSLSocketFactoryCompat(SSLSocketFactoryCompat.trustAllCert), SSLSocketFactoryCompat.trustAllCert);
|
||||||
|
defaultClient = builder.build();
|
||||||
|
}
|
||||||
|
return defaultClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OkHttpClient noRedirectClient() {
|
||||||
|
synchronized (lockO) {
|
||||||
|
if (noRedirectClient == null) {
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||||
|
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||||
|
.followRedirects(false)
|
||||||
|
.followSslRedirects(false)
|
||||||
|
.retryOnConnectionFailure(true)
|
||||||
|
.sslSocketFactory(new SSLSocketFactoryCompat(SSLSocketFactoryCompat.trustAllCert), SSLSocketFactoryCompat.trustAllCert);
|
||||||
|
noRedirectClient = builder.build();
|
||||||
|
}
|
||||||
|
return noRedirectClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String string(OkHttpClient client, String url, String tag, Map<String, String> paramsMap, Map<String, String> headerMap, Map<String, List<String>> respHeaderMap) {
|
||||||
|
OKCallBack<String> stringCallback = new OKCallBack<String>() {
|
||||||
|
@Override
|
||||||
|
public String onParseResponse(Call call, Response response) {
|
||||||
|
try {
|
||||||
|
if (respHeaderMap != null) {
|
||||||
|
respHeaderMap.clear();
|
||||||
|
respHeaderMap.putAll(response.headers().toMultimap());
|
||||||
|
}
|
||||||
|
return response.body().string();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, Exception e) {
|
||||||
|
setResult("");
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponse(String response) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OKRequest req = new OKRequest(METHOD_GET, url, paramsMap, headerMap, stringCallback);
|
||||||
|
req.setTag(tag);
|
||||||
|
req.execute(client);
|
||||||
|
return stringCallback.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String stringNoRedirect(String url, Map<String, String> headerMap, Map<String, List<String>> respHeaderMap) {
|
||||||
|
return string(noRedirectClient(), url, null, null, headerMap, respHeaderMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String string(String url, Map<String, String> headerMap, Map<String, List<String>> respHeaderMap) {
|
||||||
|
return string(defaultClient(), url, null, null, headerMap, respHeaderMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String string(String url, Map<String, String> headerMap) {
|
||||||
|
return string(defaultClient(), url, null, null, headerMap, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String string(String url, String tag, Map<String, String> headerMap) {
|
||||||
|
return string(defaultClient(), url, tag, null, headerMap, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void get(OkHttpClient client, String url, OKCallBack callBack) {
|
||||||
|
get(client, url, null, null, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void get(OkHttpClient client, String url, Map<String, String> paramsMap, OKCallBack callBack) {
|
||||||
|
get(client, url, paramsMap, null, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void get(OkHttpClient client, String url, Map<String, String> paramsMap, Map<String, String> headerMap, OKCallBack callBack) {
|
||||||
|
new OKRequest(METHOD_GET, url, paramsMap, headerMap, callBack).execute(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void post(OkHttpClient client, String url, OKCallBack callBack) {
|
||||||
|
post(client, url, null, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void post(OkHttpClient client, String url, Map<String, String> paramsMap, OKCallBack callBack) {
|
||||||
|
post(client, url, paramsMap, null, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void post(OkHttpClient client, String url, Map<String, String> paramsMap, Map<String, String> headerMap, OKCallBack callBack) {
|
||||||
|
new OKRequest(METHOD_POST, url, paramsMap, headerMap, callBack).execute(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void post(OkHttpClient client, String url, String tag, Map<String, String> paramsMap, Map<String, String> headerMap, OKCallBack callBack) {
|
||||||
|
OKRequest req = new OKRequest(METHOD_POST, url, paramsMap, headerMap, callBack);
|
||||||
|
req.setTag(tag);
|
||||||
|
req.execute(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void postJson(OkHttpClient client, String url, String jsonStr, OKCallBack callBack) {
|
||||||
|
postJson(client, url, jsonStr, null, callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void postJson(OkHttpClient client, String url, String jsonStr, Map<String, String> headerMap, OKCallBack callBack) {
|
||||||
|
new OKRequest(METHOD_POST, url, jsonStr, headerMap, callBack).execute(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据Tag取消请求
|
||||||
|
*/
|
||||||
|
public static void cancel(OkHttpClient client, Object tag) {
|
||||||
|
if (client == null || tag == null) return;
|
||||||
|
for (Call call : client.dispatcher().queuedCalls()) {
|
||||||
|
if (tag.equals(call.request().tag())) {
|
||||||
|
call.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Call call : client.dispatcher().runningCalls()) {
|
||||||
|
if (tag.equals(call.request().tag())) {
|
||||||
|
call.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancel(Object tag) {
|
||||||
|
cancel(defaultClient(), tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelAll() {
|
||||||
|
cancelAll(defaultClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消所有请求请求
|
||||||
|
*/
|
||||||
|
public static void cancelAll(OkHttpClient client) {
|
||||||
|
if (client == null) return;
|
||||||
|
for (Call call : client.dispatcher().queuedCalls()) {
|
||||||
|
call.cancel();
|
||||||
|
}
|
||||||
|
for (Call call : client.dispatcher().runningCalls()) {
|
||||||
|
call.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取重定向地址
|
||||||
|
*
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getRedirectLocation(Map<String, List<String>> headers) {
|
||||||
|
if (headers == null)
|
||||||
|
return null;
|
||||||
|
if (headers.containsKey("location"))
|
||||||
|
return headers.get("location").get(0);
|
||||||
|
if (headers.containsKey("Location"))
|
||||||
|
return headers.get("Location").get(0);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package com.github.catvod.utils.okhttp;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
public class SSLSocketFactoryCompat extends SSLSocketFactory {
|
||||||
|
private final SSLSocketFactory defaultFactory;
|
||||||
|
// Android 5.0+ (API level21) provides reasonable default settings
|
||||||
|
// but it still allows SSLv3
|
||||||
|
// https://developer.android.com/about/versions/android-5.0-changes.html#ssl
|
||||||
|
static String[] protocols = null;
|
||||||
|
static String[] cipherSuites = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
|
||||||
|
if (socket != null) {
|
||||||
|
/* set reasonable protocol versions */
|
||||||
|
// - enable all supported protocols (enables TLSv1.1 and TLSv1.2 on Android <5.0)
|
||||||
|
// - remove all SSL versions (especially SSLv3) because they're insecure now
|
||||||
|
List<String> protocols = new LinkedList<>();
|
||||||
|
for (String protocol : socket.getSupportedProtocols())
|
||||||
|
if (!protocol.toUpperCase().contains("SSL"))
|
||||||
|
protocols.add(protocol);
|
||||||
|
SSLSocketFactoryCompat.protocols = protocols.toArray(new String[protocols.size()]);
|
||||||
|
/* set up reasonable cipher suites */
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
// choose known secure cipher suites
|
||||||
|
List<String> allowedCiphers = Arrays.asList(
|
||||||
|
// TLS 1.2
|
||||||
|
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||||
|
"TLS_ECHDE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
// maximum interoperability
|
||||||
|
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
// additionally
|
||||||
|
"TLS_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
|
||||||
|
List<String> availableCiphers = Arrays.asList(socket.getSupportedCipherSuites());
|
||||||
|
// take all allowed ciphers that are available and put them into preferredCiphers
|
||||||
|
HashSet<String> preferredCiphers = new HashSet<>(allowedCiphers);
|
||||||
|
preferredCiphers.retainAll(availableCiphers);
|
||||||
|
/* For maximum security, preferredCiphers should *replace* enabled ciphers (thus disabling
|
||||||
|
* ciphers which are enabled by default, but have become unsecure), but I guess for
|
||||||
|
* the security level of DAVdroid and maximum compatibility, disabling of insecure
|
||||||
|
* ciphers should be a server-side task */
|
||||||
|
// add preferred ciphers to enabled ciphers
|
||||||
|
HashSet<String> enabledCiphers = preferredCiphers;
|
||||||
|
enabledCiphers.addAll(new HashSet<>(Arrays.asList(socket.getEnabledCipherSuites())));
|
||||||
|
SSLSocketFactoryCompat.cipherSuites = enabledCiphers.toArray(new String[enabledCiphers.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSLSocketFactoryCompat(X509TrustManager tm) {
|
||||||
|
try {
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
|
sslContext.init(null, (tm != null) ? new X509TrustManager[]{tm} : null, null);
|
||||||
|
defaultFactory = sslContext.getSocketFactory();
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new AssertionError(); // The system has no TLS. Just give up.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void upgradeTLS(SSLSocket ssl) {
|
||||||
|
// Android 5.0+ (API level21) provides reasonable default settings
|
||||||
|
// but it still allows SSLv3
|
||||||
|
// https://developer.android.com/about/versions/android-5.0-changes.html#ssl
|
||||||
|
if (protocols != null) {
|
||||||
|
ssl.setEnabledProtocols(protocols);
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && cipherSuites != null) {
|
||||||
|
ssl.setEnabledCipherSuites(cipherSuites);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getDefaultCipherSuites() {
|
||||||
|
return cipherSuites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSupportedCipherSuites() {
|
||||||
|
return cipherSuites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(s, host, port, autoClose);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String host, int port) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(host, port);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(host, port, localHost, localPort);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress host, int port) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(host, port);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
|
||||||
|
Socket ssl = defaultFactory.createSocket(address, port, localAddress, localPort);
|
||||||
|
if (ssl instanceof SSLSocket)
|
||||||
|
upgradeTLS((SSLSocket) ssl);
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//定义一个信任所有证书的TrustManager
|
||||||
|
public static final X509TrustManager trustAllCert = new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new java.security.cert.X509Certificate[]{};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,687 @@
|
|||||||
|
package com.github.catvod.xpath;
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
public class XPathRule {
|
||||||
|
/**
|
||||||
|
* user-agent
|
||||||
|
*/
|
||||||
|
private String ua;
|
||||||
|
/**
|
||||||
|
* 获取分类和首页推荐的Url
|
||||||
|
*/
|
||||||
|
private String homeUrl;
|
||||||
|
/**
|
||||||
|
* 分类节点 xpath
|
||||||
|
*/
|
||||||
|
private String cateNode;
|
||||||
|
/**
|
||||||
|
* 分类节点名 xpath
|
||||||
|
*/
|
||||||
|
private String cateName;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern cateNameR;
|
||||||
|
/**
|
||||||
|
* 分类节点id xpath
|
||||||
|
*/
|
||||||
|
private String cateId;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern cateIdR;
|
||||||
|
/**
|
||||||
|
* 手动指定 分类 如果有则不从homeUrl中获取分类
|
||||||
|
*/
|
||||||
|
private LinkedHashMap<String, String> cateManual = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 筛选
|
||||||
|
*/
|
||||||
|
private JSONObject filter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新推荐视频节点 xpath
|
||||||
|
*/
|
||||||
|
private String homeVodNode;
|
||||||
|
/**
|
||||||
|
* 更新推荐视频名称 xpath
|
||||||
|
*/
|
||||||
|
private String homeVodName;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern homeVodNameR;
|
||||||
|
/**
|
||||||
|
* 更新推荐视频id xpath
|
||||||
|
*/
|
||||||
|
private String homeVodId;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern homeVodIdR;
|
||||||
|
/**
|
||||||
|
* 更新推荐视频图片 xpath
|
||||||
|
*/
|
||||||
|
private String homeVodImg;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern homeVodImgR;
|
||||||
|
/**
|
||||||
|
* 更新推荐视频简介 xpath
|
||||||
|
*/
|
||||||
|
private String homeVodMark;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern homeVodMarkR;
|
||||||
|
/**
|
||||||
|
* 分类页地址
|
||||||
|
*/
|
||||||
|
private String cateUrl;
|
||||||
|
/**
|
||||||
|
* 分类叶视频节点 xpath
|
||||||
|
*/
|
||||||
|
private String cateVodNode;
|
||||||
|
/**
|
||||||
|
* 分类叶视频名称 xpath
|
||||||
|
*/
|
||||||
|
private String cateVodName;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern cateVodNameR;
|
||||||
|
/**
|
||||||
|
* 分类叶视频视频id xpath
|
||||||
|
*/
|
||||||
|
private String cateVodId;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern cateVodIdR;
|
||||||
|
/**
|
||||||
|
* 分类叶视频视频图片 xpath
|
||||||
|
*/
|
||||||
|
private String cateVodImg;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern cateVodImgR;
|
||||||
|
/**
|
||||||
|
* 分类叶视频视频简介 xpath
|
||||||
|
*/
|
||||||
|
private String cateVodMark;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern cateVodMarkR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情页面
|
||||||
|
*/
|
||||||
|
private String dtUrl;
|
||||||
|
/**
|
||||||
|
* 详情节点 xpath
|
||||||
|
*/
|
||||||
|
private String dtNode;
|
||||||
|
/**
|
||||||
|
* 详情 视频名 xpath
|
||||||
|
*/
|
||||||
|
private String dtName;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtNameR;
|
||||||
|
/**
|
||||||
|
* 详情视频图片 xpath
|
||||||
|
*/
|
||||||
|
private String dtImg;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtImgR;
|
||||||
|
/**
|
||||||
|
* 详情视频分类 xpath
|
||||||
|
*/
|
||||||
|
private String dtCate;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtCateR;
|
||||||
|
/**
|
||||||
|
* 详情视频年份 xpath
|
||||||
|
*/
|
||||||
|
private String dtYear;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtYearR;
|
||||||
|
/**
|
||||||
|
* 详情视频地区 xpath
|
||||||
|
*/
|
||||||
|
private String dtArea;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtAreaR;
|
||||||
|
/**
|
||||||
|
* 详情视频简介 xpath
|
||||||
|
*/
|
||||||
|
private String dtMark;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtMarkR;
|
||||||
|
/**
|
||||||
|
* 详情演员 xpath
|
||||||
|
*/
|
||||||
|
private String dtActor;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtActorR;
|
||||||
|
/**
|
||||||
|
* 详情导演 xpath
|
||||||
|
*/
|
||||||
|
private String dtDirector;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtDirectorR;
|
||||||
|
/**
|
||||||
|
* 详情 说明 长 xpath
|
||||||
|
*/
|
||||||
|
private String dtDesc;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern dtDescR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情播放来源节点
|
||||||
|
*/
|
||||||
|
private String dtFromNode;
|
||||||
|
/**
|
||||||
|
* 详情播放来源名称 xpath
|
||||||
|
*/
|
||||||
|
private String dtFromName;
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
private Pattern dtFromNameR;
|
||||||
|
/**
|
||||||
|
* 详情播放地址列表节点 xpath
|
||||||
|
*/
|
||||||
|
private String dtUrlNode;
|
||||||
|
/**
|
||||||
|
* 详情播放地址节点 xpath
|
||||||
|
*/
|
||||||
|
private String dtUrlSubNode;
|
||||||
|
/**
|
||||||
|
* 详情播放地址id xpath
|
||||||
|
*/
|
||||||
|
private String dtUrlId;
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
private Pattern dtUrlIdR;
|
||||||
|
/**
|
||||||
|
* 详情播放地址名称 xpath
|
||||||
|
*/
|
||||||
|
private String dtUrlName;
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
*/
|
||||||
|
private Pattern dtUrlNameR;
|
||||||
|
/**
|
||||||
|
* 播放页面url
|
||||||
|
*/
|
||||||
|
private String playUrl;
|
||||||
|
/**
|
||||||
|
* 播放解析调用ua
|
||||||
|
*/
|
||||||
|
private String playUa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索页地址
|
||||||
|
*/
|
||||||
|
private String searchUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索页视频节点 xpath
|
||||||
|
*/
|
||||||
|
private String scVodNode;
|
||||||
|
/**
|
||||||
|
* 搜索页视频名称 xpath
|
||||||
|
*/
|
||||||
|
private String scVodName;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern scVodNameR;
|
||||||
|
/**
|
||||||
|
* 搜索页视频id xpath
|
||||||
|
*/
|
||||||
|
private String scVodId;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern scVodIdR;
|
||||||
|
/**
|
||||||
|
* 搜索页视频图片 xpath
|
||||||
|
*/
|
||||||
|
private String scVodImg;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern scVodImgR;
|
||||||
|
/**
|
||||||
|
* 搜索页视频简介 xpath
|
||||||
|
*/
|
||||||
|
private String scVodMark;
|
||||||
|
/**
|
||||||
|
* 正则对取到的数据进行二次处理
|
||||||
|
*/
|
||||||
|
private Pattern scVodMarkR;
|
||||||
|
|
||||||
|
private static Pattern getPattern(JSONObject json, String key) {
|
||||||
|
String v = json.optString(key).trim();
|
||||||
|
if (v.isEmpty())
|
||||||
|
return null;
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
return Pattern.compile(v);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||||
|
if (pattern == null)
|
||||||
|
return src;
|
||||||
|
try {
|
||||||
|
Matcher matcher = pattern.matcher(src);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).trim();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static XPathRule fromJson(String json) {
|
||||||
|
try {
|
||||||
|
JSONObject jsonObj = new JSONObject(json);
|
||||||
|
XPathRule rule = new XPathRule();
|
||||||
|
rule.ua = jsonObj.optString("ua");
|
||||||
|
rule.homeUrl = jsonObj.optString("homeUrl").trim();
|
||||||
|
rule.cateNode = jsonObj.optString("cateNode").trim();
|
||||||
|
rule.cateName = jsonObj.optString("cateName").trim();
|
||||||
|
rule.cateNameR = getPattern(jsonObj, "cateNameR");
|
||||||
|
rule.cateId = jsonObj.optString("cateId").trim();
|
||||||
|
rule.cateIdR = getPattern(jsonObj, "cateIdR");
|
||||||
|
JSONObject navs = jsonObj.optJSONObject("cateManual");
|
||||||
|
if (navs != null) {
|
||||||
|
Iterator<String> keys = navs.keys();
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
String name = keys.next();
|
||||||
|
rule.cateManual.put(name.trim(), navs.getString(name).trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rule.filter = jsonObj.optJSONObject("filter");
|
||||||
|
rule.homeVodNode = jsonObj.optString("homeVodNode").trim();
|
||||||
|
rule.homeVodName = jsonObj.optString("homeVodName").trim();
|
||||||
|
rule.homeVodNameR = getPattern(jsonObj, "homeVodNameR");
|
||||||
|
rule.homeVodId = jsonObj.optString("homeVodId").trim();
|
||||||
|
rule.homeVodIdR = getPattern(jsonObj, "homeVodIdR");
|
||||||
|
rule.homeVodImg = jsonObj.optString("homeVodImg").trim();
|
||||||
|
rule.homeVodImgR = getPattern(jsonObj, "homeVodImgR");
|
||||||
|
rule.homeVodMark = jsonObj.optString("homeVodMark").trim();
|
||||||
|
rule.homeVodMarkR = getPattern(jsonObj, "homeVodMarkR");
|
||||||
|
rule.cateUrl = jsonObj.optString("cateUrl").trim();
|
||||||
|
rule.cateVodNode = jsonObj.optString("cateVodNode").trim();
|
||||||
|
rule.cateVodName = jsonObj.optString("cateVodName").trim();
|
||||||
|
rule.cateVodNameR = getPattern(jsonObj, "cateVodNameR");
|
||||||
|
rule.cateVodId = jsonObj.optString("cateVodId").trim();
|
||||||
|
rule.cateVodIdR = getPattern(jsonObj, "cateVodIdR");
|
||||||
|
rule.cateVodImg = jsonObj.optString("cateVodImg").trim();
|
||||||
|
rule.cateVodImgR = getPattern(jsonObj, "cateVodImgR");
|
||||||
|
rule.cateVodMark = jsonObj.optString("cateVodMark").trim();
|
||||||
|
rule.cateVodMarkR = getPattern(jsonObj, "cateVodMarkR");
|
||||||
|
rule.dtUrl = jsonObj.optString("dtUrl");
|
||||||
|
rule.dtNode = jsonObj.optString("dtNode");
|
||||||
|
rule.dtName = jsonObj.optString("dtName");
|
||||||
|
rule.dtNameR = getPattern(jsonObj, "dtNameR");
|
||||||
|
rule.dtImg = jsonObj.optString("dtImg");
|
||||||
|
rule.dtImgR = getPattern(jsonObj, "dtImgR");
|
||||||
|
rule.dtCate = jsonObj.optString("dtCate");
|
||||||
|
rule.dtCateR = getPattern(jsonObj, "dtCateR");
|
||||||
|
rule.dtYear = jsonObj.optString("dtYear");
|
||||||
|
rule.dtYearR = getPattern(jsonObj, "dtYearR");
|
||||||
|
rule.dtArea = jsonObj.optString("dtArea");
|
||||||
|
rule.dtAreaR = getPattern(jsonObj, "dtAreaR");
|
||||||
|
rule.dtMark = jsonObj.optString("dtMark");
|
||||||
|
rule.dtMarkR = getPattern(jsonObj, "dtMarkR");
|
||||||
|
rule.dtActor = jsonObj.optString("dtActor");
|
||||||
|
rule.dtActorR = getPattern(jsonObj, "dtActorR");
|
||||||
|
rule.dtDirector = jsonObj.optString("dtDirector");
|
||||||
|
rule.dtDirectorR = getPattern(jsonObj, "dtDirectorR");
|
||||||
|
rule.dtDesc = jsonObj.optString("dtDesc");
|
||||||
|
rule.dtDescR = getPattern(jsonObj, "dtDescR");
|
||||||
|
rule.dtFromNode = jsonObj.optString("dtFromNode");
|
||||||
|
rule.dtFromName = jsonObj.optString("dtFromName");
|
||||||
|
rule.dtFromNameR = getPattern(jsonObj, "dtFromNameR");
|
||||||
|
rule.dtUrlNode = jsonObj.optString("dtUrlNode");
|
||||||
|
rule.dtUrlSubNode = jsonObj.optString("dtUrlSubNode");
|
||||||
|
rule.dtUrlId = jsonObj.optString("dtUrlId");
|
||||||
|
rule.dtUrlIdR = getPattern(jsonObj, "dtUrlIdR");
|
||||||
|
rule.dtUrlName = jsonObj.optString("dtUrlName");
|
||||||
|
rule.dtUrlNameR = getPattern(jsonObj, "dtUrlNameR");
|
||||||
|
rule.playUrl = jsonObj.optString("playUrl");
|
||||||
|
rule.playUa = jsonObj.optString("playUa");
|
||||||
|
rule.searchUrl = jsonObj.optString("searchUrl");
|
||||||
|
rule.scVodNode = jsonObj.optString("scVodNode").trim();
|
||||||
|
rule.scVodName = jsonObj.optString("scVodName").trim();
|
||||||
|
rule.scVodNameR = getPattern(jsonObj, "scVodNameR");
|
||||||
|
rule.scVodId = jsonObj.optString("scVodId").trim();
|
||||||
|
rule.scVodIdR = getPattern(jsonObj, "scVodIdR");
|
||||||
|
rule.scVodImg = jsonObj.optString("scVodImg").trim();
|
||||||
|
rule.scVodImgR = getPattern(jsonObj, "scVodImgR");
|
||||||
|
rule.scVodMark = jsonObj.optString("scVodMark").trim();
|
||||||
|
rule.scVodMarkR = getPattern(jsonObj, "scVodMarkR");
|
||||||
|
return rule;
|
||||||
|
} catch (Exception e) {
|
||||||
|
SpiderDebug.log(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUa() {
|
||||||
|
return ua;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeUrl() {
|
||||||
|
return homeUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateNode() {
|
||||||
|
return cateNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateName() {
|
||||||
|
return cateName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateNameR(String src) {
|
||||||
|
return doReplaceRegex(cateNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateId() {
|
||||||
|
return cateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateIdR(String src) {
|
||||||
|
return doReplaceRegex(cateIdR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedHashMap<String, String> getCateManual() {
|
||||||
|
return cateManual;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getFilter() {
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodNode() {
|
||||||
|
return homeVodNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodName() {
|
||||||
|
return homeVodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodNameR(String src) {
|
||||||
|
return doReplaceRegex(homeVodNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodId() {
|
||||||
|
return homeVodId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodIdR(String src) {
|
||||||
|
return doReplaceRegex(homeVodIdR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodImg() {
|
||||||
|
return homeVodImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodImgR(String src) {
|
||||||
|
return doReplaceRegex(homeVodImgR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodMark() {
|
||||||
|
return homeVodMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeVodMarkR(String src) {
|
||||||
|
return doReplaceRegex(homeVodMarkR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateUrl() {
|
||||||
|
return cateUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodNode() {
|
||||||
|
return cateVodNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodName() {
|
||||||
|
return cateVodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodNameR(String src) {
|
||||||
|
return doReplaceRegex(cateVodNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodId() {
|
||||||
|
return cateVodId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodIdR(String src) {
|
||||||
|
return doReplaceRegex(cateVodIdR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodImg() {
|
||||||
|
return cateVodImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodImgR(String src) {
|
||||||
|
return doReplaceRegex(cateVodImgR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodMark() {
|
||||||
|
return cateVodMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCateVodMarkR(String src) {
|
||||||
|
return doReplaceRegex(cateVodNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailUrl() {
|
||||||
|
return dtUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailNode() {
|
||||||
|
return dtNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailName() {
|
||||||
|
return dtName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailNameR(String src) {
|
||||||
|
return doReplaceRegex(dtNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailImg() {
|
||||||
|
return dtImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailImgR(String src) {
|
||||||
|
return doReplaceRegex(dtImgR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailCate() {
|
||||||
|
return dtCate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailCateR(String src) {
|
||||||
|
return doReplaceRegex(dtCateR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailYear() {
|
||||||
|
return dtYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailYearR(String src) {
|
||||||
|
return doReplaceRegex(dtYearR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailArea() {
|
||||||
|
return dtArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailAreaR(String src) {
|
||||||
|
return doReplaceRegex(dtAreaR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailMark() {
|
||||||
|
return dtMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailMarkR(String src) {
|
||||||
|
return doReplaceRegex(dtMarkR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailActor() {
|
||||||
|
return dtActor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailActorR(String src) {
|
||||||
|
return doReplaceRegex(dtActorR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailDirector() {
|
||||||
|
return dtDirector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailDirectorR(String src) {
|
||||||
|
return doReplaceRegex(dtDirectorR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailDesc() {
|
||||||
|
return dtDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailDescR(String src) {
|
||||||
|
return doReplaceRegex(dtDescR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailFromNode() {
|
||||||
|
return dtFromNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailFromName() {
|
||||||
|
return dtFromName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailFromNameR(String src) {
|
||||||
|
return doReplaceRegex(dtFromNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailUrlNode() {
|
||||||
|
return dtUrlNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailUrlSubNode() {
|
||||||
|
return dtUrlSubNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailUrlId() {
|
||||||
|
return dtUrlId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailUrlIdR(String src) {
|
||||||
|
return doReplaceRegex(dtUrlIdR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailUrlName() {
|
||||||
|
return dtUrlName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetailUrlNameR(String src) {
|
||||||
|
return doReplaceRegex(dtUrlNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlayUrl() {
|
||||||
|
return playUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlayUa() {
|
||||||
|
return playUa;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchUrl() {
|
||||||
|
return searchUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodNode() {
|
||||||
|
return scVodNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodName() {
|
||||||
|
return scVodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodNameR(String src) {
|
||||||
|
return doReplaceRegex(scVodNameR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodId() {
|
||||||
|
return scVodId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodIdR(String src) {
|
||||||
|
return doReplaceRegex(scVodIdR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodImg() {
|
||||||
|
return scVodImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodImgR(String src) {
|
||||||
|
return doReplaceRegex(scVodImgR, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodMark() {
|
||||||
|
return scVodMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchVodMarkR(String src) {
|
||||||
|
return doReplaceRegex(scVodMarkR, src);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,1326 @@
|
|||||||
|
{
|
||||||
|
"player": {
|
||||||
|
"dpp": {
|
||||||
|
"sh": "DP播放",
|
||||||
|
"pu": "https://pic.zxzjtv.com/dplayer.php?url=",
|
||||||
|
"sn": 1,
|
||||||
|
"or": 999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"1": [
|
||||||
|
{
|
||||||
|
"key": "3",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "喜剧",
|
||||||
|
"v": "喜剧"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "爱情",
|
||||||
|
"v": "爱情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "恐怖",
|
||||||
|
"v": "恐怖"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作",
|
||||||
|
"v": "动作"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻",
|
||||||
|
"v": "科幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "剧情",
|
||||||
|
"v": "剧情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "战争",
|
||||||
|
"v": "战争"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "警匪",
|
||||||
|
"v": "警匪"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "犯罪",
|
||||||
|
"v": "犯罪"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动画",
|
||||||
|
"v": "动画"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "奇幻",
|
||||||
|
"v": "奇幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "冒险",
|
||||||
|
"v": "冒险"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "恐怖",
|
||||||
|
"v": "恐怖"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "悬疑",
|
||||||
|
"v": "悬疑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "惊悚",
|
||||||
|
"v": "惊悚"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "青春",
|
||||||
|
"v": "青春"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "情色",
|
||||||
|
"v": "情色"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "1",
|
||||||
|
"name": "地区",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "大陆",
|
||||||
|
"v": "大陆"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "香港",
|
||||||
|
"v": "香港"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "台湾",
|
||||||
|
"v": "台湾"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "欧美",
|
||||||
|
"v": "欧美"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "韩国",
|
||||||
|
"v": "韩国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日本",
|
||||||
|
"v": "日本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "泰国",
|
||||||
|
"v": "泰国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "印度",
|
||||||
|
"v": "印度"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "俄罗斯",
|
||||||
|
"v": "俄罗斯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "4",
|
||||||
|
"name": "语言",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "英语",
|
||||||
|
"v": "英语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "韩语",
|
||||||
|
"v": "韩语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日语",
|
||||||
|
"v": "日语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "法语",
|
||||||
|
"v": "法语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "泰语",
|
||||||
|
"v": "泰语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "德语",
|
||||||
|
"v": "德语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "印度语",
|
||||||
|
"v": "印度语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "国语",
|
||||||
|
"v": "国语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "粤语",
|
||||||
|
"v": "粤语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "俄语",
|
||||||
|
"v": "俄语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "西班牙语",
|
||||||
|
"v": "西班牙语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "意大利语",
|
||||||
|
"v": "意大利语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其它",
|
||||||
|
"v": "其它"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "2",
|
||||||
|
"name": "排序",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "时间",
|
||||||
|
"v": "time"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "人气",
|
||||||
|
"v": "hits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "评分",
|
||||||
|
"v": "score"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
{
|
||||||
|
"key": "3",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "剧情",
|
||||||
|
"v": "剧情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "喜剧",
|
||||||
|
"v": "喜剧"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "爱情",
|
||||||
|
"v": "爱情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作",
|
||||||
|
"v": "动作"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "悬疑",
|
||||||
|
"v": "悬疑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "恐怖",
|
||||||
|
"v": "恐怖"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "奇幻",
|
||||||
|
"v": "奇幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "惊悚",
|
||||||
|
"v": "惊悚"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "犯罪",
|
||||||
|
"v": "犯罪"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻",
|
||||||
|
"v": "科幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "音乐",
|
||||||
|
"v": "音乐"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "4",
|
||||||
|
"name": "语言",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "英语",
|
||||||
|
"v": "英语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "法语",
|
||||||
|
"v": "法语"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "2",
|
||||||
|
"name": "排序",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "时间",
|
||||||
|
"v": "time"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "人气",
|
||||||
|
"v": "hits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "评分",
|
||||||
|
"v": "score"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
{
|
||||||
|
"key": "3",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "剧情",
|
||||||
|
"v": "剧情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "喜剧",
|
||||||
|
"v": "喜剧"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "爱情",
|
||||||
|
"v": "爱情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作",
|
||||||
|
"v": "动作"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "悬疑",
|
||||||
|
"v": "悬疑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "恐怖",
|
||||||
|
"v": "恐怖"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "奇幻",
|
||||||
|
"v": "奇幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "惊悚",
|
||||||
|
"v": "惊悚"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "犯罪",
|
||||||
|
"v": "犯罪"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻",
|
||||||
|
"v": "科幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "音乐",
|
||||||
|
"v": "音乐"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "2",
|
||||||
|
"name": "排序",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "时间",
|
||||||
|
"v": "time"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "人气",
|
||||||
|
"v": "hits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "评分",
|
||||||
|
"v": "score"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
{
|
||||||
|
"key": "3",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "剧情",
|
||||||
|
"v": "剧情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "喜剧",
|
||||||
|
"v": "喜剧"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "爱情",
|
||||||
|
"v": "爱情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作",
|
||||||
|
"v": "动作"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "悬疑",
|
||||||
|
"v": "悬疑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "恐怖",
|
||||||
|
"v": "恐怖"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "奇幻",
|
||||||
|
"v": "奇幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "惊悚",
|
||||||
|
"v": "惊悚"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "犯罪",
|
||||||
|
"v": "犯罪"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻",
|
||||||
|
"v": "科幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "音乐",
|
||||||
|
"v": "音乐"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "2",
|
||||||
|
"name": "排序",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "时间",
|
||||||
|
"v": "time"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "人气",
|
||||||
|
"v": "hits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "评分",
|
||||||
|
"v": "score"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6": [
|
||||||
|
{
|
||||||
|
"key": "3",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "情感",
|
||||||
|
"v": "情感"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻",
|
||||||
|
"v": "科幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "热血",
|
||||||
|
"v": "热血"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "推理",
|
||||||
|
"v": "推理"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "搞笑",
|
||||||
|
"v": "搞笑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "冒险",
|
||||||
|
"v": "冒险"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "萝莉",
|
||||||
|
"v": "萝莉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "校园",
|
||||||
|
"v": "校园"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作",
|
||||||
|
"v": "动作"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "机战",
|
||||||
|
"v": "机战"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "运动",
|
||||||
|
"v": "运动"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "战争",
|
||||||
|
"v": "战争"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "少年",
|
||||||
|
"v": "少年"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "少女",
|
||||||
|
"v": "少女"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "社会",
|
||||||
|
"v": "社会"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "原创",
|
||||||
|
"v": "原创"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "亲子",
|
||||||
|
"v": "亲子"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "益智",
|
||||||
|
"v": "益智"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "励志",
|
||||||
|
"v": "励志"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "1",
|
||||||
|
"name": "地区",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "国产",
|
||||||
|
"v": "国产"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日本",
|
||||||
|
"v": "日本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "欧美",
|
||||||
|
"v": "欧美"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "4",
|
||||||
|
"name": "语言",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "国语",
|
||||||
|
"v": "国语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日语",
|
||||||
|
"v": "日语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "英语",
|
||||||
|
"v": "英语"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "2",
|
||||||
|
"name": "排序",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "时间",
|
||||||
|
"v": "time"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "人气",
|
||||||
|
"v": "hits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "评分",
|
||||||
|
"v": "score"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5": [
|
||||||
|
{
|
||||||
|
"key": "3",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "剧情",
|
||||||
|
"v": "剧情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "喜剧",
|
||||||
|
"v": "喜剧"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "爱情",
|
||||||
|
"v": "爱情"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作",
|
||||||
|
"v": "动作"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "悬疑",
|
||||||
|
"v": "悬疑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "恐怖",
|
||||||
|
"v": "恐怖"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "奇幻",
|
||||||
|
"v": "奇幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "惊悚",
|
||||||
|
"v": "惊悚"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "犯罪",
|
||||||
|
"v": "犯罪"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻",
|
||||||
|
"v": "科幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "音乐",
|
||||||
|
"v": "音乐"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "2",
|
||||||
|
"name": "排序",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "时间",
|
||||||
|
"v": "time"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "人气",
|
||||||
|
"v": "hits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "评分",
|
||||||
|
"v": "score"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,791 @@
|
|||||||
|
{
|
||||||
|
"siteUrl": "https://www.smdyy.cc",
|
||||||
|
"regexCategory": "/list/(\\d+).html",
|
||||||
|
"regexVid": "/kan/(\\d+).html",
|
||||||
|
"regexPlay": "/play/(\\d+)-(\\d+)-(\\d+).html",
|
||||||
|
"regexPage": "/show/(\\S+).html",
|
||||||
|
"player": {
|
||||||
|
"duoduozy": {
|
||||||
|
"show": "高清线路",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"sohu": {
|
||||||
|
"show": "优选7",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"qq": {
|
||||||
|
"show": "优选3",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"bilibili": {
|
||||||
|
"show": "bilibili",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"youku": {
|
||||||
|
"show": "优选1",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"qiyi": {
|
||||||
|
"show": "优选2",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"letv": {
|
||||||
|
"show": "优选6",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"xigua": {
|
||||||
|
"show": "西瓜视频",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"mgtv": {
|
||||||
|
"show": "优选4",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"tkm3u8": {
|
||||||
|
"show": "备用",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
},
|
||||||
|
"pptv": {
|
||||||
|
"show": "优选5",
|
||||||
|
"or": 999,
|
||||||
|
"ps": "0",
|
||||||
|
"parse": "https://player.6080kan.cc/player/play.php?url="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"1": [
|
||||||
|
{
|
||||||
|
"key": "tid",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作片",
|
||||||
|
"v": "6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "喜剧片",
|
||||||
|
"v": "7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "爱情片",
|
||||||
|
"v": "8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻片",
|
||||||
|
"v": "9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "恐怖片",
|
||||||
|
"v": "10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "剧情片",
|
||||||
|
"v": "11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "战争片",
|
||||||
|
"v": "12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "犯罪片",
|
||||||
|
"v": "20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "惊悚片",
|
||||||
|
"v": "21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "冒险片",
|
||||||
|
"v": "22"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "悬疑片",
|
||||||
|
"v": "23"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "武侠片",
|
||||||
|
"v": "24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "奇幻片",
|
||||||
|
"v": "25"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "纪录片",
|
||||||
|
"v": "26"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动画片",
|
||||||
|
"v": "27"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "1",
|
||||||
|
"name": "地区",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "大陆",
|
||||||
|
"v": "大陆"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "香港",
|
||||||
|
"v": "香港"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "台湾",
|
||||||
|
"v": "台湾"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "美国",
|
||||||
|
"v": "美国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "法国",
|
||||||
|
"v": "法国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "英国",
|
||||||
|
"v": "英国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日本",
|
||||||
|
"v": "日本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "韩国",
|
||||||
|
"v": "韩国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "德国",
|
||||||
|
"v": "德国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "泰国",
|
||||||
|
"v": "泰国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "印度",
|
||||||
|
"v": "印度"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "意大利",
|
||||||
|
"v": "意大利"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "西班牙",
|
||||||
|
"v": "西班牙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "加拿大",
|
||||||
|
"v": "加拿大"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "4",
|
||||||
|
"name": "语言",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
{
|
||||||
|
"key": "tid",
|
||||||
|
"name": "类型",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "国产剧",
|
||||||
|
"v": "13"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "港台剧",
|
||||||
|
"v": "14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日韩剧",
|
||||||
|
"v": "15"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "欧美剧",
|
||||||
|
"v": "16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "泰国剧",
|
||||||
|
"v": "28"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "1",
|
||||||
|
"name": "地区",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "大陆",
|
||||||
|
"v": "大陆"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "香港",
|
||||||
|
"v": "香港"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "韩国",
|
||||||
|
"v": "韩国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "美国",
|
||||||
|
"v": "美国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日本",
|
||||||
|
"v": "日本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "法国",
|
||||||
|
"v": "法国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "英国",
|
||||||
|
"v": "英国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "德国",
|
||||||
|
"v": "德国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "台湾",
|
||||||
|
"v": "台湾"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "泰国",
|
||||||
|
"v": "泰国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "印度",
|
||||||
|
"v": "印度"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "4",
|
||||||
|
"name": "语言",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
{
|
||||||
|
"key": "3",
|
||||||
|
"name": "剧情",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "情感",
|
||||||
|
"v": "情感"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "科幻",
|
||||||
|
"v": "科幻"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "热血",
|
||||||
|
"v": "热血"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "推理",
|
||||||
|
"v": "推理"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "搞笑",
|
||||||
|
"v": "搞笑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "冒险",
|
||||||
|
"v": "冒险"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "萝莉",
|
||||||
|
"v": "萝莉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "校园",
|
||||||
|
"v": "校园"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "动作",
|
||||||
|
"v": "动作"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "机战",
|
||||||
|
"v": "机战"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "运动",
|
||||||
|
"v": "运动"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "战争",
|
||||||
|
"v": "战争"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "少年",
|
||||||
|
"v": "少年"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "少女",
|
||||||
|
"v": "少女"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "社会",
|
||||||
|
"v": "社会"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "原创",
|
||||||
|
"v": "原创"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "亲子",
|
||||||
|
"v": "亲子"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "益智",
|
||||||
|
"v": "益智"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "励志",
|
||||||
|
"v": "励志"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "1",
|
||||||
|
"name": "地区",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": " 内地",
|
||||||
|
"v": " 内地"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "韩国",
|
||||||
|
"v": "韩国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "香港",
|
||||||
|
"v": "香港"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "台湾",
|
||||||
|
"v": "台湾"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "日本",
|
||||||
|
"v": "日本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "美国",
|
||||||
|
"v": "美国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "泰国",
|
||||||
|
"v": "泰国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "英国",
|
||||||
|
"v": "英国"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "新加坡",
|
||||||
|
"v": "新加坡"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "其他",
|
||||||
|
"v": "其他"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "11",
|
||||||
|
"name": "年份",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2022",
|
||||||
|
"v": "2022"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2021",
|
||||||
|
"v": "2021"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2020",
|
||||||
|
"v": "2020"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2019",
|
||||||
|
"v": "2019"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2018",
|
||||||
|
"v": "2018"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2017",
|
||||||
|
"v": "2017"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2016",
|
||||||
|
"v": "2016"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2015",
|
||||||
|
"v": "2015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2014",
|
||||||
|
"v": "2014"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2013",
|
||||||
|
"v": "2013"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2012",
|
||||||
|
"v": "2012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2011",
|
||||||
|
"v": "2011"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2010",
|
||||||
|
"v": "2010"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2009",
|
||||||
|
"v": "2009"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2008",
|
||||||
|
"v": "2008"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2007",
|
||||||
|
"v": "2007"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2006",
|
||||||
|
"v": "2006"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2005",
|
||||||
|
"v": "2005"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2004",
|
||||||
|
"v": "2004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2003",
|
||||||
|
"v": "2003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2002",
|
||||||
|
"v": "2002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2001",
|
||||||
|
"v": "2001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "2000",
|
||||||
|
"v": "2000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "4",
|
||||||
|
"name": "语言",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"n": "全部",
|
||||||
|
"v": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">CatVodSpider</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
buildscript {
|
||||||
|
ext {
|
||||||
|
appVersionCode = 1
|
||||||
|
appVersionName = "1.0.0"
|
||||||
|
|
||||||
|
miniSdkVersion = 16
|
||||||
|
compileSdkVersion = 30
|
||||||
|
targetSdkVersion = 26
|
||||||
|
|
||||||
|
jsoup_version = "1.14.1"
|
||||||
|
jsoupxpath_version = "2.5.0"
|
||||||
|
okhttp_version = "3.12.13"
|
||||||
|
rxhttp_version = "2.6.5"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/google' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/central' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||||
|
classpath "gradle.plugin.ru.cleverpumpkin.proguard-dictionaries-generator:plugin:1.0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/google' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/central' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
call "%~dp0\gradlew" assembleRelease --no-daemon
|
||||||
|
|
||||||
|
call "%~dp0\jar\genJar.bat" ec
|
||||||
|
|
||||||
|
pause
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
|
# Android operating system, and which are packaged with your app"s APK
|
||||||
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
|
android.useAndroidX=true
|
||||||
Vendored
BIN
Binary file not shown.
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#Tue Sep 21 09:53:05 CST 2021
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
Vendored
+84
@@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+143
@@ -0,0 +1,143 @@
|
|||||||
|
## 共享包
|
||||||
|
|
||||||
|
### 这里的jar包由群友玩家共享的爬虫代码生成,不定期更新jar包和配置
|
||||||
|
|
||||||
|
### **注意:由于防火墙的问题,你可能无法直接使用这里的jar包,请自己想办法解决**
|
||||||
|
|
||||||
|
```json
|
||||||
|
|
||||||
|
"spider": "https://github.com/catvod/CatVodTVSpider/blob/master/jar/custom_spider.jar?raw=true",
|
||||||
|
|
||||||
|
国内镜像
|
||||||
|
|
||||||
|
"spider": "https://litecucumber.coding.net/p/cat/d/config/git/raw/master/custom_spider.txt",
|
||||||
|
|
||||||
|
......
|
||||||
|
"sites": [
|
||||||
|
......
|
||||||
|
{
|
||||||
|
"key": "csp_Aidi",
|
||||||
|
"name": "爱迪",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Aidi",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Enlienli",
|
||||||
|
"name": "嗯哩嗯哩",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Enlienli",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Auete",
|
||||||
|
"name": "Auete",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Auete",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Cokemv",
|
||||||
|
"name": "Cokemv",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Cokemv",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Buka",
|
||||||
|
"name": "真不卡(测试)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Buka",
|
||||||
|
"searchable": 0,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Ysgc",
|
||||||
|
"name": "影视工厂",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Ysgc",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_N0ys",
|
||||||
|
"name": "90影视",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_N0ys",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 1,
|
||||||
|
"filterable": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Nekk",
|
||||||
|
"name": "9E看看",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Nekk",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Imaple",
|
||||||
|
"name": "枫林网(爬虫)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Imaple",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Jumi",
|
||||||
|
"name": "剧迷(爬虫)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Jumi",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_Nfx",
|
||||||
|
"name": "NFXHD(爬虫)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_Nfx",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "csp_YydsAli1",
|
||||||
|
"name": "YYDS阿里(爬虫)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_YydsAli1",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 0
|
||||||
|
}
|
||||||
|
......
|
||||||
|
],
|
||||||
|
......
|
||||||
|
"parses": [
|
||||||
|
......
|
||||||
|
{
|
||||||
|
"name": "Json并发",
|
||||||
|
"type": 2,
|
||||||
|
"url": "Parallel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Json轮询",
|
||||||
|
"type": 2,
|
||||||
|
"url": "Sequence"
|
||||||
|
}
|
||||||
|
......
|
||||||
|
]
|
||||||
|
```
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
d63fe3db21b48e04884c2d5303907bd1
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
del "%~dp0\custom_spider.jar"
|
||||||
|
|
||||||
|
rd /s/q "%~dp0\Smali_classes"
|
||||||
|
|
||||||
|
java -jar "%~dp0\3rd\baksmali-2.5.2.jar" d "%~dp0\..\app\build\intermediates\dex\release\minifyReleaseWithR8\classes.dex" -o "%~dp0\Smali_classes"
|
||||||
|
|
||||||
|
rd /s/q "%~dp0\spider.jar\smali\com\github\catvod\spider"
|
||||||
|
rd /s/q "%~dp0\spider.jar\smali\com\github\catvod\parser"
|
||||||
|
|
||||||
|
if not exist "%~dp0\spider.jar\smali\com\github\catvod\" md "%~dp0\spider.jar\smali\com\github\catvod\"
|
||||||
|
|
||||||
|
if "%1" == "ec" (
|
||||||
|
java -Dfile.encoding=utf-8 -jar "%~dp0\3rd\oss.jar" "%~dp0\Smali_classes"
|
||||||
|
)
|
||||||
|
|
||||||
|
move "%~dp0\Smali_classes\com\github\catvod\spider" "%~dp0\spider.jar\smali\com\github\catvod\"
|
||||||
|
move "%~dp0\Smali_classes\com\github\catvod\parser" "%~dp0\spider.jar\smali\com\github\catvod\"
|
||||||
|
|
||||||
|
rd /s/q "%~dp0\Smali_classes"
|
||||||
|
|
||||||
|
java -jar "%~dp0\3rd\apktool_2.4.1.jar" b "%~dp0\spider.jar" -c
|
||||||
|
|
||||||
|
move "%~dp0\spider.jar\dist\dex.jar" "%~dp0\custom_spider.jar"
|
||||||
|
|
||||||
|
certUtil -hashfile "%~dp0\custom_spider.jar" MD5 | find /i /v "md5" | find /i /v "certutil" > "%~dp0\custom_spider.jar.md5"
|
||||||
|
|
||||||
|
rd /s/q "%~dp0\spider.jar\smali\com\github\catvod\spider"
|
||||||
|
rd /s/q "%~dp0\spider.jar\smali\com\github\catvod\parser"
|
||||||
|
|
||||||
|
rd /s/q "%~dp0\spider.jar\build"
|
||||||
|
rd /s/q "%~dp0\spider.jar\dist"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
!!brut.androlib.meta.MetaInfo
|
||||||
|
apkFileName: dex.jar
|
||||||
|
compressionType: false
|
||||||
|
doNotCompress: null
|
||||||
|
isFrameworkApk: false
|
||||||
|
packageInfo: null
|
||||||
|
sdkInfo: null
|
||||||
|
sharedLibrary: false
|
||||||
|
sparseResources: false
|
||||||
|
unknownFiles:
|
||||||
|
usesFramework: null
|
||||||
|
version: 2.4.1_0303
|
||||||
|
versionInfo: null
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Dex-Location: classes.dex
|
||||||
|
Created-By: dx 1.11
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
rootProject.name = "CatVodSpider"
|
||||||
|
include ':app'
|
||||||
Reference in New Issue
Block a user