parsehub 2.1.2__tar.gz → 2.1.3__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.1.2/src/parsehub.egg-info → parsehub-2.1.3}/PKG-INFO +2 -2
- {parsehub-2.1.2 → parsehub-2.1.3}/pyproject.toml +3 -2
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/base/ytdlp.py +2 -2
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/bilibili.py +6 -5
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/douyin.py +26 -13
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/bilibili.py +4 -4
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/coolapk.py +4 -4
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/douyin.py +1 -1
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/instagram.py +5 -5
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/twitter.py +1 -1
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/zhihu.py +4 -4
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/types/result.py +13 -13
- {parsehub-2.1.2 → parsehub-2.1.3/src/parsehub.egg-info}/PKG-INFO +2 -2
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub.egg-info/requires.txt +1 -1
- {parsehub-2.1.2 → parsehub-2.1.3}/LICENSE +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/README.md +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/setup.cfg +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/cli.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/cli_config.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/config/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/config/config.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/errors.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/base/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/base/base.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/coolapk.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/facebook.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/instagram.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/kuaishou.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/pipix.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/snapchat.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/threads.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/tieba.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/tiktok.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/twitter.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/weibo.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/weixin.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/xhs.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/xiaoheihe.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/youtube.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/zhihu.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/parsers/parser/zuiyou.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/kuaishou.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/pipix.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/threads.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/tieba.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/tiktok.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/weibo.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/weixin.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/xhs.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/xiaoheihe.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/provider_api/zuiyou.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/types/__init__.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/types/callback.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/types/media_file.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/types/media_ref.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/types/platform.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/types/post.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/utils/downloader.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/utils/helpers.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub/utils/media_info.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub.egg-info/SOURCES.txt +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub.egg-info/dependency_links.txt +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub.egg-info/entry_points.txt +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/src/parsehub.egg-info/top_level.txt +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/test/test_cli.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/test/test_cli_config.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/test/test_core_offline.py +0 -0
- {parsehub-2.1.2 → parsehub-2.1.3}/test/test_downloader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: parsehub
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.3
|
|
4
4
|
Summary: 轻量、异步、开箱即用的社交媒体聚合解析库
|
|
5
5
|
Author-email: 梓澪 <zilingmio@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -34,7 +34,7 @@ Requires-Dist: python-slugify[unidecode]>=8.0.4
|
|
|
34
34
|
Requires-Dist: opencv-python-headless>=4.13.0.92
|
|
35
35
|
Requires-Dist: cryptography>=49.0.0
|
|
36
36
|
Requires-Dist: gmssl>=3.2.2
|
|
37
|
-
Requires-Dist:
|
|
37
|
+
Requires-Dist: signerpy>=0.12.0
|
|
38
38
|
Provides-Extra: cli
|
|
39
39
|
Requires-Dist: argcomplete>=3.6.3; extra == "cli"
|
|
40
40
|
Requires-Dist: platformdirs>=4.5.1; extra == "cli"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "parsehub"
|
|
3
|
-
version = "2.1.
|
|
3
|
+
version = "2.1.3"
|
|
4
4
|
description = "轻量、异步、开箱即用的社交媒体聚合解析库"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12.0"
|
|
@@ -37,7 +37,7 @@ dependencies = [
|
|
|
37
37
|
"opencv-python-headless>=4.13.0.92",
|
|
38
38
|
"cryptography>=49.0.0",
|
|
39
39
|
"gmssl>=3.2.2",
|
|
40
|
-
"
|
|
40
|
+
"signerpy>=0.12.0",
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
[project.scripts]
|
|
@@ -66,6 +66,7 @@ Issues = "https://github.com/z-mio/parsehub/issues"
|
|
|
66
66
|
|
|
67
67
|
[tool.ruff]
|
|
68
68
|
line-length = 120
|
|
69
|
+
exclude = ["test/_*.py"]
|
|
69
70
|
|
|
70
71
|
[tool.ruff.lint]
|
|
71
72
|
select = [
|
|
@@ -445,9 +445,9 @@ class YtVideoParseResult(VideoParseResult):
|
|
|
445
445
|
def __init__(
|
|
446
446
|
self,
|
|
447
447
|
dl: "YtVideoInfo",
|
|
448
|
-
title: str
|
|
448
|
+
title: str = "",
|
|
449
449
|
video: VideoRef | None = None,
|
|
450
|
-
content: str
|
|
450
|
+
content: str = "",
|
|
451
451
|
):
|
|
452
452
|
"""dl: yt-dlp解析结果"""
|
|
453
453
|
self.dl = dl
|
|
@@ -106,7 +106,6 @@ class BiliParse(BaseParser):
|
|
|
106
106
|
view = data["View"]
|
|
107
107
|
|
|
108
108
|
cid = view["cid"]
|
|
109
|
-
part = ""
|
|
110
109
|
duration = view["duration"]
|
|
111
110
|
dimension = view["dimension"]
|
|
112
111
|
desc = view["desc"]
|
|
@@ -114,7 +113,6 @@ class BiliParse(BaseParser):
|
|
|
114
113
|
if p != 1 and (pages := view.get("pages")):
|
|
115
114
|
if page_info := next((i for i in pages if i["page"] == p), None):
|
|
116
115
|
cid = page_info["cid"]
|
|
117
|
-
part = page_info["part"]
|
|
118
116
|
duration = page_info["duration"]
|
|
119
117
|
dimension = page_info["dimension"]
|
|
120
118
|
|
|
@@ -123,9 +121,12 @@ class BiliParse(BaseParser):
|
|
|
123
121
|
|
|
124
122
|
durl = video_playurl["data"]["durl"][0]
|
|
125
123
|
video_url = self.change_source(durl["backup_url"][0]) if durl.get("backup_url") else durl["url"]
|
|
124
|
+
content = desc.strip()
|
|
125
|
+
if content == "-":
|
|
126
|
+
content = ""
|
|
126
127
|
return BiliVideoParseResult(
|
|
127
128
|
title=data["View"]["title"],
|
|
128
|
-
content=
|
|
129
|
+
content=content,
|
|
129
130
|
video=VideoRef(
|
|
130
131
|
url=video_url,
|
|
131
132
|
thumb_url=data["View"]["pic"],
|
|
@@ -147,9 +148,9 @@ class BiliParse(BaseParser):
|
|
|
147
148
|
)
|
|
148
149
|
|
|
149
150
|
@staticmethod
|
|
150
|
-
def hashtag_handler(desc: str
|
|
151
|
+
def hashtag_handler(desc: str) -> str:
|
|
151
152
|
if not desc:
|
|
152
|
-
return
|
|
153
|
+
return ""
|
|
153
154
|
hashtags = re.findall(r" ?#[^#]+# ?", desc)
|
|
154
155
|
for hashtag in hashtags:
|
|
155
156
|
desc = desc.replace(hashtag, f" {hashtag.strip().removesuffix('#')} ")
|
|
@@ -117,13 +117,17 @@ def remove_video_watermark(url: str) -> str:
|
|
|
117
117
|
return url.replace("playwm", "play")
|
|
118
118
|
|
|
119
119
|
|
|
120
|
-
def
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
def _p_play_addr(video_data: dict) -> tuple[str | None, int, int]:
|
|
121
|
+
play_addr = video_data["play_addr"]
|
|
122
|
+
url_list = play_addr["url_list"]
|
|
123
|
+
if not url_list:
|
|
124
|
+
return None, 0, 0
|
|
125
|
+
return url_list[0], play_addr.get("width", 0), play_addr.get("height", 0)
|
|
126
|
+
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
def _p_bit_rates(video_data: dict) -> tuple[str, int, int]:
|
|
129
|
+
bit_rates: list = video_data.get("bit_rate", [])
|
|
130
|
+
bit_rates = list(filter(lambda i: i.get("is_bytevc1", 0) == 0, bit_rates))
|
|
127
131
|
bit_rates.sort(
|
|
128
132
|
key=lambda x: (
|
|
129
133
|
x.get("play_addr", {}).get("width", 0) * x.get("play_addr", {}).get("height", 0),
|
|
@@ -135,11 +139,20 @@ def parse_video_info(video_data: dict) -> dict:
|
|
|
135
139
|
best_quality = bit_rates[0]
|
|
136
140
|
|
|
137
141
|
play_addr = best_quality.get("play_addr", {})
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
url_list = play_addr.get("url_list", [])
|
|
143
|
+
return url_list[0], play_addr.get("width", 0), play_addr.get("height", 0)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def parse_video_info(video_data: dict) -> dict:
|
|
147
|
+
u, w, h = None, 0, 0
|
|
148
|
+
is_bytevc1 = video_data.get("is_bytevc1")
|
|
149
|
+
# is_bytevc1 = 1 | 2 为字节自研视频编码 bytevc1 | bytevc2
|
|
150
|
+
if is_bytevc1 == 0:
|
|
151
|
+
u, w, h = _p_play_addr(video_data)
|
|
152
|
+
if not u:
|
|
153
|
+
u, w, h = _p_bit_rates(video_data)
|
|
141
154
|
|
|
142
|
-
video_url = remove_video_watermark(
|
|
155
|
+
video_url = remove_video_watermark(u)
|
|
143
156
|
|
|
144
157
|
cover = video_data.get("cover", {})
|
|
145
158
|
thumb_url_list = cover.get("url_list", [])
|
|
@@ -148,9 +161,9 @@ def parse_video_info(video_data: dict) -> dict:
|
|
|
148
161
|
return {
|
|
149
162
|
"video_url": video_url,
|
|
150
163
|
"thumb_url": thumb_url,
|
|
151
|
-
"duration":
|
|
152
|
-
"width":
|
|
153
|
-
"height":
|
|
164
|
+
"duration": video_data.get("duration", 0),
|
|
165
|
+
"width": w,
|
|
166
|
+
"height": h,
|
|
154
167
|
}
|
|
155
168
|
|
|
156
169
|
|
|
@@ -245,8 +245,8 @@ class BiliImage:
|
|
|
245
245
|
|
|
246
246
|
@dataclass(kw_only=True)
|
|
247
247
|
class BiliDynamic:
|
|
248
|
-
title: str
|
|
249
|
-
content: str
|
|
248
|
+
title: str = ""
|
|
249
|
+
content: str = ""
|
|
250
250
|
images: list[BiliImage] | None = None
|
|
251
251
|
|
|
252
252
|
@classmethod
|
|
@@ -361,10 +361,10 @@ class BiliDynamic:
|
|
|
361
361
|
return cls(title=title)
|
|
362
362
|
|
|
363
363
|
@staticmethod
|
|
364
|
-
def _get_desc_text(module_dynamic: dict) -> str
|
|
364
|
+
def _get_desc_text(module_dynamic: dict) -> str:
|
|
365
365
|
if desc := module_dynamic["desc"]:
|
|
366
366
|
return str(desc["text"]).strip()
|
|
367
|
-
return
|
|
367
|
+
return ""
|
|
368
368
|
|
|
369
369
|
@staticmethod
|
|
370
370
|
def _get_major_cover(major_content: dict) -> list[BiliImage] | None:
|
|
@@ -10,9 +10,9 @@ from ..utils.helpers import UA
|
|
|
10
10
|
|
|
11
11
|
@dataclass
|
|
12
12
|
class Coolapk:
|
|
13
|
-
title: str
|
|
14
|
-
markdown_content: str
|
|
15
|
-
text_content: str
|
|
13
|
+
title: str = ""
|
|
14
|
+
markdown_content: str = ""
|
|
15
|
+
text_content: str = ""
|
|
16
16
|
imgs: list[str] | None = None
|
|
17
17
|
|
|
18
18
|
@classmethod
|
|
@@ -37,6 +37,6 @@ class Coolapk:
|
|
|
37
37
|
if feed_element and (feed_content := feed_element.text.strip()):
|
|
38
38
|
message_image_group = soup.find(class_="message-image-group")
|
|
39
39
|
imgs = [f"https:{i['src']}" for i in message_image_group.find_all("img")] if message_image_group else []
|
|
40
|
-
return cls(
|
|
40
|
+
return cls("", "", feed_content, imgs)
|
|
41
41
|
|
|
42
42
|
raise ValueError("获取内容失败, 分享时请保留 shareKey 或 s 参数")
|
|
@@ -1147,7 +1147,7 @@ class DouyinMobileCrawler:
|
|
|
1147
1147
|
return cast(dict[str, Any], payload)
|
|
1148
1148
|
last_error = f"{host} missing aweme_detail: {payload.get('status_msg') or payload}"
|
|
1149
1149
|
await asyncio.sleep(0.15)
|
|
1150
|
-
raise ParseError(f"
|
|
1150
|
+
raise ParseError(f"获取抖音作品失败: {last_error}")
|
|
1151
1151
|
|
|
1152
1152
|
async def parse(self, raw_url: str) -> dict:
|
|
1153
1153
|
aweme_id = await self.get_aweme_id(raw_url)
|
|
@@ -65,17 +65,17 @@ class InstagramPost:
|
|
|
65
65
|
return bool(self._field("is_video"))
|
|
66
66
|
|
|
67
67
|
@property
|
|
68
|
-
def title(self) -> str
|
|
69
|
-
return self._node.get("title")
|
|
68
|
+
def title(self) -> str:
|
|
69
|
+
return str(self._node.get("title", ""))
|
|
70
70
|
|
|
71
71
|
@property
|
|
72
|
-
def caption(self) -> str
|
|
72
|
+
def caption(self) -> str:
|
|
73
73
|
caption_edges = self._node.get("edge_media_to_caption", {}).get("edges") or []
|
|
74
74
|
if caption_edges:
|
|
75
75
|
if text := caption_edges[0].get("node", {}).get("text"):
|
|
76
76
|
return str(text)
|
|
77
|
-
return
|
|
78
|
-
return self._node.get("caption")
|
|
77
|
+
return ""
|
|
78
|
+
return str(self._node.get("caption", ""))
|
|
79
79
|
|
|
80
80
|
@property
|
|
81
81
|
def url(self) -> str:
|
|
@@ -91,8 +91,8 @@ class ZhihuQA:
|
|
|
91
91
|
class ZhihuZhuanLan:
|
|
92
92
|
title: str
|
|
93
93
|
imgs: list[str]
|
|
94
|
-
markdown_content: str
|
|
95
|
-
plaintext_content: str
|
|
94
|
+
markdown_content: str = ""
|
|
95
|
+
plaintext_content: str = ""
|
|
96
96
|
|
|
97
97
|
@classmethod
|
|
98
98
|
def parse(cls, data: dict) -> Self:
|
|
@@ -122,8 +122,8 @@ class ZhihuPin:
|
|
|
122
122
|
type: ZhihuPinType
|
|
123
123
|
title: str
|
|
124
124
|
media: list[ZhihuMedia]
|
|
125
|
-
markdown_content: str
|
|
126
|
-
plaintext_content: str
|
|
125
|
+
markdown_content: str = ""
|
|
126
|
+
plaintext_content: str = ""
|
|
127
127
|
|
|
128
128
|
@classmethod
|
|
129
129
|
def parse(cls, result: dict) -> "ZhihuPin":
|
|
@@ -30,8 +30,8 @@ class ParseResult(ABC): # noqa: B024
|
|
|
30
30
|
|
|
31
31
|
def __init__(
|
|
32
32
|
self,
|
|
33
|
-
title: str
|
|
34
|
-
content: str
|
|
33
|
+
title: str = "",
|
|
34
|
+
content: str = "",
|
|
35
35
|
media: Sequence[AnyMediaRef] | AnyMediaRef | None = None,
|
|
36
36
|
platform: Platform | None = None,
|
|
37
37
|
):
|
|
@@ -42,8 +42,8 @@ class ParseResult(ABC): # noqa: B024
|
|
|
42
42
|
:param platform: 平台
|
|
43
43
|
"""
|
|
44
44
|
self.raw_url: str = ""
|
|
45
|
-
self.title =
|
|
46
|
-
self.content =
|
|
45
|
+
self.title = title.strip()
|
|
46
|
+
self.content = content.strip()
|
|
47
47
|
self.media = media
|
|
48
48
|
self.platform = platform
|
|
49
49
|
self.name = slugify(
|
|
@@ -294,9 +294,9 @@ class VideoParseResult(ParseResult):
|
|
|
294
294
|
|
|
295
295
|
def __init__(
|
|
296
296
|
self,
|
|
297
|
-
title: str
|
|
297
|
+
title: str = "",
|
|
298
298
|
video: str | VideoRef | None = None,
|
|
299
|
-
content: str
|
|
299
|
+
content: str = "",
|
|
300
300
|
):
|
|
301
301
|
video = VideoRef(url=video) if isinstance(video, str) else video
|
|
302
302
|
super().__init__(
|
|
@@ -313,9 +313,9 @@ class ImageParseResult(ParseResult):
|
|
|
313
313
|
|
|
314
314
|
def __init__(
|
|
315
315
|
self,
|
|
316
|
-
title: str
|
|
316
|
+
title: str = "",
|
|
317
317
|
photo: Sequence[str | ImageRef | AniRef | LivePhotoRef] | None = None,
|
|
318
|
-
content: str
|
|
318
|
+
content: str = "",
|
|
319
319
|
):
|
|
320
320
|
media = [ImageRef(url=p) if isinstance(p, str) else p for p in photo] if photo else None
|
|
321
321
|
super().__init__(title=title, media=media, content=content)
|
|
@@ -328,9 +328,9 @@ class MultimediaParseResult(ParseResult):
|
|
|
328
328
|
|
|
329
329
|
def __init__(
|
|
330
330
|
self,
|
|
331
|
-
title: str
|
|
331
|
+
title: str = "",
|
|
332
332
|
media: Sequence[AnyMediaRef] | None = None,
|
|
333
|
-
content: str
|
|
333
|
+
content: str = "",
|
|
334
334
|
):
|
|
335
335
|
super().__init__(title=title, media=media, content=content)
|
|
336
336
|
|
|
@@ -342,16 +342,16 @@ class RichTextParseResult(ParseResult):
|
|
|
342
342
|
|
|
343
343
|
def __init__(
|
|
344
344
|
self,
|
|
345
|
-
title: str
|
|
345
|
+
title: str = "",
|
|
346
346
|
media: Sequence[AnyMediaRef] | None = None,
|
|
347
|
-
markdown_content: str
|
|
347
|
+
markdown_content: str = "",
|
|
348
348
|
):
|
|
349
349
|
"""
|
|
350
350
|
:param title: 标题
|
|
351
351
|
:param media: 文章中的媒体
|
|
352
352
|
:param markdown_content: markdown 格式正文
|
|
353
353
|
"""
|
|
354
|
-
self.markdown_content = markdown_content
|
|
354
|
+
self.markdown_content = markdown_content
|
|
355
355
|
super().__init__(title=title, media=media, content=self.plaintext_content)
|
|
356
356
|
|
|
357
357
|
def __repr__(self) -> str:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: parsehub
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.3
|
|
4
4
|
Summary: 轻量、异步、开箱即用的社交媒体聚合解析库
|
|
5
5
|
Author-email: 梓澪 <zilingmio@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -34,7 +34,7 @@ Requires-Dist: python-slugify[unidecode]>=8.0.4
|
|
|
34
34
|
Requires-Dist: opencv-python-headless>=4.13.0.92
|
|
35
35
|
Requires-Dist: cryptography>=49.0.0
|
|
36
36
|
Requires-Dist: gmssl>=3.2.2
|
|
37
|
-
Requires-Dist:
|
|
37
|
+
Requires-Dist: signerpy>=0.12.0
|
|
38
38
|
Provides-Extra: cli
|
|
39
39
|
Requires-Dist: argcomplete>=3.6.3; extra == "cli"
|
|
40
40
|
Requires-Dist: platformdirs>=4.5.1; extra == "cli"
|
|
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
|