parse-video-py turns a share link into a direct video URL for 25 platforms
Python短视频去水印爬虫:抖音,皮皮虾,火山,微视,最右,快手,全民小视频,皮皮搞笑,西瓜视频,虎牙,梨视频,acfun,好看视频...
At a glance
- What is it?
- parse-video-py is a Python service that resolves a short share link from a Chinese short video platform into the underlying media URLs, with a FastAPI web interface, a Typer CLI, Docker packaging and an MCP endpoint. Its platform list is the substance of the project, since each platform needs its own parser and the list changes whenever a platform changes its sharing flow.
- Who is it for?
- Adopt parse-video-py if you need to resolve share links from Chinese short video platforms into direct media URLs, either from the CLI, the HTTP API or through an MCP client, since it ships all three interfaces over one parser set. Skip it if you need a stable production dependency, because the version is 0.0.3, the parsers are tied to platform behaviour that changes without notice, and the platform count is the project's real surface area.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 65 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The interface list is longer than the feature list
parse-video-py is a Python service for short video parsing and watermark removal, supporting 20 or more platforms, and it presents itself through four interfaces over the same core.
The CLI is the simplest. The console script is `parse-video-py`, mapped to `parse_video_py.cli:app`, and the commands cover parsing a link, starting a web service, and printing the version:
# 解析视频
parse-video-py parse "https://v.douyin.com/xxx"
parse-video-py parse "https://v.douyin.com/xxx" --format json
# 启动 Web 服务
parse-video-py serve --port 8000
# 查看版本
parse-video-py versionThe web service is the second, and the default local setup is a virtual environment with the web extra installed:
# 创建虚拟环境并安装全部依赖
uv venv && uv pip install -e ".[all]"
# 激活虚拟环境
source .venv/bin/activateThe third interface is the HTTP API, which is the one an automated workflow would use:
curl 'http://127.0.0.1:8000/video/share/url/parse?url=视频分享链接' | jqAnd the fourth is MCP, the Model Context Protocol, which the project now supports through a StreamableHttp transport at http://localhost:8000/mcp. That is a recent addition and it is the interface that makes the parser reachable from an AI agent, which is why it appears in the documentation at all.
So the same resolution logic is reachable from a terminal, from a web page, from an HTTP call and from an MCP client. The interfaces are thin; the parsers are the work.
Twenty-five platforms is the real feature list
The platform tables are the substance of the project, and they are worth reading closely because each entry is a parser that has to keep working.
The video table covers Xiaohongshu, Pipixia, Douyin, Huoshan, Pipigaoxiao, Kuaishou, Weishi, Xigua Video, Zuorui, Li Video, the former Quanmin now Duxiaoshi, Doupai, Weibo, Lvzhou, Quanmin K Ge, 6jianfang, Meipai, Xinpianchang, Haokan Video, Huya, AcFun, CCTV, Sohu Video, Bilibili, Tencent Video and Twitter/X.
The image gallery support is narrower, with Douyin, Kuaishou, Xiaohongshu, Pipixia and Weibo. The LivePhoto support, which is the animated image format, covers Xiaohongshu and Douyin.
That asymmetry is instructive. Video parsing is the mature path, and gallery support covers a fraction of the platforms because the gallery URLs come from a different part of each app's response. A platform where the gallery data is not exposed in the share payload simply cannot be supported without a different extraction route.
The shared behaviour across all of them is the same problem. When you tap share in a Chinese app you get a short link like a v.douyin.com URL, and resolving it means following the redirect, then finding the real media URL in the landing page or in the API the page calls. The project depends on parsel and lxml for the HTML and jmespath for pulling values out of the JSON responses that sit behind those pages, which is what the dependency list says the modules are for.
The project is explicit that the parsers are fragile by nature, and its own tips say to prefer app share links because the desktop web version is not fully tested, and to include reproducible platform information and a share link when reporting a failure.
The response shape is fixed, and the fields tell you what is optional
The API returns a consistent object regardless of platform, which is the design decision that makes a multi-platform parser usable from code.
{
"author": {
"uid": "uid",
"name": "name",
"avatar": "https://xxx"
},
"title": "记录美好生活#峡谷天花板",
"video_url": "https://xxx",
"music_url": "https://yyy",
"cover_url": "https://zzz"
}The field table gives the meaning of each one, and the video_url is described as the watermark-free video link. The author block carries the uid, name and avatar. The music_url is the video's music link and the cover_url is the cover image.
For galleries there is an images list, with each entry carrying a url and a live_photo_url for the LivePhoto video of that image.
The one caveat is stated in a single line and it is the important one: fields other than the video address may be empty. So the contract is a fixed shape with optional contents, and a caller cannot assume a title or a cover exists for every platform. That is the price of a common schema across 25 platforms whose data models have no reason to agree, and it is a much better contract than a per-platform response that forces branching at every call site.
The library entry points mirror the two ways you can hold a reference to a video. There is parse_video_share_url, which takes the share link, and parse_video_id, which takes a platform and an id:
import json
import asyncio
from parse_video_py import parse_video_share_url, parse_video_id, VideoSource
# 根据分享链接解析
video_info = asyncio.run(parse_video_share_url("分享链接"))Both are coroutines, so they are driven with asyncio.run in the example. VideoSource is an enum, with entries such as VideoSource.DouYin, so the id-based call names the platform explicitly rather than inferring it from the id format.
Basic auth and a proxy are both opt-in, and both are environment variables
Two operational settings exist, and both are off by default, which matters if you expose the service.
The first is basic auth on the web service. To turn it on you set the environment variables yourself, and if you do not set them the authentication is not enabled:
export PARSE_VIDEO_USERNAME=username
export PARSE_VIDEO_PASSWORD=passwordThe second is an outbound proxy. If you do not set it, the service connects directly:
# 无认证代理
export PARSE_VIDEO_PROXY=http://proxy.example.com:端口
# 有认证代理
export PARSE_VIDEO_PROXY=http://user:[email protected]:端口The defaults are the right defaults for a service running on your own machine and the wrong defaults for one reachable from a network, so the deployment choice is yours. A proxy is often necessary anyway, since the platforms this targets are typically not reachable directly from outside mainland China, and the proxy setting takes the credentials inline for the authenticated form.
The Docker packaging carries both settings through as environment variables on the run command, and the same is true of the port mapping:
docker run -d -p 8000:8000 -e PARSE_VIDEO_USERNAME=username -e PARSE_VIDEO_PASSWORD=password wujunwei928/parse-video-pyThe image is based on python:3.10-slim, copies uv in from the registry image, copies pyproject.toml and src/ in, installs with `uv pip install --system ".[all]"`, exposes 8000 and starts the ASGI app with uvicorn bound to 0.0.0.0 on port 8000.
The packaging moved to extras, and the old requirements file is marked legacy
The dependency management has been tidied recently, and the project is explicit about it.
The pyproject.toml carries a base dependency set of aiohttp, fake-useragent, lxml, parsel, httpx, jmespath and pyyaml, and then three optional groups. The web group brings in fastapi, uvicorn, jinja2, python-multipart and the MCP packages, fastapi-mcp at 0.4 or newer plus mcp at 1.12 or newer below 2. The cli group brings in typer and rich. The dev group brings in pytest, pytest-asyncio, pytest-timeout, black, isort, flake8 and pre-commit. And there is an all extra that is simply the web and cli extras together, which is what the install commands use.
The requirements.txt at the root is now a legacy file, and its own header says so, noting that dependency management has moved to pyproject.toml and that new installs should use `uv pip install -e ".[all]"`. The pinned list is still there, aiohttp at 3.12.15, fastapi at 0.110.1, lxml at 5.2.1, parsel at 1.9.0, rich at 13.7.1 and so on, and the file is useful as a snapshot of what the project ran against when it was generated.
The rest of the configuration is conventional. The build is hatchling with the wheel target pointed at src/parse_video_py, so the package uses a src layout. Black runs at line length 88 and isort uses the black profile. Pytest has testpaths set to tests and asyncio_mode set to auto, which matters for a project whose tests are mostly async parser calls.
The project is MIT licensed, the version is 0.0.3, and it requires Python 3.10 or newer. The release history is v0.0.1 from 2025-07-06 and then v0.0.2 and v0.0.3 both on 2026-04-18, and the last push was on 2026-08-19.
Editorial conclusion
Adopt parse-video-py if you need to resolve share links from Chinese short video platforms into direct media URLs, either from the CLI, the HTTP API or through an MCP client, since it ships all three interfaces over one parser set. Skip it if you need a stable production dependency, because the version is 0.0.3, the parsers are tied to platform behaviour that changes without notice, and the platform count is the project's real surface area. Verify first which platform and link type you are parsing, since the project asks you to prefer app share links over the desktop web version, and that you have read the terms of the platforms involved before building a service on top of it.
Frequently asked questions
How do I install and run parse-video-py locally?
Create a virtual environment and install the project with all extras using `uv venv && uv pip install -e ".[all]"`, then activate it with `source .venv/bin/activate`. You can parse a link with `parse-video-py parse "https://v.douyin.com/xxx"`, add `--format json` for JSON output, start the web service with `parse-video-py serve --port 8000`, and check the version with `parse-video-py version`.
How do I call the parse-video-py HTTP API?
Start the service and request the parse endpoint with a `curl` call to the video share url parse path on port 8000, piping the result through `jq`. The response contains author, title, video_url, music_url and cover_url fields, and an images list for galleries, with the note that fields other than the video address may be empty.
Does parse-video-py support authentication and proxies?
Both are optional and off by default. Set PARSE_VIDEO_USERNAME and PARSE_VIDEO_PASSWORD to enable basic auth, and set PARSE_VIDEO_PROXY to route outbound requests through a proxy, with or without inline credentials. If the proxy variable is not set, the service connects directly.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wujunwei928-parse-video-py)Was this useful?