mirror of
https://github.com/Evil0ctal/Douyin_TikTok_Download_API.git
synced 2025-04-22 12:05:13 +08:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
3172d73310
31
README.en.md
31
README.en.md
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
[English](./README.en.md)\|[Simplified Chinese](./README.md)
|
[English](./README.en.md)\|[Simplified Chinese](./README.md)
|
||||||
|
|
||||||
🚀"Douyin_TikTok_Download_API" is a high-performance asynchronous API that can be used out of the box[Tik Tok](https://www.douyin.com)\|[TikTok](https://www.tiktok.com)Data crawling tool supports API calling, online batch analysis and downloading.
|
🚀"Douyin_TikTok_Download_API" is a high-performance asynchronous API that can be used out of the box[Tik Tok](https://www.douyin.com)\|[TikTok](https://www.tiktok.com)\|[Bilibili](https://www.bilibili.com)Data crawling tool supports API calling, online batch analysis and downloading.
|
||||||
|
|
||||||
[](LICENSE)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/releases/latest)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/stargazers)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/network/members)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues?q=is%3Aissue+is%3Aclosed)<br>[](https://pypi.org/project/douyin-tiktok-scraper/)[](https://pypi.org/project/douyin-tiktok-scraper/#files)[](https://pypi.org/project/douyin-tiktok-scraper/)[](https://pypi.org/project/douyin-tiktok-scraper/)<br>[](https://api.douyin.wtf/docs)[](https://api.tikhub.io/docs)<br>[](https://afdian.net/@evil0ctal)[](https://ko-fi.com/evil0ctal)[](https://www.patreon.com/evil0ctal)
|
[](LICENSE)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/releases/latest)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/stargazers)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/network/members)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues)[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues?q=is%3Aissue+is%3Aclosed)<br>[](https://pypi.org/project/douyin-tiktok-scraper/)[](https://pypi.org/project/douyin-tiktok-scraper/#files)[](https://pypi.org/project/douyin-tiktok-scraper/)[](https://pypi.org/project/douyin-tiktok-scraper/)<br>[](https://api.douyin.wtf/docs)[](https://api.tikhub.io/docs)<br>[](https://afdian.net/@evil0ctal)[](https://ko-fi.com/evil0ctal)[](https://www.patreon.com/evil0ctal)
|
||||||
|
|
||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
> 🚨If you need to use a private server to run this project, please refer to the deployment method\[[Docker deployment](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%BA%8C-docker),[One-click deployment](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%B8%80-linux)]
|
> 🚨If you need to use a private server to run this project, please refer to the deployment method\[[Docker deployment](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%BA%8C-docker),[One-click deployment](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%B8%80-linux)]
|
||||||
|
|
||||||
This project is based on[PyWebIO](https://github.com/pywebio/PyWebIO),[FastAPI](https://fastapi.tiangolo.com/),[AIOHTTP](https://docs.aiohttp.org/), fast and asynchronous[Tik Tok](https://www.douyin.com/)/[TikTok](https://www.tiktok.com/)Data crawling tool, and realizes online batch parsing and downloading of videos or photo albums without watermarks, data crawling API, iOS shortcut commands without watermark downloading through the Web, etc. You can deploy or modify this project yourself to achieve more functions, or you can call it directly in your project[scraper.py](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/blob/Stable/scraper.py)or install an existing[pip package](https://pypi.org/project/douyin-tiktok-scraper/)As a parsing library, it is easy to crawl data, etc.....
|
This project is based on[PyWebIO](https://github.com/pywebio/PyWebIO),[FastAPI](https://fastapi.tiangolo.com/),[AIOHTTP](https://docs.aiohttp.org/), fast and asynchronous[Tik Tok](https://www.douyin.com/)/[TikTok](https://www.tiktok.com/)/[Bilibili](https://www.bilibili.com)Data crawling tool, and realizes online batch parsing and downloading of videos or photo albums without watermarks, data crawling API, and iOS shortcut commands without watermark downloads through the Web. You can deploy or modify this project yourself to achieve more functions, or you can call it directly in your project[scraper.py](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/blob/Stable/scraper.py)or install an existing[pip package](https://pypi.org/project/douyin-tiktok-scraper/)As a parsing library, it is easy to crawl data, etc.....
|
||||||
|
|
||||||
_Some simple application scenarios:_
|
_Some simple application scenarios:_
|
||||||
|
|
||||||
@ -62,9 +62,9 @@ _Download prohibited videos, perform data analysis, download without watermark o
|
|||||||
|
|
||||||
> **_web_app.py:_**
|
> **_web_app.py:_**
|
||||||
|
|
||||||
- for`web_api.py`as well as`scraper.py`A simple web program created to process the values entered on the web page and use them`Scraper()`Class processing and cooperation`web_api.py`The interface is output on the web page (similar to front-end and back-end separation)
|
- for`web_api.py`as well as`scraper.py`A simple web program created to process the values entered on the web page and use them`Scraper()`Class processing and cooperation`web_api.py`The interface output is on the web page (similar to front-end and back-end separation)
|
||||||
|
|
||||||
**_Most of the parameters of the above files can be found in[config.ini](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/blob/main/config.ini)Modify in_**
|
**_Most of the parameters of the above files can be found in[config.ini](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/blob/main/config.ini)Make changes in_**
|
||||||
|
|
||||||
## 💡Project file structure
|
## 💡Project file structure
|
||||||
|
|
||||||
@ -80,6 +80,8 @@ _Download prohibited videos, perform data analysis, download without watermark o
|
|||||||
## ✨Features:
|
## ✨Features:
|
||||||
|
|
||||||
- Douyin (overseas version of Douyin: TikTok) video/picture analysis
|
- Douyin (overseas version of Douyin: TikTok) video/picture analysis
|
||||||
|
- Bilibili video analysis
|
||||||
|
- Watermelon video analysis
|
||||||
- Batch analysis on the web page (supports Douyin/TikTok mixed submission)
|
- Batch analysis on the web page (supports Douyin/TikTok mixed submission)
|
||||||
- Batch download of non-watermarked videos from the web parsing result page (removed for V3.X and above versions, please deploy V2.X version by yourself)
|
- Batch download of non-watermarked videos from the web parsing result page (removed for V3.X and above versions, please deploy V2.X version by yourself)
|
||||||
- API call to get link data
|
- API call to get link data
|
||||||
@ -102,7 +104,7 @@ _Download prohibited videos, perform data analysis, download without watermark o
|
|||||||
|
|
||||||
## 📦Call the parsing library:
|
## 📦Call the parsing library:
|
||||||
|
|
||||||
> 💡PyPi:<https://pypi.org/project/douyin-tiktok-scraper/>
|
> 💡PyPi:<https://pypi.org/project/douyin-tiktok-scraper/>
|
||||||
|
|
||||||
Install the parsing library:`pip install douyin-tiktok-scraper`
|
Install the parsing library:`pip install douyin-tiktok-scraper`
|
||||||
|
|
||||||
@ -118,13 +120,26 @@ async def hybrid_parsing(url: str) -> dict:
|
|||||||
print(f"The hybrid parsing result:\n {result}")
|
print(f"The hybrid parsing result:\n {result}")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
asyncio.run(hybrid_parsing(url=input("Paste Douyin/TikTok share URL here: ")))
|
asyncio.run(hybrid_parsing(url=input("Paste Douyin/TikTok/Bilibili share URL here: ")))
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🗺️Supported submission formats:
|
## 🗺️Supported submission formats:
|
||||||
|
|
||||||
> 💡Tip: Including but not limited to the following examples, if you encounter link parsing failure, please open a new one[issue](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues)
|
> 💡Tip: Including but not limited to the following examples, if you encounter link parsing failure, please open a new one[issue](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues)
|
||||||
|
|
||||||
|
- Watermelon video link
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://www.ixigua.com/7270448082586698281/
|
||||||
|
https://m.ixigua.com/video/7274710134306112054/
|
||||||
|
```
|
||||||
|
|
||||||
|
- Bilibili video link
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://www.bilibili.com/video/BV1Th411x7ii/
|
||||||
|
```
|
||||||
|
|
||||||
- Douyin sharing password (copy in APP)
|
- Douyin sharing password (copy in APP)
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@ -210,7 +225,7 @@ Online:<https://api.tikhub.io/docs>
|
|||||||
|
|
||||||
## 💻Deployment (Method 1 Linux)
|
## 💻Deployment (Method 1 Linux)
|
||||||
|
|
||||||
> 💡Tip: It is best to deploy this project to a server in the United States, otherwise strange BUGs may occur.
|
> 💡Tips: It is best to deploy this project to a server in the United States, otherwise strange BUGs may occur.
|
||||||
|
|
||||||
Recommended for everyone to use[Digitalocean](https://www.digitalocean.com/)servers, mainly because they are free.
|
Recommended for everyone to use[Digitalocean](https://www.digitalocean.com/)servers, mainly because they are free.
|
||||||
|
|
||||||
@ -310,7 +325,7 @@ docker rm -f douyin_tiktok_download_api
|
|||||||
docker-compose pull && docker-compose down && docker-compose up -d
|
docker-compose pull && docker-compose down && docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
## ❤️Contributor
|
## ❤️ Contributor
|
||||||
|
|
||||||
[](https://github.com/Evil0ctal)[](https://github.com/jw-star)[](https://github.com/Jeffrey-deng)[](https://github.com/chris-ss)[](https://github.com/weixuan00)[](https://github.com/Tairraos)
|
[](https://github.com/Evil0ctal)[](https://github.com/jw-star)[](https://github.com/Jeffrey-deng)[](https://github.com/chris-ss)[](https://github.com/weixuan00)[](https://github.com/Tairraos)
|
||||||
|
|
||||||
|
21
README.md
21
README.md
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
[English](./README.en.md) | [简体中文](./README.md)
|
[English](./README.en.md) | [简体中文](./README.md)
|
||||||
|
|
||||||
🚀「Douyin_TikTok_Download_API」是一个开箱即用的高性能异步[抖音](https://www.douyin.com)|[TikTok](https://www.tiktok.com)数据爬取工具,支持API调用,在线批量解析及下载。
|
🚀「Douyin_TikTok_Download_API」是一个开箱即用的高性能异步[抖音](https://www.douyin.com)|[TikTok](https://www.tiktok.com)|[Bilibili](https://www.bilibili.com)数据爬取工具,支持API调用,在线批量解析及下载。
|
||||||
|
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/releases/latest)
|
[](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/releases/latest)
|
||||||
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
> 🚨如需使用私有服务器运行本项目,请参考部署方式[[Docker部署](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%BA%8C-docker), [一键部署](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%B8%80-linux)]
|
> 🚨如需使用私有服务器运行本项目,请参考部署方式[[Docker部署](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%BA%8C-docker), [一键部署](./README.md#%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F%E4%B8%80-linux)]
|
||||||
|
|
||||||
本项目是基于 [PyWebIO](https://github.com/pywebio/PyWebIO),[FastAPI](https://fastapi.tiangolo.com/),[AIOHTTP](https://docs.aiohttp.org/),快速异步的[抖音](https://www.douyin.com/)/[TikTok](https://www.tiktok.com/)数据爬取工具,并通过Web端实现在线批量解析以及下载无水印视频或图集,数据爬取API,iOS快捷指令无水印下载等功能。你可以自己部署或改造本项目实现更多功能,也可以在你的项目中直接调用[scraper.py](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/blob/Stable/scraper.py)或安装现有的[pip包](https://pypi.org/project/douyin-tiktok-scraper/)作为解析库轻松爬取数据等.....
|
本项目是基于 [PyWebIO](https://github.com/pywebio/PyWebIO),[FastAPI](https://fastapi.tiangolo.com/),[AIOHTTP](https://docs.aiohttp.org/),快速异步的[抖音](https://www.douyin.com/)/[TikTok](https://www.tiktok.com/)/[Bilibili](https://www.bilibili.com)数据爬取工具,并通过Web端实现在线批量解析以及下载无水印视频或图集,数据爬取API,iOS快捷指令无水印下载等功能。你可以自己部署或改造本项目实现更多功能,也可以在你的项目中直接调用[scraper.py](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/blob/Stable/scraper.py)或安装现有的[pip包](https://pypi.org/project/douyin-tiktok-scraper/)作为解析库轻松爬取数据等.....
|
||||||
|
|
||||||
*一些简单的运用场景:*
|
*一些简单的运用场景:*
|
||||||
|
|
||||||
@ -101,6 +101,8 @@
|
|||||||
## ✨功能:
|
## ✨功能:
|
||||||
|
|
||||||
- 抖音(抖音海外版: TikTok)视频/图片解析
|
- 抖音(抖音海外版: TikTok)视频/图片解析
|
||||||
|
- Bilibili视频解析
|
||||||
|
- 西瓜视频解析
|
||||||
- 网页端批量解析(支持抖音/TikTok混合提交)
|
- 网页端批量解析(支持抖音/TikTok混合提交)
|
||||||
- 网页端解析结果页批量下载无水印视频(V3.X以上版本移除,请自行部署V2.X版本)
|
- 网页端解析结果页批量下载无水印视频(V3.X以上版本移除,请自行部署V2.X版本)
|
||||||
- API调用获取链接数据
|
- API调用获取链接数据
|
||||||
@ -139,13 +141,26 @@ async def hybrid_parsing(url: str) -> dict:
|
|||||||
print(f"The hybrid parsing result:\n {result}")
|
print(f"The hybrid parsing result:\n {result}")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
asyncio.run(hybrid_parsing(url=input("Paste Douyin/TikTok share URL here: ")))
|
asyncio.run(hybrid_parsing(url=input("Paste Douyin/TikTok/Bilibili share URL here: ")))
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🗺️支持的提交格式:
|
## 🗺️支持的提交格式:
|
||||||
|
|
||||||
> 💡提示:包含但不仅限于以下例子,如果遇到链接解析失败请开启一个新 [issue](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues)
|
> 💡提示:包含但不仅限于以下例子,如果遇到链接解析失败请开启一个新 [issue](https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues)
|
||||||
|
|
||||||
|
- 西瓜视频链接
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://www.ixigua.com/7270448082586698281/
|
||||||
|
https://m.ixigua.com/video/7274710134306112054/
|
||||||
|
```
|
||||||
|
|
||||||
|
- Bilibili视频链接
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://www.bilibili.com/video/BV1Th411x7ii/
|
||||||
|
```
|
||||||
|
|
||||||
- 抖音分享口令 (APP内复制)
|
- 抖音分享口令 (APP内复制)
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
146
scraper.py
146
scraper.py
@ -10,7 +10,7 @@
|
|||||||
# If this project is helpful to you, please give me a star, thank you!
|
# If this project is helpful to you, please give me a star, thank you!
|
||||||
# @备注:
|
# @备注:
|
||||||
# 核心代码,估值1块(๑•̀ㅂ•́)و✧
|
# 核心代码,估值1块(๑•̀ㅂ•́)و✧
|
||||||
# 用于爬取Douyin/TikTok/Bilibili的数据并以字典形式返回。
|
# 用于爬取Douyin/TikTok/Bilibili/xigua的数据并以字典形式返回。
|
||||||
# 如果本项目对您有帮助,请给我一个star,谢谢!
|
# 如果本项目对您有帮助,请给我一个star,谢谢!
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
@ -24,7 +24,9 @@ import asyncio
|
|||||||
import traceback
|
import traceback
|
||||||
import configparser
|
import configparser
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
import random
|
||||||
|
|
||||||
|
from zlib import crc32
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from tenacity import *
|
from tenacity import *
|
||||||
|
|
||||||
@ -49,6 +51,22 @@ class Scraper:
|
|||||||
self.bilibili_api_headers = {
|
self.bilibili_api_headers = {
|
||||||
'User-Agent': 'com.ss.android.ugc.trill/494+Mozilla/5.0+(Linux;+Android+12;+2112123G+Build/SKQ1.211006.001;+wv)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Version/4.0+Chrome/107.0.5304.105+Mobile+Safari/537.36'
|
'User-Agent': 'com.ss.android.ugc.trill/494+Mozilla/5.0+(Linux;+Android+12;+2112123G+Build/SKQ1.211006.001;+wv)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Version/4.0+Chrome/107.0.5304.105+Mobile+Safari/537.36'
|
||||||
}
|
}
|
||||||
|
self.ixigua_api_headers = {
|
||||||
|
'authority': 'ib.365yg.com',
|
||||||
|
'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.7',
|
||||||
|
'accept-language': 'zh-CN,zh;q=0.9',
|
||||||
|
'cache-control': 'no-cache',
|
||||||
|
'pragma': 'no-cache',
|
||||||
|
'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'document',
|
||||||
|
'sec-fetch-mode': 'navigate',
|
||||||
|
'sec-fetch-site': 'none',
|
||||||
|
'sec-fetch-user': '?1',
|
||||||
|
'upgrade-insecure-requests': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
|
||||||
|
}
|
||||||
# 判断配置文件是否存在/Check if the configuration file exists
|
# 判断配置文件是否存在/Check if the configuration file exists
|
||||||
if os.path.exists('config.ini'):
|
if os.path.exists('config.ini'):
|
||||||
self.config = configparser.ConfigParser()
|
self.config = configparser.ConfigParser()
|
||||||
@ -212,6 +230,37 @@ class Scraper:
|
|||||||
else:
|
else:
|
||||||
print('该链接为原始链接,无需转换,原始链接为: {}'.format(url))
|
print('该链接为原始链接,无需转换,原始链接为: {}'.format(url))
|
||||||
return url
|
return url
|
||||||
|
elif 'ixigua.com' in url:
|
||||||
|
"""
|
||||||
|
西瓜视频链接类型(不全):
|
||||||
|
1. https://v.ixigua.com/ienrQ5bR/
|
||||||
|
2. https://www.ixigua.com/7270448082586698281
|
||||||
|
3. https://m.ixigua.com/video/7270448082586698281
|
||||||
|
西瓜用户链接类型(不全):
|
||||||
|
1. https://www.ixigua.com/home/3189050062678823
|
||||||
|
西瓜直播链接类型(不全):
|
||||||
|
"""
|
||||||
|
if 'v.ixigua.com' in url:
|
||||||
|
print('正在通过西瓜分享链接获取原始链接...')
|
||||||
|
try:
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(url, headers=self.ixigua_api_headers, proxy=self.proxies, allow_redirects=False,
|
||||||
|
timeout=10) as response:
|
||||||
|
print("asdfasdf",response.headers)
|
||||||
|
if response.status == 302:
|
||||||
|
url = response.headers['Location'].split('?')[0] if '?' in response.headers[
|
||||||
|
'Location'] else \
|
||||||
|
response.headers['Location']
|
||||||
|
print('获取原始链接成功, 原始链接为: {}'.format(url))
|
||||||
|
return url
|
||||||
|
except Exception as e:
|
||||||
|
print('获取原始链接失败!')
|
||||||
|
print(e)
|
||||||
|
# return None
|
||||||
|
raise e
|
||||||
|
else:
|
||||||
|
print('该链接为原始链接,无需转换,原始链接为: {}'.format(url))
|
||||||
|
return url
|
||||||
|
|
||||||
"""__________________________________________⬇️Douyin methods(抖音方法)⬇️______________________________________"""
|
"""__________________________________________⬇️Douyin methods(抖音方法)⬇️______________________________________"""
|
||||||
|
|
||||||
@ -367,7 +416,7 @@ class Scraper:
|
|||||||
|
|
||||||
"""__________________________________________⬇️bilibili methods(Bilibili方法)⬇️______________________________________"""
|
"""__________________________________________⬇️bilibili methods(Bilibili方法)⬇️______________________________________"""
|
||||||
|
|
||||||
# 获取TikTok视频ID/Get TikTok video ID
|
# 获取bilibili视频ID/Get BiliBili video ID
|
||||||
async def get_bilibili_video_id(self, original_url: str) -> Union[str, None]:
|
async def get_bilibili_video_id(self, original_url: str) -> Union[str, None]:
|
||||||
"""
|
"""
|
||||||
获取视频id
|
获取视频id
|
||||||
@ -429,6 +478,73 @@ class Scraper:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError(f'获取BiliBili视频数据出错了:{e}')
|
raise ValueError(f'获取BiliBili视频数据出错了:{e}')
|
||||||
|
|
||||||
|
|
||||||
|
"""__________________________________________⬇️xigua methods(xigua方法)⬇️______________________________________"""
|
||||||
|
# 获取西瓜拿播放地址的接口
|
||||||
|
def get_xigua_json_url(self,video_id):
|
||||||
|
# 获取json文件的地址
|
||||||
|
r = str(random.random())[2:]
|
||||||
|
url_part = "/video/urls/v/1/toutiao/mp4/{}?r={}".format(video_id, r)
|
||||||
|
s = crc32(url_part.encode())
|
||||||
|
json_url = "https://ib.365yg.com{}&s={}&nobase64=true".format(url_part, s)
|
||||||
|
return json_url
|
||||||
|
# 获取西瓜视频ID/Get xigua video ID
|
||||||
|
async def get_ixigua_video_id(self, original_url: str) -> Union[str, None]:
|
||||||
|
"""
|
||||||
|
获取视频id
|
||||||
|
:param original_url: 视频链接
|
||||||
|
:return: 视频id
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 转换链接/Convert link
|
||||||
|
original_url = await self.convert_share_urls(original_url)
|
||||||
|
# 获取视频ID/Get video ID
|
||||||
|
if 'www.ixigua.com/' in original_url:
|
||||||
|
video_id = re.findall('ixigua\.com/(\d+)', original_url)[0]
|
||||||
|
elif 'm.ixigua.com/video' in original_url:
|
||||||
|
video_id = re.findall('/video/(\d+)', original_url)[0]
|
||||||
|
# 返回视频ID/Return video ID
|
||||||
|
return video_id
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f'获取西瓜视频ID出错了:{e}')
|
||||||
|
|
||||||
|
@retry(stop=stop_after_attempt(4), wait=wait_fixed(7))
|
||||||
|
async def get_ixigua_video_data(self, video_id: str) -> Union[dict, None]:
|
||||||
|
"""
|
||||||
|
获取单个视频信息
|
||||||
|
:param video_id: 视频id
|
||||||
|
:return: 视频信息
|
||||||
|
"""
|
||||||
|
print('正在获取西瓜视频数据...')
|
||||||
|
try:
|
||||||
|
# 构造访问链接/Construct the access link
|
||||||
|
video_url = f'https://m.ixigua.com/video/{video_id}?wid_try=1'
|
||||||
|
print("video_url",video_url)
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(video_url, headers=self.ixigua_api_headers, proxy=self.proxies,
|
||||||
|
timeout=10) as response:
|
||||||
|
response = await response.text()
|
||||||
|
search = re.search("\"vid\":\"([^\"]+)\",", response)
|
||||||
|
vid = search.group(1)
|
||||||
|
print('获取视频vid信息成功!')
|
||||||
|
play_url_api = self.get_xigua_json_url(vid)
|
||||||
|
print(f"正在获取视频数据API: {play_url_api}")
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(play_url_api, headers=self.ixigua_api_headers, proxy=self.proxies,
|
||||||
|
timeout=10) as response:
|
||||||
|
response = await response.json()
|
||||||
|
video_data = response.get("data",{}).get("video_list",{}).get("video_3",{}).get("main_url","")
|
||||||
|
video_data = {
|
||||||
|
'status': 'success',
|
||||||
|
'message': "更多接口请查看(More API see): https://api.tikhub.io/",
|
||||||
|
'type': 'video',
|
||||||
|
'platform': '西瓜',
|
||||||
|
'video_url': video_data,
|
||||||
|
}
|
||||||
|
return video_data
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f'获取西瓜视频数据出错了:{e}')
|
||||||
|
|
||||||
"""__________________________________________⬇️Hybrid methods(混合方法)⬇️______________________________________"""
|
"""__________________________________________⬇️Hybrid methods(混合方法)⬇️______________________________________"""
|
||||||
|
|
||||||
# 判断链接平台/Judge link platform
|
# 判断链接平台/Judge link platform
|
||||||
@ -437,6 +553,8 @@ class Scraper:
|
|||||||
url_platform = 'douyin'
|
url_platform = 'douyin'
|
||||||
elif 'bilibili' in video_url:
|
elif 'bilibili' in video_url:
|
||||||
url_platform = 'bilibili'
|
url_platform = 'bilibili'
|
||||||
|
elif 'xigua' in video_url:
|
||||||
|
url_platform = 'xigua'
|
||||||
elif 'tiktok' in video_url:
|
elif 'tiktok' in video_url:
|
||||||
url_platform = 'tiktok'
|
url_platform = 'tiktok'
|
||||||
else:
|
else:
|
||||||
@ -458,6 +576,7 @@ class Scraper:
|
|||||||
video_id = await self.get_douyin_video_id(video_url) if url_platform == 'douyin' \
|
video_id = await self.get_douyin_video_id(video_url) if url_platform == 'douyin' \
|
||||||
else await self.get_tiktok_video_id(video_url) if url_platform == 'tiktok' \
|
else await self.get_tiktok_video_id(video_url) if url_platform == 'tiktok' \
|
||||||
else await self.get_bilibili_video_id(video_url) if url_platform == 'bilibili' \
|
else await self.get_bilibili_video_id(video_url) if url_platform == 'bilibili' \
|
||||||
|
else await self.get_ixigua_video_id(video_url) if url_platform == 'xigua' \
|
||||||
else None
|
else None
|
||||||
|
|
||||||
# 如果获取不到视频ID抛出异常/If the video ID cannot be obtained, an exception is thrown
|
# 如果获取不到视频ID抛出异常/If the video ID cannot be obtained, an exception is thrown
|
||||||
@ -469,6 +588,7 @@ class Scraper:
|
|||||||
data = await self.get_douyin_video_data(video_id) if url_platform == 'douyin' \
|
data = await self.get_douyin_video_data(video_id) if url_platform == 'douyin' \
|
||||||
else await self.get_tiktok_video_data(video_id) if url_platform == 'tiktok' \
|
else await self.get_tiktok_video_data(video_id) if url_platform == 'tiktok' \
|
||||||
else await self.get_bilibili_video_data(video_id) if url_platform == 'bilibili' \
|
else await self.get_bilibili_video_data(video_id) if url_platform == 'bilibili' \
|
||||||
|
else await self.get_ixigua_video_data(video_id) if url_platform == 'xigua' \
|
||||||
else None
|
else None
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
@ -477,6 +597,10 @@ class Scraper:
|
|||||||
if url_platform == 'bilibili':
|
if url_platform == 'bilibili':
|
||||||
print("获取Bilibili视频数据成功!")
|
print("获取Bilibili视频数据成功!")
|
||||||
return data
|
return data
|
||||||
|
# 如果是西瓜平台则返回视频数据/If it is a ixigua platform, return video data
|
||||||
|
if url_platform == 'xigua':
|
||||||
|
print("获取西瓜视频数据成功!")
|
||||||
|
return data
|
||||||
|
|
||||||
# 如果是抖音/TikTok平台则继续进行数据解析/If it is a Douyin/TikTok platform, continue to parse the data
|
# 如果是抖音/TikTok平台则继续进行数据解析/If it is a Douyin/TikTok platform, continue to parse the data
|
||||||
print(f"获取**{url_platform}**视频数据成功,正在判断数据类型...")
|
print(f"获取**{url_platform}**视频数据成功,正在判断数据类型...")
|
||||||
@ -656,11 +780,19 @@ class Scraper:
|
|||||||
"""__________________________________________⬇️Test methods(测试方法)⬇️______________________________________"""
|
"""__________________________________________⬇️Test methods(测试方法)⬇️______________________________________"""
|
||||||
|
|
||||||
|
|
||||||
async def async_test(_douyin_url: str = None, _tiktok_url: str = None, _bilibili_url: str = None) -> None:
|
async def async_test(_douyin_url: str = None, _tiktok_url: str = None, _bilibili_url: str = None, _ixigua_url: str = None) -> None:
|
||||||
# 异步测试/Async test
|
# 异步测试/Async test
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
print("<异步测试/Async test>")
|
print("<异步测试/Async test>")
|
||||||
|
|
||||||
|
print('\n--------------------------------------------------')
|
||||||
|
print("正在测试异步获取西瓜视频ID方法...")
|
||||||
|
ixigua_id = await api.get_ixigua_video_id(_ixigua_url)
|
||||||
|
print(f"西瓜视频ID: {ixigua_id}")
|
||||||
|
print("正在测试异步获取西瓜视频数据方法...")
|
||||||
|
ixigua_data = await api.get_ixigua_video_data(ixigua_id)
|
||||||
|
print(f"西瓜视频数据: {str(ixigua_data)[:100]}")
|
||||||
|
|
||||||
print('\n--------------------------------------------------')
|
print('\n--------------------------------------------------')
|
||||||
print("正在测试异步获取哔哩哔哩视频ID方法...")
|
print("正在测试异步获取哔哩哔哩视频ID方法...")
|
||||||
bilibili_id = await api.get_bilibili_video_id(_bilibili_url)
|
bilibili_id = await api.get_bilibili_video_id(_bilibili_url)
|
||||||
@ -690,7 +822,8 @@ async def async_test(_douyin_url: str = None, _tiktok_url: str = None, _bilibili
|
|||||||
douyin_hybrid_data = await api.hybrid_parsing(_douyin_url)
|
douyin_hybrid_data = await api.hybrid_parsing(_douyin_url)
|
||||||
tiktok_hybrid_data = await api.hybrid_parsing(_tiktok_url)
|
tiktok_hybrid_data = await api.hybrid_parsing(_tiktok_url)
|
||||||
bilibili_hybrid_data = await api.hybrid_parsing(_bilibili_url)
|
bilibili_hybrid_data = await api.hybrid_parsing(_bilibili_url)
|
||||||
print(f"抖音、TikTok、哔哩哔哩混合解析全部成功!")
|
xigua_hybrid_data = await api.hybrid_parsing(_ixigua_url)
|
||||||
|
print(f"抖音、TikTok、哔哩哔哩、西瓜混合解析全部成功!")
|
||||||
|
|
||||||
print('\n--------------------------------------------------')
|
print('\n--------------------------------------------------')
|
||||||
# 总耗时/Total time
|
# 总耗时/Total time
|
||||||
@ -706,4 +839,7 @@ if __name__ == '__main__':
|
|||||||
douyin_url = 'https://v.douyin.com/rLyrQxA/6.66'
|
douyin_url = 'https://v.douyin.com/rLyrQxA/6.66'
|
||||||
tiktok_url = 'https://www.tiktok.com/@evil0ctal/video/7217027383390555438'
|
tiktok_url = 'https://www.tiktok.com/@evil0ctal/video/7217027383390555438'
|
||||||
bilibili_url = "https://www.bilibili.com/video/BV1Th411x7ii/"
|
bilibili_url = "https://www.bilibili.com/video/BV1Th411x7ii/"
|
||||||
asyncio.run(async_test(_douyin_url=douyin_url, _tiktok_url=tiktok_url, _bilibili_url=bilibili_url))
|
ixigua_url = "https://www.ixigua.com/7270448082586698281"
|
||||||
|
# ixigua_url = "ttps://v.ixigua.com/ienrQ5bR/" # convert_share_urls 这里有bug 如果抖音的口令解析的出来其他的都是none
|
||||||
|
asyncio.run(async_test(_douyin_url=douyin_url, _tiktok_url=tiktok_url, _bilibili_url=bilibili_url, _ixigua_url=ixigua_url))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user