parsehub 2.3.13__tar.gz → 2.3.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {parsehub-2.3.13/src/parsehub.egg-info → parsehub-2.3.15}/PKG-INFO +2 -2
- {parsehub-2.3.13 → parsehub-2.3.15}/pyproject.toml +2 -2
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/bilibili.py +8 -9
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/xhs.py +1 -22
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/zuiyou.py +2 -1
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/xhs.py +6 -9
- {parsehub-2.3.13 → parsehub-2.3.15/src/parsehub.egg-info}/PKG-INFO +2 -2
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub.egg-info/SOURCES.txt +1 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub.egg-info/requires.txt +1 -1
- parsehub-2.3.15/test/test_bilibili_offline.py +63 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/test/test_core_offline.py +1 -2
- {parsehub-2.3.13 → parsehub-2.3.15}/LICENSE +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/README.md +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/setup.cfg +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/cli.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/cli_config.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/config/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/config/config.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/errors.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/base/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/base/base.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/base/ytdlp.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/bangumi.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/coolapk.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/douban.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/douyin.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/facebook.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/instagram.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/kuaishou.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/medium.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/pipix.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/snapchat.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/threads.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/tieba.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/tiktok.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/toutiao.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/twitter.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/weibo.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/weixin.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/wxchannels.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/xiaoheihe.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/youtube.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/parsers/parser/zhihu.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/bangumi.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/bilibili.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/coolapk.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/douban.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/douyin.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/instagram.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/kuaishou.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/medium.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/pipix.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/threads.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/tieba.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/tiktok.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/toutiao.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/twitter.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/weibo.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/weixin.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/wxchannels.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/xiaoheihe.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/zhihu.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/provider_api/zuiyou.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/types/__init__.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/types/callback.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/types/media_file.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/types/media_ref.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/types/platform.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/types/post.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/types/result.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/utils/downloader.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/utils/fallback.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/utils/helpers.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub/utils/media_info.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub.egg-info/dependency_links.txt +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub.egg-info/entry_points.txt +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/src/parsehub.egg-info/top_level.txt +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/test/test_cli.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/test/test_cli_config.py +0 -0
- {parsehub-2.3.13 → parsehub-2.3.15}/test/test_downloader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: parsehub
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.15
|
|
4
4
|
Summary: 轻量、异步、开箱即用的社交媒体聚合解析库
|
|
5
5
|
Author-email: 梓澪 <zilingmio@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -22,7 +22,7 @@ Requires-Dist: pydub>=0.25.1
|
|
|
22
22
|
Requires-Dist: python-dotenv>=1.0.1
|
|
23
23
|
Requires-Dist: tenacity>=8.5.0
|
|
24
24
|
Requires-Dist: urlextract>=1.9.0
|
|
25
|
-
Requires-Dist: yt-dlp[default]>=2026.10.
|
|
25
|
+
Requires-Dist: yt-dlp[default]>=2026.10.26.220202.dev0
|
|
26
26
|
Requires-Dist: lxml>=5.3.0
|
|
27
27
|
Requires-Dist: pydantic>=1.10.19
|
|
28
28
|
Requires-Dist: markdownify>=1.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "parsehub"
|
|
3
|
-
version = "2.3.
|
|
3
|
+
version = "2.3.15"
|
|
4
4
|
description = "轻量、异步、开箱即用的社交媒体聚合解析库"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12.0"
|
|
@@ -25,7 +25,7 @@ dependencies = [
|
|
|
25
25
|
"python-dotenv>=1.0.1",
|
|
26
26
|
"tenacity>=8.5.0",
|
|
27
27
|
"urlextract>=1.9.0",
|
|
28
|
-
"yt-dlp[default]>=2026.10.
|
|
28
|
+
"yt-dlp[default]>=2026.10.26.220202.dev0",
|
|
29
29
|
"lxml>=5.3.0",
|
|
30
30
|
"pydantic>=1.10.19",
|
|
31
31
|
"markdownify>=1.1.0",
|
|
@@ -112,17 +112,16 @@ class BiliParse(BaseParser):
|
|
|
112
112
|
p = int(parse_qs(urlparse(url).query).get("p", ["1"])[0])
|
|
113
113
|
view = data["View"]
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
pages = view.get("pages") or []
|
|
116
|
+
page_info = next((i for i in pages if i["page"] == p), None)
|
|
117
|
+
if page_info is None and pages:
|
|
118
|
+
page_info = pages[0] # p 越界时回退默认P
|
|
119
|
+
|
|
120
|
+
cid = page_info["cid"] if page_info else view["cid"]
|
|
121
|
+
duration = page_info["duration"] if page_info else view["duration"]
|
|
122
|
+
dimension = page_info["dimension"] if page_info else view["dimension"]
|
|
118
123
|
desc = view["desc"]
|
|
119
124
|
|
|
120
|
-
if p != 1 and (pages := view.get("pages")):
|
|
121
|
-
if page_info := next((i for i in pages if i["page"] == p), None):
|
|
122
|
-
cid = page_info["cid"]
|
|
123
|
-
duration = page_info["duration"]
|
|
124
|
-
dimension = page_info["dimension"]
|
|
125
|
-
|
|
126
125
|
b3, b4 = await bili.get_buvid()
|
|
127
126
|
video_playurl = await bili.get_video_playurl(url, cid, b3, b4)
|
|
128
127
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from typing import Union
|
|
3
3
|
|
|
4
|
-
import httpx
|
|
5
|
-
|
|
6
4
|
from ...provider_api.xhs import MOBILE_HEADERS, PC_HEADERS, XHSAPI, XHSMedia, XHSMediaType, XHSPost, XHSPostType
|
|
7
5
|
from ...types import (
|
|
8
6
|
ContentUnavailableError,
|
|
@@ -81,12 +79,8 @@ class XHSParser(BaseParser):
|
|
|
81
79
|
LivePhotoRef(url=i.thumb_url or "", video_url=i.url, width=i.width, height=i.height)
|
|
82
80
|
)
|
|
83
81
|
else:
|
|
84
|
-
# 小红书图片格式: "png" | "webp" | "jpeg" | "heic" | "avif"
|
|
85
|
-
ext = await self.get_ext_by_url(i.url)
|
|
86
|
-
if ext not in ["png", "webp", "jpeg", "heic", "avif"]:
|
|
87
|
-
ext = "jpeg"
|
|
88
82
|
photos.append(
|
|
89
|
-
ImageRef(url=i.url, ext=
|
|
83
|
+
ImageRef(url=i.url, ext="jpg", thumb_url=i.thumb_url, width=i.width, height=i.height)
|
|
90
84
|
)
|
|
91
85
|
|
|
92
86
|
return ImageParseResult(
|
|
@@ -97,21 +91,6 @@ class XHSParser(BaseParser):
|
|
|
97
91
|
case _:
|
|
98
92
|
raise ParseError("不支持的类型")
|
|
99
93
|
|
|
100
|
-
async def get_ext_by_url(self, url: str) -> str:
|
|
101
|
-
async with httpx.AsyncClient(proxy=self.proxy) as client:
|
|
102
|
-
try:
|
|
103
|
-
response = await client.head(url, follow_redirects=True)
|
|
104
|
-
except Exception:
|
|
105
|
-
return ""
|
|
106
|
-
|
|
107
|
-
if content_type := response.headers.get("content-type"):
|
|
108
|
-
media_type = content_type.split(";")[0].strip()
|
|
109
|
-
if "/" in media_type:
|
|
110
|
-
extension = media_type.split("/")[-1]
|
|
111
|
-
return str(extension)
|
|
112
|
-
|
|
113
|
-
return ""
|
|
114
|
-
|
|
115
94
|
@staticmethod
|
|
116
95
|
def hashtag_handler(desc: str | None) -> str:
|
|
117
96
|
if not desc:
|
|
@@ -6,7 +6,8 @@ from ..base.base import BaseParser
|
|
|
6
6
|
class ZuiYouParser(BaseParser):
|
|
7
7
|
__platform__ = Platform.ZUIYOU
|
|
8
8
|
__supported_type__ = ["视频", "图文"]
|
|
9
|
-
__match__ = r"^(http(s)?://)share.xiaochuankeji.cn/hybrid/share/post\?pid=\d+"
|
|
9
|
+
__match__ = r"^(http(s)?://)(share.xiaochuankeji.cn/hybrid/share/post\?pid=\d+|s.izuiyou.com/s/\w+)"
|
|
10
|
+
__redirect_keywords__ = ["s.izuiyou.com/s/"]
|
|
10
11
|
__reserved_parameters__ = ["pid"]
|
|
11
12
|
|
|
12
13
|
async def _do_parse(self, raw_url: str) -> MultimediaParseResult:
|
|
@@ -8,6 +8,7 @@ import re
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from enum import Enum
|
|
10
10
|
from typing import Any, cast
|
|
11
|
+
from urllib.parse import urlsplit
|
|
11
12
|
|
|
12
13
|
import httpx
|
|
13
14
|
from bs4 import BeautifulSoup
|
|
@@ -87,6 +88,7 @@ class XHSAPI:
|
|
|
87
88
|
script = scripts[0].text
|
|
88
89
|
json_data = script.replace("window.__INITIAL_STATE__=", "")
|
|
89
90
|
json_data = re.sub(r"\bundefined\b", "null", json_data) # 清理js对象
|
|
91
|
+
json_data = re.sub(r"new Set\((\[[^\]]*\])\)", r"\1", json_data)
|
|
90
92
|
data = json.loads(json_data)
|
|
91
93
|
return cast(dict[str, Any], data)
|
|
92
94
|
|
|
@@ -192,18 +194,13 @@ class XHSAPI:
|
|
|
192
194
|
|
|
193
195
|
@staticmethod
|
|
194
196
|
def get_trace_id(img_url: str) -> str:
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
match = re.search(r"/([^/!]+)(?:!.*)?$", img_url)
|
|
200
|
-
if match:
|
|
201
|
-
return match.group(1)
|
|
202
|
-
return img_url
|
|
197
|
+
path = urlsplit(img_url).path.split("!", 1)[0]
|
|
198
|
+
match = re.search(r"/[a-f0-9]{32}/(.+)", path)
|
|
199
|
+
return match.group(1) if match else path.lstrip("/")
|
|
203
200
|
|
|
204
201
|
def get_raw_image_url(self, ime_url: str) -> str:
|
|
205
202
|
"""拼接无水印图片链接"""
|
|
206
|
-
return f"
|
|
203
|
+
return f"https://sns-img-hw.xhscdn.com/{self.get_trace_id(ime_url)}?imageView2/format/jpg"
|
|
207
204
|
|
|
208
205
|
|
|
209
206
|
class XHSMediaType(Enum):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: parsehub
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.15
|
|
4
4
|
Summary: 轻量、异步、开箱即用的社交媒体聚合解析库
|
|
5
5
|
Author-email: 梓澪 <zilingmio@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -22,7 +22,7 @@ Requires-Dist: pydub>=0.25.1
|
|
|
22
22
|
Requires-Dist: python-dotenv>=1.0.1
|
|
23
23
|
Requires-Dist: tenacity>=8.5.0
|
|
24
24
|
Requires-Dist: urlextract>=1.9.0
|
|
25
|
-
Requires-Dist: yt-dlp[default]>=2026.10.
|
|
25
|
+
Requires-Dist: yt-dlp[default]>=2026.10.26.220202.dev0
|
|
26
26
|
Requires-Dist: lxml>=5.3.0
|
|
27
27
|
Requires-Dist: pydantic>=1.10.19
|
|
28
28
|
Requires-Dist: markdownify>=1.1.0
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import patch
|
|
3
|
+
|
|
4
|
+
from parsehub.parsers.parser.bilibili import BiliParse
|
|
5
|
+
|
|
6
|
+
VIEW = {
|
|
7
|
+
"cid": 111,
|
|
8
|
+
"duration": 769,
|
|
9
|
+
"dimension": {"width": 1920, "height": 1080},
|
|
10
|
+
"desc": "",
|
|
11
|
+
"title": "test",
|
|
12
|
+
"pic": "https://cdn.example/cover.jpg",
|
|
13
|
+
"pages": [
|
|
14
|
+
{"page": 1, "cid": 111, "duration": 190, "dimension": {"width": 1920, "height": 1080}},
|
|
15
|
+
{"page": 2, "cid": 222, "duration": 193, "dimension": {"width": 1920, "height": 1080}},
|
|
16
|
+
],
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class FakeBiliAPI:
|
|
21
|
+
last_cid = None
|
|
22
|
+
|
|
23
|
+
def __init__(self, proxy=None):
|
|
24
|
+
self.proxy = proxy
|
|
25
|
+
|
|
26
|
+
async def __aenter__(self):
|
|
27
|
+
return self
|
|
28
|
+
|
|
29
|
+
async def __aexit__(self, *args):
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
async def get_video_info(self, url):
|
|
33
|
+
return {"data": {"View": VIEW}}
|
|
34
|
+
|
|
35
|
+
async def get_buvid(self):
|
|
36
|
+
return "b3", "b4"
|
|
37
|
+
|
|
38
|
+
async def get_video_playurl(self, url, cid, b3, b4):
|
|
39
|
+
FakeBiliAPI.last_cid = cid
|
|
40
|
+
return {"data": {"durl": [{"url": "https://cdn.example/video.mp4"}]}}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class TestBilibiliParts(unittest.IsolatedAsyncioTestCase):
|
|
44
|
+
async def test_default_part_uses_first_page_duration(self):
|
|
45
|
+
with patch("parsehub.parsers.parser.bilibili.BiliAPI", FakeBiliAPI):
|
|
46
|
+
result = await BiliParse().bili_api_parse("https://www.bilibili.com/video/BV1zLap6VEz1/")
|
|
47
|
+
|
|
48
|
+
self.assertEqual(result.media.duration, 190)
|
|
49
|
+
self.assertEqual(FakeBiliAPI.last_cid, 111)
|
|
50
|
+
|
|
51
|
+
async def test_requested_part_uses_page_duration(self):
|
|
52
|
+
with patch("parsehub.parsers.parser.bilibili.BiliAPI", FakeBiliAPI):
|
|
53
|
+
result = await BiliParse().bili_api_parse("https://www.bilibili.com/video/BV1zLap6VEz1/?p=2")
|
|
54
|
+
|
|
55
|
+
self.assertEqual(result.media.duration, 193)
|
|
56
|
+
self.assertEqual(FakeBiliAPI.last_cid, 222)
|
|
57
|
+
|
|
58
|
+
async def test_out_of_range_falls_back_to_default_part(self):
|
|
59
|
+
with patch("parsehub.parsers.parser.bilibili.BiliAPI", FakeBiliAPI):
|
|
60
|
+
result = await BiliParse().bili_api_parse("https://www.bilibili.com/video/BV1zLap6VEz1/?p=99")
|
|
61
|
+
|
|
62
|
+
self.assertEqual(result.media.duration, 190)
|
|
63
|
+
self.assertEqual(FakeBiliAPI.last_cid, 111)
|
|
@@ -640,8 +640,7 @@ class TestPlatformUrlMatching(unittest.TestCase):
|
|
|
640
640
|
],
|
|
641
641
|
Platform.XIAOHEIHE: [
|
|
642
642
|
"https://www.xiaoheihe.cn/app/bbs/link/174972336",
|
|
643
|
-
"https://
|
|
644
|
-
"https://api.xiaoheihe.cn/v3/bbs/app/link?link_id=174972336",
|
|
643
|
+
"https://api.xiaoheihe.cn/v3/bbs/app/api/web/share?h_camp=link&h_src=YXBwX3NoYXJl&link_id=57b172affdbc",
|
|
645
644
|
],
|
|
646
645
|
Platform.YOUTUBE: [
|
|
647
646
|
"https://www.youtube.com/watch?v=1h_uc3K4Cpg",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|