parsehub 2.3.13__tar.gz → 2.3.14__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.
Files changed (85) hide show
  1. {parsehub-2.3.13/src/parsehub.egg-info → parsehub-2.3.14}/PKG-INFO +1 -1
  2. {parsehub-2.3.13 → parsehub-2.3.14}/pyproject.toml +1 -1
  3. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/bilibili.py +8 -9
  4. {parsehub-2.3.13 → parsehub-2.3.14/src/parsehub.egg-info}/PKG-INFO +1 -1
  5. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub.egg-info/SOURCES.txt +1 -0
  6. parsehub-2.3.14/test/test_bilibili_offline.py +63 -0
  7. {parsehub-2.3.13 → parsehub-2.3.14}/LICENSE +0 -0
  8. {parsehub-2.3.13 → parsehub-2.3.14}/README.md +0 -0
  9. {parsehub-2.3.13 → parsehub-2.3.14}/setup.cfg +0 -0
  10. {parsehub-2.3.13 → parsehub-2.3.14}/src/__init__.py +0 -0
  11. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/__init__.py +0 -0
  12. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/cli.py +0 -0
  13. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/cli_config.py +0 -0
  14. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/config/__init__.py +0 -0
  15. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/config/config.py +0 -0
  16. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/errors.py +0 -0
  17. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/__init__.py +0 -0
  18. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/base/__init__.py +0 -0
  19. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/base/base.py +0 -0
  20. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/base/ytdlp.py +0 -0
  21. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/__init__.py +0 -0
  22. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/bangumi.py +0 -0
  23. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/coolapk.py +0 -0
  24. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/douban.py +0 -0
  25. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/douyin.py +0 -0
  26. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/facebook.py +0 -0
  27. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/instagram.py +0 -0
  28. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/kuaishou.py +0 -0
  29. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/medium.py +0 -0
  30. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/pipix.py +0 -0
  31. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/snapchat.py +0 -0
  32. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/threads.py +0 -0
  33. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/tieba.py +0 -0
  34. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/tiktok.py +0 -0
  35. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/toutiao.py +0 -0
  36. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/twitter.py +0 -0
  37. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/weibo.py +0 -0
  38. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/weixin.py +0 -0
  39. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/wxchannels.py +0 -0
  40. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/xhs.py +0 -0
  41. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/xiaoheihe.py +0 -0
  42. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/youtube.py +0 -0
  43. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/zhihu.py +0 -0
  44. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/parsers/parser/zuiyou.py +0 -0
  45. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/__init__.py +0 -0
  46. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/bangumi.py +0 -0
  47. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/bilibili.py +0 -0
  48. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/coolapk.py +0 -0
  49. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/douban.py +0 -0
  50. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/douyin.py +0 -0
  51. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/instagram.py +0 -0
  52. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/kuaishou.py +0 -0
  53. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/medium.py +0 -0
  54. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/pipix.py +0 -0
  55. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/threads.py +0 -0
  56. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/tieba.py +0 -0
  57. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/tiktok.py +0 -0
  58. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/toutiao.py +0 -0
  59. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/twitter.py +0 -0
  60. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/weibo.py +0 -0
  61. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/weixin.py +0 -0
  62. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/wxchannels.py +0 -0
  63. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/xhs.py +0 -0
  64. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/xiaoheihe.py +0 -0
  65. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/zhihu.py +0 -0
  66. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/provider_api/zuiyou.py +0 -0
  67. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/types/__init__.py +0 -0
  68. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/types/callback.py +0 -0
  69. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/types/media_file.py +0 -0
  70. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/types/media_ref.py +0 -0
  71. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/types/platform.py +0 -0
  72. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/types/post.py +0 -0
  73. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/types/result.py +0 -0
  74. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/utils/downloader.py +0 -0
  75. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/utils/fallback.py +0 -0
  76. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/utils/helpers.py +0 -0
  77. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub/utils/media_info.py +0 -0
  78. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub.egg-info/dependency_links.txt +0 -0
  79. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub.egg-info/entry_points.txt +0 -0
  80. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub.egg-info/requires.txt +0 -0
  81. {parsehub-2.3.13 → parsehub-2.3.14}/src/parsehub.egg-info/top_level.txt +0 -0
  82. {parsehub-2.3.13 → parsehub-2.3.14}/test/test_cli.py +0 -0
  83. {parsehub-2.3.13 → parsehub-2.3.14}/test/test_cli_config.py +0 -0
  84. {parsehub-2.3.13 → parsehub-2.3.14}/test/test_core_offline.py +0 -0
  85. {parsehub-2.3.13 → parsehub-2.3.14}/test/test_downloader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: parsehub
3
- Version: 2.3.13
3
+ Version: 2.3.14
4
4
  Summary: 轻量、异步、开箱即用的社交媒体聚合解析库
5
5
  Author-email: 梓澪 <zilingmio@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "parsehub"
3
- version = "2.3.13"
3
+ version = "2.3.14"
4
4
  description = "轻量、异步、开箱即用的社交媒体聚合解析库"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12.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
- cid = view["cid"]
116
- duration = view["duration"]
117
- dimension = view["dimension"]
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: parsehub
3
- Version: 2.3.13
3
+ Version: 2.3.14
4
4
  Summary: 轻量、异步、开箱即用的社交媒体聚合解析库
5
5
  Author-email: 梓澪 <zilingmio@gmail.com>
6
6
  License: MIT
@@ -76,6 +76,7 @@ src/parsehub/utils/downloader.py
76
76
  src/parsehub/utils/fallback.py
77
77
  src/parsehub/utils/helpers.py
78
78
  src/parsehub/utils/media_info.py
79
+ test/test_bilibili_offline.py
79
80
  test/test_cli.py
80
81
  test/test_cli_config.py
81
82
  test/test_core_offline.py
@@ -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)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes