Skip to content

Commit 3c0a27b

Browse files
authored
v2.5.14: 增加对禁漫本子分类、副分类的搜索支持; 压缩本子优化; 更新文档和测试. (#247)
1 parent 88ad684 commit 3c0a27b

File tree

8 files changed

+208
-70
lines changed

8 files changed

+208
-70
lines changed

assets/docs/sources/tutorial/0_demo.md

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,62 @@ page: JmCategoryPage = cl.month_ranking(1)
144144
page: JmCategoryPage = cl.week_ranking(1)
145145

146146
# 循环获取分页,使用 cl.categories_filter_gen
147-
for page in cl.categories_filter_gen(1, # 起始页码
147+
for page in cl.categories_filter_gen(page=1, # 起始页码
148148
# 下面是分类参数
149-
JmMagicConstants.TIME_WEEK,
150-
JmMagicConstants.CATEGORY_ALL,
151-
JmMagicConstants.ORDER_BY_VIEW,
149+
time=JmMagicConstants.TIME_WEEK,
150+
category=JmMagicConstants.CATEGORY_ALL,
151+
order_by=JmMagicConstants.ORDER_BY_VIEW,
152152
):
153153
for aid, atitle in page:
154154
print(aid, atitle)
155155

156156
```
157157

158+
## 高级搜索(分类/副分类)
159+
160+
禁漫网页端的搜索除了常规条件,还支持【分类】和【副分类】的搜索。
161+
162+
在任一搜索页面,你会看到本子图的右上方有两个标签。左边的是【分类】,右边的是【副分类】。
163+
164+
下面演示代码如何编写。
165+
166+
* **注意!!禁漫移动端没有提供如下功能,以下代码仅对网页端生效。**
167+
168+
```python
169+
# 在编写代码前,建议先熟悉禁漫网页的搜本功能,下面的代码都是对照网页编写的。
170+
# 网页搜索示例:https://18comic.vip/search/photos/doujin/sub/CG?main_tag=0&search_query=mana&page=1&o=mr&t=a
171+
172+
from jmcomic import *
173+
174+
op = create_option_by_file('op.yml')
175+
# 创建网页端client
176+
html_cl = op.new_jm_client(impl='html')
177+
178+
# 使用站内搜索,指定【分类】和【副分类】
179+
# 分类 = JmMagicConstants.CATEGORY_DOUJIN = 同人本
180+
# 副分类 = JmMagicConstants.SUB_DOUJIN_CG = CG本
181+
# 实际URL:https://18comic.vip/search/photos/doujin/sub/CG?main_tag=0&search_query=mana&page=1&o=mr&t=a
182+
page = html_cl.search_site(search_query='mana',
183+
category=JmMagicConstants.CATEGORY_DOUJIN,
184+
sub_category=JmMagicConstants.SUB_DOUJIN_CG,
185+
page=1,
186+
)
187+
# 打印page内容
188+
for aid, atitle in page.iter_id_title():
189+
print(aid, atitle)
190+
191+
# 循环获取分页
192+
for page in html_cl.search_gen(search_query='mana',
193+
category=JmMagicConstants.CATEGORY_DOUJIN,
194+
sub_category=JmMagicConstants.SUB_DOUJIN_CG,
195+
page=1, # 起始页码
196+
):
197+
# 打印page内容
198+
for aid, atitle in page.iter_id_title():
199+
print(aid, atitle)
200+
```
201+
202+
158203
## 手动创建Client
159204

160205
```python
@@ -184,6 +229,4 @@ cl = JmApiClient(
184229
domain_list=JmModuleConfig.DOMAIN_API_LIST,
185230
retry_times=1
186231
)
187-
188-
189232
```

src/jmcomic/__init__.py

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

5-
__version__ = '2.5.12'
5+
__version__ = '2.5.14'
66

77
from .api import *
88
from .jm_plugin import *

src/jmcomic/jm_client_impl.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ class JmHtmlClient(AbstractJmClient):
237237

238238
func_to_cache = ['search', 'fetch_detail_entity']
239239

240+
API_SEARCH = '/search/photos'
241+
API_CATEGORY = '/albums'
242+
240243
def add_favorite_album(self,
241244
album_id,
242245
folder_id='0',
@@ -304,7 +307,12 @@ def search(self,
304307
main_tag: int,
305308
order_by: str,
306309
time: str,
310+
category: str,
311+
sub_category: Optional[str],
307312
) -> JmSearchPage:
313+
"""
314+
网页搜索API
315+
"""
308316
params = {
309317
'main_tag': main_tag,
310318
'search_query': search_query,
@@ -313,8 +321,10 @@ def search(self,
313321
't': time,
314322
}
315323

324+
url = self.build_search_url(self.API_SEARCH, category, sub_category)
325+
316326
resp = self.get_jm_html(
317-
self.append_params_to_url('/search/photos', params),
327+
self.append_params_to_url(url, params),
318328
allow_redirects=True,
319329
)
320330

@@ -326,19 +336,39 @@ def search(self,
326336
else:
327337
return JmPageTool.parse_html_to_search_page(resp.text)
328338

339+
@classmethod
340+
def build_search_url(cls, base: str, category: str, sub_category: Optional[str]):
341+
"""
342+
构建网页搜索/分类的URL
343+
344+
示例:
345+
:param base: "/search/photos"
346+
:param category CATEGORY_DOUJIN
347+
:param sub_category SUB_DOUJIN_CG
348+
:return "/search/photos/doujin/sub/CG"
349+
"""
350+
if category == JmMagicConstants.CATEGORY_ALL:
351+
return base
352+
353+
if sub_category is None:
354+
return f'{base}/{category}'
355+
else:
356+
return f'{base}/{category}/sub/{sub_category}'
357+
329358
def categories_filter(self,
330359
page: int,
331360
time: str,
332361
category: str,
333362
order_by: str,
363+
sub_category: Optional[str] = None,
334364
) -> JmCategoryPage:
335365
params = {
336366
'page': page,
337367
'o': order_by,
338368
't': time,
339369
}
340370

341-
url = f'/albums/' + (category if category != JmMagicConstants.CATEGORY_ALL else '')
371+
url = self.build_search_url(self.API_CATEGORY, category, sub_category)
342372

343373
resp = self.get_jm_html(
344374
self.append_params_to_url(url, params),
@@ -573,7 +603,12 @@ def search(self,
573603
main_tag: int,
574604
order_by: str,
575605
time: str,
606+
category: str,
607+
sub_category: Optional[str],
576608
) -> JmSearchPage:
609+
"""
610+
移动端暂不支持 category和sub_category
611+
"""
577612
params = {
578613
'main_tag': main_tag,
579614
'search_query': search_query,
@@ -603,7 +638,11 @@ def categories_filter(self,
603638
time: str,
604639
category: str,
605640
order_by: str,
641+
sub_category: Optional[str] = None,
606642
):
643+
"""
644+
移动端不支持 sub_category
645+
"""
607646
# o: mv, mv_m, mv_w, mv_t
608647
o = f'{order_by}_{time}' if time != JmMagicConstants.TIME_ALL else order_by
609648

src/jmcomic/jm_client_interface.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,14 @@ def search(self,
308308
main_tag: int,
309309
order_by: str,
310310
time: str,
311+
category: str,
312+
sub_category: Optional[str],
311313
) -> JmSearchPage:
312314
"""
313315
搜索【成人A漫】
316+
网页端与移动端的搜索有差别:
317+
318+
- 移动端不支持 category, sub_category参数,网页端支持全部参数
314319
"""
315320
raise NotImplementedError
316321

@@ -319,55 +324,65 @@ def search_site(self,
319324
page: int = 1,
320325
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
321326
time: str = JmMagicConstants.TIME_ALL,
327+
category: str = JmMagicConstants.CATEGORY_ALL,
328+
sub_category: Optional[str] = None,
322329
):
323330
"""
324331
对应禁漫的站内搜索
325332
"""
326-
return self.search(search_query, page, 0, order_by, time)
333+
return self.search(search_query, page, 0, order_by, time, category, sub_category)
327334

328335
def search_work(self,
329336
search_query: str,
330337
page: int = 1,
331338
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
332339
time: str = JmMagicConstants.TIME_ALL,
340+
category: str = JmMagicConstants.CATEGORY_ALL,
341+
sub_category: Optional[str] = None,
333342
):
334343
"""
335344
搜索album的作品 work
336345
"""
337-
return self.search(search_query, page, 1, order_by, time)
346+
return self.search(search_query, page, 1, order_by, time, category, sub_category)
338347

339348
def search_author(self,
340349
search_query: str,
341350
page: int = 1,
342351
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
343352
time: str = JmMagicConstants.TIME_ALL,
353+
category: str = JmMagicConstants.CATEGORY_ALL,
354+
sub_category: Optional[str] = None,
344355
):
345356
"""
346357
搜索album的作者 author
347358
"""
348-
return self.search(search_query, page, 2, order_by, time)
359+
return self.search(search_query, page, 2, order_by, time, category, sub_category)
349360

350361
def search_tag(self,
351362
search_query: str,
352363
page: int = 1,
353364
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
354365
time: str = JmMagicConstants.TIME_ALL,
366+
category: str = JmMagicConstants.CATEGORY_ALL,
367+
sub_category: Optional[str] = None,
355368
):
356369
"""
357370
搜索album的标签 tag
358371
"""
359-
return self.search(search_query, page, 3, order_by, time)
372+
return self.search(search_query, page, 3, order_by, time, category, sub_category)
360373

361374
def search_actor(self,
362375
search_query: str,
363376
page: int = 1,
364377
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
365378
time: str = JmMagicConstants.TIME_ALL,
379+
category: str = JmMagicConstants.CATEGORY_ALL,
380+
sub_category: Optional[str] = None,
366381
):
367382
"""
368383
搜索album的登场角色 actor
369384
"""
370-
return self.search(search_query, page, 4, order_by, time)
385+
return self.search(search_query, page, 4, order_by, time, category, sub_category)
371386

372387

373388
class JmCategoryClient:
@@ -384,13 +399,15 @@ def categories_filter(self,
384399
time: str,
385400
category: str,
386401
order_by: str,
402+
sub_category: Optional[str] = None,
387403
) -> JmCategoryPage:
388404
"""
389405
分类
390406
391407
:param page: 页码
392408
:param time: 时间范围,默认是全部时间
393409
:param category: 类别,默认是最新,即显示最新的禁漫本子
410+
:param sub_category: 副分类,仅网页端有这功能
394411
:param order_by: 排序方式,默认是观看数
395412
"""
396413
raise NotImplementedError
@@ -522,6 +539,8 @@ def search_gen(self,
522539
page: int = 1,
523540
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
524541
time: str = JmMagicConstants.TIME_ALL,
542+
category: str = JmMagicConstants.CATEGORY_ALL,
543+
sub_category: Optional[str] = None,
525544
) -> Generator[JmSearchPage, Dict, None]:
526545
"""
527546
搜索结果的生成器,支持下面这种调用方式:
@@ -552,6 +571,8 @@ def search_gen(self,
552571
'main_tag': main_tag,
553572
'order_by': order_by,
554573
'time': time,
574+
'category': category,
575+
'sub_category': sub_category,
555576
}
556577

557578
yield from self.do_page_iter(params, page, self.search)
@@ -561,6 +582,7 @@ def categories_filter_gen(self,
561582
time: str = JmMagicConstants.TIME_ALL,
562583
category: str = JmMagicConstants.CATEGORY_ALL,
563584
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
585+
sub_category: Optional[str] = None,
564586
) -> Generator[JmCategoryPage, Dict, None]:
565587
"""
566588
见 search_gen
@@ -569,6 +591,7 @@ def categories_filter_gen(self,
569591
'time': time,
570592
'category': category,
571593
'order_by': order_by,
594+
'sub_category': sub_category,
572595
}
573596

574597
yield from self.do_page_iter(params, page, self.categories_filter)

src/jmcomic/jm_config.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,29 @@ class JmMagicConstants:
3535
CATEGORY_DOUJIN_COSPLAY = 'doujin_cosplay' # cosplay
3636
CATEGORY_3D = '3D' # 3D
3737
CATEGORY_ENGLISH_SITE = 'english_site' # 英文站
38-
CATEGORY_JM_TEAM = '禁漫漢化組'
38+
39+
# 副分类
40+
SUB_CHINESE = 'chinese' # 汉化,通用副分类
41+
SUB_JAPANESE = 'japanese' # 日语,通用副分类
42+
43+
# 其他类(CATEGORY_ANOTHER)的副分类
44+
SUB_ANOTHER_OTHER = 'other' # 其他漫画
45+
SUB_ANOTHER_3D = '3d' # 3D
46+
SUB_ANOTHER_COSPLAY = 'cosplay' # cosplay
47+
48+
# 同人(SUB_CHINESE)的副分类
49+
SUB_DOUJIN_CG = 'CG' # CG
50+
SUB_DOUJIN_CHINESE = SUB_CHINESE
51+
SUB_DOUJIN_JAPANESE = SUB_JAPANESE
52+
53+
# 短篇(CATEGORY_SHORT)的副分类
54+
SUB_SHORT_CHINESE = SUB_CHINESE
55+
SUB_SHORT_JAPANESE = SUB_JAPANESE
56+
57+
# 单本(CATEGORY_SINGLE)的副分类
58+
SUB_SINGLE_CHINESE = SUB_CHINESE
59+
SUB_SINGLE_JAPANESE = SUB_JAPANESE
60+
SUB_SINGLE_YOUTH = 'youth'
3961

4062
# 分页大小
4163
PAGE_SIZE_SEARCH = 80
@@ -53,7 +75,7 @@ class JmMagicConstants:
5375
APP_TOKEN_SECRET = '18comicAPP'
5476
APP_TOKEN_SECRET_2 = '18comicAPPContent'
5577
APP_DATA_SECRET = '185Hcomic3PAPP7R'
56-
APP_VERSION = '1.6.7'
78+
APP_VERSION = '1.7.0'
5779
APP_HEADERS_TEMPLATE = {
5880
'Accept-Encoding': 'gzip',
5981
'user-agent': 'Mozilla/5.0 (Linux; Android 9; V1938CT Build/PQ3A.190705.11211812; wv) AppleWebKit/537.36 (KHTML, '
@@ -65,14 +87,20 @@ class JmMagicConstants:
6587
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,'
6688
'application/signed-exchange;v=b3;q=0.7',
6789
'accept-language': 'zh-CN,zh;q=0.9',
68-
'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"',
90+
'cache-control': 'no-cache',
91+
'dnt': '1',
92+
'pragma': 'no-cache',
93+
'priority': 'u=0, i',
94+
'referer': 'https://18comic.vip/',
95+
'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
6996
'sec-ch-ua-mobile': '?0',
7097
'sec-ch-ua-platform': '"Windows"',
7198
'sec-fetch-dest': 'document',
7299
'sec-fetch-mode': 'navigate',
73100
'sec-fetch-site': 'none',
74101
'sec-fetch-user': '?1',
75-
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 '
102+
'upgrade-insecure-requests': '1',
103+
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 '
76104
'Safari/537.36',
77105
}
78106

0 commit comments

Comments
 (0)