parsehub 2.3.8__tar.gz → 2.3.9__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 (83) hide show
  1. {parsehub-2.3.8/src/parsehub.egg-info → parsehub-2.3.9}/PKG-INFO +1 -1
  2. {parsehub-2.3.8 → parsehub-2.3.9}/pyproject.toml +1 -1
  3. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/xiaoheihe.py +18 -2
  4. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/xiaoheihe.py +15 -4
  5. {parsehub-2.3.8 → parsehub-2.3.9/src/parsehub.egg-info}/PKG-INFO +1 -1
  6. {parsehub-2.3.8 → parsehub-2.3.9}/LICENSE +0 -0
  7. {parsehub-2.3.8 → parsehub-2.3.9}/README.md +0 -0
  8. {parsehub-2.3.8 → parsehub-2.3.9}/setup.cfg +0 -0
  9. {parsehub-2.3.8 → parsehub-2.3.9}/src/__init__.py +0 -0
  10. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/__init__.py +0 -0
  11. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/cli.py +0 -0
  12. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/cli_config.py +0 -0
  13. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/config/__init__.py +0 -0
  14. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/config/config.py +0 -0
  15. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/errors.py +0 -0
  16. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/__init__.py +0 -0
  17. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/base/__init__.py +0 -0
  18. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/base/base.py +0 -0
  19. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/base/ytdlp.py +0 -0
  20. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/__init__.py +0 -0
  21. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/bangumi.py +0 -0
  22. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/bilibili.py +0 -0
  23. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/coolapk.py +0 -0
  24. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/douban.py +0 -0
  25. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/douyin.py +0 -0
  26. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/facebook.py +0 -0
  27. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/instagram.py +0 -0
  28. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/kuaishou.py +0 -0
  29. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/medium.py +0 -0
  30. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/pipix.py +0 -0
  31. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/snapchat.py +0 -0
  32. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/threads.py +0 -0
  33. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/tieba.py +0 -0
  34. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/tiktok.py +0 -0
  35. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/toutiao.py +0 -0
  36. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/twitter.py +0 -0
  37. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/weibo.py +0 -0
  38. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/weixin.py +0 -0
  39. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/wxchannels.py +0 -0
  40. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/xhs.py +0 -0
  41. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/youtube.py +0 -0
  42. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/zhihu.py +0 -0
  43. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/parsers/parser/zuiyou.py +0 -0
  44. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/__init__.py +0 -0
  45. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/bangumi.py +0 -0
  46. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/bilibili.py +0 -0
  47. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/coolapk.py +0 -0
  48. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/douban.py +0 -0
  49. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/douyin.py +0 -0
  50. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/instagram.py +0 -0
  51. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/kuaishou.py +0 -0
  52. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/medium.py +0 -0
  53. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/pipix.py +0 -0
  54. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/threads.py +0 -0
  55. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/tieba.py +0 -0
  56. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/tiktok.py +0 -0
  57. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/toutiao.py +0 -0
  58. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/twitter.py +0 -0
  59. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/weibo.py +0 -0
  60. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/weixin.py +0 -0
  61. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/wxchannels.py +0 -0
  62. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/xhs.py +0 -0
  63. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/zhihu.py +0 -0
  64. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/provider_api/zuiyou.py +0 -0
  65. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/types/__init__.py +0 -0
  66. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/types/callback.py +0 -0
  67. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/types/media_file.py +0 -0
  68. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/types/media_ref.py +0 -0
  69. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/types/platform.py +0 -0
  70. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/types/post.py +0 -0
  71. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/types/result.py +0 -0
  72. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/utils/downloader.py +0 -0
  73. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/utils/helpers.py +0 -0
  74. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub/utils/media_info.py +0 -0
  75. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub.egg-info/SOURCES.txt +0 -0
  76. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub.egg-info/dependency_links.txt +0 -0
  77. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub.egg-info/entry_points.txt +0 -0
  78. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub.egg-info/requires.txt +0 -0
  79. {parsehub-2.3.8 → parsehub-2.3.9}/src/parsehub.egg-info/top_level.txt +0 -0
  80. {parsehub-2.3.8 → parsehub-2.3.9}/test/test_cli.py +0 -0
  81. {parsehub-2.3.8 → parsehub-2.3.9}/test/test_cli_config.py +0 -0
  82. {parsehub-2.3.8 → parsehub-2.3.9}/test/test_core_offline.py +0 -0
  83. {parsehub-2.3.8 → parsehub-2.3.9}/test/test_downloader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: parsehub
3
- Version: 2.3.8
3
+ Version: 2.3.9
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.8"
3
+ version = "2.3.9"
4
4
  description = "轻量、异步、开箱即用的社交媒体聚合解析库"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12.0"
@@ -54,7 +54,23 @@ class XiaoHeiHeParser(BaseParser):
54
54
  images: list[ImageRef | AniRef] = []
55
55
  for media in xhh.media or []:
56
56
  if media.type == XiaoHeiHeMediaType.IMAGE:
57
- images.append(ImageRef(url=media.url, width=media.width or 0, height=media.height or 0))
57
+ images.append(
58
+ ImageRef(
59
+ url=media.url,
60
+ thumb_url=media.thumb_url,
61
+ ext=media.ext or "jpg",
62
+ width=media.width or 0,
63
+ height=media.height or 0,
64
+ )
65
+ )
58
66
  else:
59
- images.append(AniRef(url=media.url, width=media.width or 0, height=media.height or 0))
67
+ images.append(
68
+ AniRef(
69
+ url=media.url,
70
+ thumb_url=media.thumb_url,
71
+ ext=media.ext or "gif",
72
+ width=media.width or 0,
73
+ height=media.height or 0,
74
+ )
75
+ )
60
76
  return images
@@ -23,6 +23,11 @@ from cryptography.hazmat.primitives.ciphers.modes import CBC, ECB
23
23
  from markdownify import MarkdownConverter
24
24
 
25
25
 
26
+ def original_image_url(url: str) -> str:
27
+ path = url.split("?", 1)[0]
28
+ return re.sub(r"/thumb\.(\w+)$", r".\1", path)
29
+
30
+
26
31
  class XiaoHeiHePostType(Enum):
27
32
  VIDEO = "video"
28
33
  IMAGE = "image" # 图文, 单张或多张图片 + 文案
@@ -40,6 +45,7 @@ class XiaoHeiHeMedia:
40
45
  type: XiaoHeiHeMediaType
41
46
  url: str
42
47
  thumb_url: str | None = None
48
+ ext: str | None = None
43
49
  height: int | None = None
44
50
  width: int | None = None
45
51
 
@@ -89,11 +95,14 @@ class XiaoHeiHeAPI:
89
95
  for image in text_list[1:]:
90
96
  if image["type"] == "img":
91
97
  media_type = XiaoHeiHeMediaType.GIF if ".gif" in image["url"] else XiaoHeiHeMediaType.IMAGE
98
+ url = original_image_url(image["url"])
99
+ ext_match = re.search(r"\.([^./]+)$", url)
92
100
  images.append(
93
101
  XiaoHeiHeMedia(
94
102
  type=media_type,
95
- url=image["url"],
103
+ url=url,
96
104
  thumb_url=image["url"],
105
+ ext=ext_match.group(1) if ext_match else None,
97
106
  height=int(float(image.get("height", 0))),
98
107
  width=int(float(image.get("width", 0))),
99
108
  )
@@ -134,7 +143,7 @@ class XiaoHeiHeAPI:
134
143
  "owner_only": "1",
135
144
  **sig_params,
136
145
  }
137
- cookies = {"x_xhh_tokenid": await SecuritySm.get_d_id()}
146
+ cookies = {"x_xhh_tokenid": await SecuritySm.get_d_id(self.proxy)}
138
147
  async with httpx.AsyncClient(proxy=self.proxy) as cli:
139
148
  result = await cli.get(self.api_url + "/bbs/app/link/tree", params=params, cookies=cookies)
140
149
  result.raise_for_status()
@@ -355,6 +364,8 @@ class XHHConverter(MarkdownConverter):
355
364
  def convert_img(self, el, _, parent_tags):
356
365
  alt = el.attrs.get("alt", None) or ""
357
366
  src = el.attrs.get("data-original", None) or ""
367
+ if src:
368
+ src = original_image_url(src)
358
369
  title = el.attrs.get("title", None) or ""
359
370
  title_part = ' "{}"'.format(title.replace('"', r"\"")) if title else ""
360
371
  options = cast(dict[str, Any], getattr(self, "options")) # noqa: B009
@@ -504,7 +515,7 @@ class SecuritySm:
504
515
  return v + smsk_web + "0"
505
516
 
506
517
  @classmethod
507
- async def get_d_id(cls):
518
+ async def get_d_id(cls, proxy: str | None = None):
508
519
  uid = str(uuid.uuid4()).encode("utf-8")
509
520
  priId = hashlib.md5(uid).hexdigest()[0:16]
510
521
  encrypted_uid = cls.PK.encrypt(uid, padding.PKCS1v15())
@@ -531,7 +542,7 @@ class SecuritySm:
531
542
  des_target["tn"] = hashlib.md5(cls.get_tn(des_target).encode()).hexdigest()
532
543
 
533
544
  des_result = cls._AES(cls.GZIP(cls._DES(des_target)), priId.encode("utf-8"))
534
- async with httpx.AsyncClient() as client:
545
+ async with httpx.AsyncClient(proxy=proxy) as client:
535
546
  response = await client.post(
536
547
  cls.DEVICES_INFO_URL,
537
548
  json={
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: parsehub
3
- Version: 2.3.8
3
+ Version: 2.3.9
4
4
  Summary: 轻量、异步、开箱即用的社交媒体聚合解析库
5
5
  Author-email: 梓澪 <zilingmio@gmail.com>
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes