Skip to content

Commit

Permalink
v2.5.14: 增加对禁漫本子分类、副分类的搜索支持; 压缩本子优化; 更新文档和测试. (#247)
Browse files Browse the repository at this point in the history
  • Loading branch information
hect0x7 committed Jun 10, 2024
1 parent 88ad684 commit 3c0a27b
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 70 deletions.
55 changes: 49 additions & 6 deletions assets/docs/sources/tutorial/0_demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,62 @@ page: JmCategoryPage = cl.month_ranking(1)
page: JmCategoryPage = cl.week_ranking(1)

# 循环获取分页,使用 cl.categories_filter_gen
for page in cl.categories_filter_gen(1, # 起始页码
for page in cl.categories_filter_gen(page=1, # 起始页码
# 下面是分类参数
JmMagicConstants.TIME_WEEK,
JmMagicConstants.CATEGORY_ALL,
JmMagicConstants.ORDER_BY_VIEW,
time=JmMagicConstants.TIME_WEEK,
category=JmMagicConstants.CATEGORY_ALL,
order_by=JmMagicConstants.ORDER_BY_VIEW,
):
for aid, atitle in page:
print(aid, atitle)

```

## 高级搜索(分类/副分类)

禁漫网页端的搜索除了常规条件,还支持【分类】和【副分类】的搜索。

在任一搜索页面,你会看到本子图的右上方有两个标签。左边的是【分类】,右边的是【副分类】。

下面演示代码如何编写。

* **注意!!禁漫移动端没有提供如下功能,以下代码仅对网页端生效。**

```python
# 在编写代码前,建议先熟悉禁漫网页的搜本功能,下面的代码都是对照网页编写的。
# 网页搜索示例:https://18comic.vip/search/photos/doujin/sub/CG?main_tag=0&search_query=mana&page=1&o=mr&t=a

from jmcomic import *

op = create_option_by_file('op.yml')
# 创建网页端client
html_cl = op.new_jm_client(impl='html')

# 使用站内搜索,指定【分类】和【副分类】
# 分类 = JmMagicConstants.CATEGORY_DOUJIN = 同人本
# 副分类 = JmMagicConstants.SUB_DOUJIN_CG = CG本
# 实际URL:https://18comic.vip/search/photos/doujin/sub/CG?main_tag=0&search_query=mana&page=1&o=mr&t=a
page = html_cl.search_site(search_query='mana',
category=JmMagicConstants.CATEGORY_DOUJIN,
sub_category=JmMagicConstants.SUB_DOUJIN_CG,
page=1,
)
# 打印page内容
for aid, atitle in page.iter_id_title():
print(aid, atitle)

# 循环获取分页
for page in html_cl.search_gen(search_query='mana',
category=JmMagicConstants.CATEGORY_DOUJIN,
sub_category=JmMagicConstants.SUB_DOUJIN_CG,
page=1, # 起始页码
):
# 打印page内容
for aid, atitle in page.iter_id_title():
print(aid, atitle)
```


## 手动创建Client

```python
Expand Down Expand Up @@ -184,6 +229,4 @@ cl = JmApiClient(
domain_list=JmModuleConfig.DOMAIN_API_LIST,
retry_times=1
)


```
2 changes: 1 addition & 1 deletion src/jmcomic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# 被依赖方 <--- 使用方
# config <--- entity <--- toolkit <--- client <--- option <--- downloader

__version__ = '2.5.12'
__version__ = '2.5.14'

from .api import *
from .jm_plugin import *
Expand Down
43 changes: 41 additions & 2 deletions src/jmcomic/jm_client_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ class JmHtmlClient(AbstractJmClient):

func_to_cache = ['search', 'fetch_detail_entity']

API_SEARCH = '/search/photos'
API_CATEGORY = '/albums'

def add_favorite_album(self,
album_id,
folder_id='0',
Expand Down Expand Up @@ -304,7 +307,12 @@ def search(self,
main_tag: int,
order_by: str,
time: str,
category: str,
sub_category: Optional[str],
) -> JmSearchPage:
"""
网页搜索API
"""
params = {
'main_tag': main_tag,
'search_query': search_query,
Expand All @@ -313,8 +321,10 @@ def search(self,
't': time,
}

url = self.build_search_url(self.API_SEARCH, category, sub_category)

resp = self.get_jm_html(
self.append_params_to_url('/search/photos', params),
self.append_params_to_url(url, params),
allow_redirects=True,
)

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

@classmethod
def build_search_url(cls, base: str, category: str, sub_category: Optional[str]):
"""
构建网页搜索/分类的URL
示例:
:param base: "/search/photos"
:param category CATEGORY_DOUJIN
:param sub_category SUB_DOUJIN_CG
:return "/search/photos/doujin/sub/CG"
"""
if category == JmMagicConstants.CATEGORY_ALL:
return base

if sub_category is None:
return f'{base}/{category}'
else:
return f'{base}/{category}/sub/{sub_category}'

def categories_filter(self,
page: int,
time: str,
category: str,
order_by: str,
sub_category: Optional[str] = None,
) -> JmCategoryPage:
params = {
'page': page,
'o': order_by,
't': time,
}

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

resp = self.get_jm_html(
self.append_params_to_url(url, params),
Expand Down Expand Up @@ -573,7 +603,12 @@ def search(self,
main_tag: int,
order_by: str,
time: str,
category: str,
sub_category: Optional[str],
) -> JmSearchPage:
"""
移动端暂不支持 category和sub_category
"""
params = {
'main_tag': main_tag,
'search_query': search_query,
Expand Down Expand Up @@ -603,7 +638,11 @@ def categories_filter(self,
time: str,
category: str,
order_by: str,
sub_category: Optional[str] = None,
):
"""
移动端不支持 sub_category
"""
# o: mv, mv_m, mv_w, mv_t
o = f'{order_by}_{time}' if time != JmMagicConstants.TIME_ALL else order_by

Expand Down
33 changes: 28 additions & 5 deletions src/jmcomic/jm_client_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,14 @@ def search(self,
main_tag: int,
order_by: str,
time: str,
category: str,
sub_category: Optional[str],
) -> JmSearchPage:
"""
搜索【成人A漫】
网页端与移动端的搜索有差别:
- 移动端不支持 category, sub_category参数,网页端支持全部参数
"""
raise NotImplementedError

Expand All @@ -319,55 +324,65 @@ def search_site(self,
page: int = 1,
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
time: str = JmMagicConstants.TIME_ALL,
category: str = JmMagicConstants.CATEGORY_ALL,
sub_category: Optional[str] = None,
):
"""
对应禁漫的站内搜索
"""
return self.search(search_query, page, 0, order_by, time)
return self.search(search_query, page, 0, order_by, time, category, sub_category)

def search_work(self,
search_query: str,
page: int = 1,
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
time: str = JmMagicConstants.TIME_ALL,
category: str = JmMagicConstants.CATEGORY_ALL,
sub_category: Optional[str] = None,
):
"""
搜索album的作品 work
"""
return self.search(search_query, page, 1, order_by, time)
return self.search(search_query, page, 1, order_by, time, category, sub_category)

def search_author(self,
search_query: str,
page: int = 1,
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
time: str = JmMagicConstants.TIME_ALL,
category: str = JmMagicConstants.CATEGORY_ALL,
sub_category: Optional[str] = None,
):
"""
搜索album的作者 author
"""
return self.search(search_query, page, 2, order_by, time)
return self.search(search_query, page, 2, order_by, time, category, sub_category)

def search_tag(self,
search_query: str,
page: int = 1,
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
time: str = JmMagicConstants.TIME_ALL,
category: str = JmMagicConstants.CATEGORY_ALL,
sub_category: Optional[str] = None,
):
"""
搜索album的标签 tag
"""
return self.search(search_query, page, 3, order_by, time)
return self.search(search_query, page, 3, order_by, time, category, sub_category)

def search_actor(self,
search_query: str,
page: int = 1,
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
time: str = JmMagicConstants.TIME_ALL,
category: str = JmMagicConstants.CATEGORY_ALL,
sub_category: Optional[str] = None,
):
"""
搜索album的登场角色 actor
"""
return self.search(search_query, page, 4, order_by, time)
return self.search(search_query, page, 4, order_by, time, category, sub_category)


class JmCategoryClient:
Expand All @@ -384,13 +399,15 @@ def categories_filter(self,
time: str,
category: str,
order_by: str,
sub_category: Optional[str] = None,
) -> JmCategoryPage:
"""
分类
:param page: 页码
:param time: 时间范围,默认是全部时间
:param category: 类别,默认是最新,即显示最新的禁漫本子
:param sub_category: 副分类,仅网页端有这功能
:param order_by: 排序方式,默认是观看数
"""
raise NotImplementedError
Expand Down Expand Up @@ -522,6 +539,8 @@ def search_gen(self,
page: int = 1,
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
time: str = JmMagicConstants.TIME_ALL,
category: str = JmMagicConstants.CATEGORY_ALL,
sub_category: Optional[str] = None,
) -> Generator[JmSearchPage, Dict, None]:
"""
搜索结果的生成器,支持下面这种调用方式:
Expand Down Expand Up @@ -552,6 +571,8 @@ def search_gen(self,
'main_tag': main_tag,
'order_by': order_by,
'time': time,
'category': category,
'sub_category': sub_category,
}

yield from self.do_page_iter(params, page, self.search)
Expand All @@ -561,6 +582,7 @@ def categories_filter_gen(self,
time: str = JmMagicConstants.TIME_ALL,
category: str = JmMagicConstants.CATEGORY_ALL,
order_by: str = JmMagicConstants.ORDER_BY_LATEST,
sub_category: Optional[str] = None,
) -> Generator[JmCategoryPage, Dict, None]:
"""
见 search_gen
Expand All @@ -569,6 +591,7 @@ def categories_filter_gen(self,
'time': time,
'category': category,
'order_by': order_by,
'sub_category': sub_category,
}

yield from self.do_page_iter(params, page, self.categories_filter)
Expand Down
36 changes: 32 additions & 4 deletions src/jmcomic/jm_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,29 @@ class JmMagicConstants:
CATEGORY_DOUJIN_COSPLAY = 'doujin_cosplay' # cosplay
CATEGORY_3D = '3D' # 3D
CATEGORY_ENGLISH_SITE = 'english_site' # 英文站
CATEGORY_JM_TEAM = '禁漫漢化組'

# 副分类
SUB_CHINESE = 'chinese' # 汉化,通用副分类
SUB_JAPANESE = 'japanese' # 日语,通用副分类

# 其他类(CATEGORY_ANOTHER)的副分类
SUB_ANOTHER_OTHER = 'other' # 其他漫画
SUB_ANOTHER_3D = '3d' # 3D
SUB_ANOTHER_COSPLAY = 'cosplay' # cosplay

# 同人(SUB_CHINESE)的副分类
SUB_DOUJIN_CG = 'CG' # CG
SUB_DOUJIN_CHINESE = SUB_CHINESE
SUB_DOUJIN_JAPANESE = SUB_JAPANESE

# 短篇(CATEGORY_SHORT)的副分类
SUB_SHORT_CHINESE = SUB_CHINESE
SUB_SHORT_JAPANESE = SUB_JAPANESE

# 单本(CATEGORY_SINGLE)的副分类
SUB_SINGLE_CHINESE = SUB_CHINESE
SUB_SINGLE_JAPANESE = SUB_JAPANESE
SUB_SINGLE_YOUTH = 'youth'

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

Expand Down
Loading

0 comments on commit 3c0a27b

Please sign in to comment.