Skip to content

Commit 36f02c4

Browse files
authored
v2.1.3: 实现对禁漫图片URL中的v参数的模拟 (#78)
1 parent 41b3c0c commit 36f02c4

File tree

7 files changed

+83
-16
lines changed

7 files changed

+83
-16
lines changed

.github/workflows/test.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ name: 跑测试
33
on:
44
push:
55
branches: [ "dev" ]
6-
paths:
7-
- 'assets/config/*.yml' # option配置文件
8-
- 'src/**/*.py' # 源码
9-
- 'tests/**/*.py' # 测试代码
6+
paths-ignore:
7+
- 'src/**/__init__.py'
8+
- '.github/workflows/*'
9+
- 'usage/workflow_download.py'
10+
- 'assets/config/option_workflow_download.yml'
11+
- 'assets/docs/*'
1012

1113
jobs:
1214
test: # This code is based on https://github.com/gaogaotiantian/viztracer/blob/master/.github/workflows/python-package.yml

src/jmcomic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
# 被依赖方 <--- 使用方
33
# config <--- entity <--- toolkit <--- client <--- option
44

5-
__version__ = '2.1.2'
5+
__version__ = '2.1.3'
66

77
from .api import *

src/jmcomic/jm_client_impl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def get_if_fail_raise(url):
246246
"""
247247
使用此方法包装 self.get
248248
"""
249-
resp = JmImageResp(self.get(url, params={'v': format_ts()}))
249+
resp = JmImageResp(self.get(url))
250250

251251
if resp.is_success:
252252
return resp

src/jmcomic/jm_client_interface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ def download_by_image_detail(self,
237237
decode_image=True,
238238
):
239239
self.download_image(
240-
img_detail.img_url,
240+
img_detail.download_url,
241241
img_save_path,
242242
img_detail.scramble_id,
243243
decode_image=decode_image,

src/jmcomic/jm_entity.py

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def __init__(self,
4848
img_file_name,
4949
img_file_suffix,
5050
from_photo=None,
51+
query_params=None,
5152
) -> None:
5253
self.aid: str = aid
5354
self.scramble_id: str = scramble_id
@@ -56,17 +57,31 @@ def __init__(self,
5657
self.img_file_suffix: str = img_file_suffix
5758

5859
self.from_photo: Optional[JmPhotoDetail] = from_photo
60+
self.query_params: StrNone = query_params
5961

6062
@property
61-
def filename(self):
63+
def filename(self) -> str:
6264
return self.img_file_name + self.img_file_suffix
6365

66+
@property
67+
def download_url(self) -> str:
68+
"""
69+
图片的下载路径
70+
与 self.img_url 的唯一不同是,在最后会带上 ?{self.query_params}
71+
@return:
72+
"""
73+
if self.query_params is None:
74+
return self.img_url
75+
76+
return f'{self.img_url}?{self.query_params}'
77+
6478
@classmethod
6579
def of(cls,
6680
photo_id: str,
6781
scramble_id: str,
6882
data_original: str,
6983
from_photo=None,
84+
query_params=None,
7085
) -> 'JmImageDetail':
7186
"""
7287
该方法用于创建 JmImageDetail 对象
@@ -85,6 +100,7 @@ def of(cls,
85100
img_file_name=data_original[x + 1:y],
86101
img_file_suffix=data_original[y:],
87102
from_photo=from_photo,
103+
query_params=query_params,
88104
)
89105

90106

@@ -99,6 +115,7 @@ def __init__(self,
99115
sort,
100116
page_arr=None,
101117
data_original_domain=None,
118+
data_original_0=None,
102119
author=None,
103120
from_album=None,
104121
):
@@ -111,17 +128,28 @@ def __init__(self,
111128

112129
self._author: StrNone = author
113130
self.from_album: Optional[JmAlbumDetail] = from_album
131+
self.index = self.album_index
114132

115133
# 下面的属性和图片url有关
116134
if isinstance(page_arr, str):
117135
import json
118136
page_arr = json.loads(page_arr)
119137

120-
# 该photo的所有图片名 img_name
138+
# page_arr存放了该photo的所有图片文件名 img_name
121139
self.page_arr: List[str] = page_arr
122-
# 图片域名
140+
# 图片的cdn域名
123141
self.data_original_domain: StrNone = data_original_domain
124-
self.index = self.album_index
142+
# 第一张图的URL
143+
self.data_original_0 = data_original_0
144+
145+
# 2023-07-14
146+
# 禁漫的图片url加上了一个参数v,如果没有带上这个参数v,图片会返回空数据
147+
# 参数v的特点:
148+
# 1. 值似乎是该photo的更新时间的时间戳,因此所有图片都使用同一个值
149+
# 2. 值目前在网页端只在photo页面的图片标签的data-original属性出现
150+
# 这里的模拟思路是,获取到第一个图片标签的data-original,
151+
# 取出其query参数 → self.data_original_query_params, 该值未来会传递给 JmImageDetail
152+
self.data_original_query_params = self.get_data_original_query_params(data_original_0)
125153

126154
@property
127155
def is_single_album(self) -> bool:
@@ -179,7 +207,8 @@ def create_image_detail(self, index) -> JmImageDetail:
179207
self.photo_id,
180208
self.scramble_id,
181209
data_original,
182-
from_photo=self
210+
from_photo=self,
211+
query_params=self.data_original_query_params,
183212
)
184213

185214
def get_img_data_original(self, img_name: str) -> str:
@@ -194,6 +223,17 @@ def get_img_data_original(self, img_name: str) -> str:
194223

195224
return f'https://{data_original_domain}/media/photos/{self.photo_id}/{img_name}'
196225

226+
# noinspection PyMethodMayBeStatic
227+
def get_data_original_query_params(self, data_original_0: StrNone) -> str:
228+
if data_original_0 is None:
229+
return f'v={time_stamp()}'
230+
231+
index = data_original_0.rfind('?')
232+
if index == -1:
233+
return f'v={time_stamp()}'
234+
235+
return data_original_0[index + 1:]
236+
197237
def __getitem__(self, item) -> JmImageDetail:
198238
return self.create_image_detail(item)
199239

src/jmcomic/jm_toolkit.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class JmcomicText:
1111
pattern_html_photo_title = compile('<title>(.*?)\|.*</title>')
1212
# pattern_html_photo_data_original_list = compile('data-original="(.*?)" id="album_photo_.+?"')
1313
pattern_html_photo_data_original_domain = compile('src="https://(.*?)/media/albums/blank')
14+
pattern_html_photo_data_original_0 = compile('data-original="(.*?)" id="album_photo')
1415
pattern_html_photo_keywords = compile('<meta name="keywords"[\s\S]*?content="(.*?)"')
1516
pattern_html_photo_series_id = compile('var series_id = (\d+);')
1617
pattern_html_photo_sort = compile('var sort = (\d+);')

tests/test_jmcomic/test_jm_api.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,31 @@ def run(aid):
102102
)
103103

104104
def test_get_jmcomic_url(self):
105-
print(self.client.get_jmcomic_url())
106-
print(self.client.get_jmcomic_domain_all())
107-
print(JmModuleConfig.get_jmcomic_url())
108-
print(JmModuleConfig.get_jmcomic_domain_all())
105+
func_list = {
106+
self.client.get_jmcomic_url,
107+
self.client.get_jmcomic_domain_all,
108+
JmModuleConfig.get_jmcomic_url,
109+
JmModuleConfig.get_jmcomic_domain_all,
110+
}
111+
112+
exception_list = []
113+
114+
def run_func_async(func):
115+
try:
116+
func()
117+
except BaseException as e:
118+
exception_list.append(e)
119+
traceback_print_exec()
120+
121+
multi_thread_launcher(
122+
iter_objs=func_list,
123+
apply_each_obj_func=run_func_async,
124+
)
125+
126+
if len(exception_list) == 0:
127+
return
128+
129+
for e in exception_list:
130+
print(e)
131+
132+
raise AssertionError(exception_list)

0 commit comments

Comments
 (0)