Skip to content

Commit e8785b2

Browse files
authored
Merge branch 'hect0x7:master' into master
2 parents 253f7ad + 1ed1cac commit e8785b2

21 files changed

+554
-120
lines changed

.github/release.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# .github/release.yml
2+
3+
changelog:
4+
exclude:
5+
labels:
6+
- ignore-for-release
7+
authors:
8+
- octocat
9+
categories:
10+
- title: 🏕 Features
11+
labels:
12+
- '*'
13+
exclude:
14+
labels:
15+
- dependencies
16+
- title: 👒 Dependencies
17+
labels:
18+
- dependencies
19+
- title: Other Changes
20+
labels:
21+
- "*"

.github/workflows/download_dispatch.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ on:
3131
default: ''
3232
required: false
3333

34+
PDF_OPTION:
35+
description: '是否要下载后将图片合并为pdf文件'
36+
required: false
37+
type: choice
38+
options:
39+
-
40+
- 是 | 本子维度合并pdf
41+
- 是 | 章节维度合并pdf
42+
3443
ZIP_NAME:
3544
type: string
3645
default: 本子.tar.gz
@@ -68,6 +77,7 @@ jobs:
6877
ZIP_NAME: ${{ github.event.inputs.ZIP_NAME }}
6978
UPLOAD_NAME: ${{ github.event.inputs.UPLOAD_NAME }}
7079
IMAGE_SUFFIX: ${{ github.event.inputs.IMAGE_SUFFIX }}
80+
PDF_OPTION: ${{ github.event.inputs.PDF_OPTION }}
7181

7282
# 登录相关secrets
7383
JM_USERNAME: ${{ secrets.JM_USERNAME }}
@@ -95,6 +105,11 @@ jobs:
95105
python -m pip install --upgrade pip
96106
pip install -r requirements-dev.txt
97107
108+
- name: Install img2pdf
109+
if: inputs.PDF_OPTION != '否'
110+
run: |
111+
pip install img2pdf
112+
98113
- name: 安装jmcomic(pip)
99114
if: ${{ github.ref != 'refs/heads/dev' }}
100115
run: |

.github/workflows/release_auto.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ on:
1010
jobs:
1111
release:
1212
runs-on: ubuntu-latest
13+
permissions:
14+
id-token: write
15+
contents: write
1316
if: startsWith(github.event.head_commit.message, 'v')
1417
steps:
1518
- uses: actions/checkout@v4
@@ -26,12 +29,13 @@ jobs:
2629
python .github/release.py "$commit_message"
2730
2831
- name: Create Release
29-
uses: softprops/action-gh-release@v1
32+
uses: softprops/action-gh-release@v2
3033
env:
3134
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3235
with:
3336
tag_name: ${{ steps.tb.outputs.tag }}
3437
body_path: release_body.txt
38+
generate_release_notes: true
3539

3640
- name: Build
3741
run: |
@@ -40,5 +44,5 @@ jobs:
4044
4145
- name: Release PYPI
4246
uses: pypa/gh-action-pypi-publish@release/v1
43-
with:
44-
password: ${{ secrets.PYPI_JMCOMIC }}
47+
# with:
48+
# password: ${{ secrets.PYPI_JMCOMIC }}

README.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
1-
# Python API For JMComic (禁漫天堂)
1+
<!-- 顶部标题 & 统计徽章 -->
2+
<div align="center">
3+
<h1 style="margin-top: 0" align="center">Python API for JMComic</h1>
4+
<p align="center">
5+
<strong>提供 Python API 访问禁漫天堂(网页端 & 移动端),集成 GitHub Actions 下载器🚀</strong>
6+
</p>
27

3-
本项目封装了一套可用于爬取JM的Python API.
8+
[![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=github)](https://github.com/hect0x7)
9+
[![Stars](https://img.shields.io/github/stars/hect0x7/JMComic-Crawler-Python?color=orange&label=stars&style=flat)](https://github.com/hect0x7/JMComic-Crawler-Python/stargazers)
10+
[![Forks](https://img.shields.io/github/forks/hect0x7/JMComic-Crawler-Python?color=green&label=forks&style=flat)](https://github.com/hect0x7/JMComic-Crawler-Python/forks)
11+
[![GitHub latest releases](https://img.shields.io/github/v/release/hect0x7/JMComic-Crawler-Python?color=blue&label=version)](https://github.com/hect0x7/JMComic-Crawler-Python/releases/latest)
12+
[![PyPI - Downloads](https://img.shields.io/pypi/dm/jmcomic?style=flat&color=hotpink)](https://pepy.tech/projects/jmcomic)
13+
[![Licence](https://img.shields.io/github/license/hect0x7/JMComic-Crawler-Python?color=red)](https://github.com/hect0x7/JMComic-Crawler-Python)
414

5-
你可以通过简单的几行Python代码,实现下载JM上的本子到本地,并且是处理好的图片。
15+
</div>
16+
17+
18+
19+
20+
> 本项目封装了一套可用于爬取JM的Python API.
21+
>
22+
> 你可以通过简单的几行Python代码,实现下载JM上的本子到本地,并且是处理好的图片。
23+
>
24+
> **友情提示:珍爱JM,为了减轻JM的服务器压力,请不要一次性爬取太多本子,西门🙏🙏🙏**.
625
726
[【指路】教程:使用GitHub Actions下载禁漫本子](./assets/docs/sources/tutorial/1_github_actions.md)
827

928
[【指路】教程:导出并下载你的禁漫收藏夹数据](./assets/docs/sources/tutorial/10_export_favorites.md)
1029

11-
**友情提示:珍爱JM,为了减轻JM的服务器压力,请不要一次性爬取太多本子,西门🙏🙏🙏**.
1230

1331
## 项目介绍
1432

@@ -47,11 +65,11 @@
4765

4866
### 1. 下载本子方法
4967

50-
只需要使用如下代码,就可以下载本子`JM422866`的所有章节的图片:
68+
只需要使用如下代码,就可以下载本子`JM123`的所有章节的图片:
5169

5270
```python
5371
import jmcomic # 导入此模块,需要先安装.
54-
jmcomic.download_album('422866') # 传入要下载的album的id,即可下载整个album到本地.
72+
jmcomic.download_album('123') # 传入要下载的album的id,即可下载整个album到本地.
5573
```
5674

5775
上面的 `download_album`方法还有一个参数`option`,可用于控制下载配置,配置包括禁漫域名、网络代理、图片格式转换、插件等等。
@@ -80,8 +98,8 @@ import jmcomic
8098
# 创建配置对象
8199
option = jmcomic.create_option_by_file('你的配置文件路径,例如 D:/option.yml')
82100
# 使用option对象来下载本子
83-
jmcomic.download_album(422866, option)
84-
# 等价写法: option.download_album(422866)
101+
jmcomic.download_album(123, option)
102+
# 等价写法: option.download_album(123)
85103
```
86104

87105
### 3. 使用命令行
@@ -91,10 +109,10 @@ jmcomic.download_album(422866, option)
91109
92110
示例:
93111

94-
下载本子422866的命令
112+
下载本子123的命令
95113

96114
```sh
97-
jmcomic 422866
115+
jmcomic 123
98116
```
99117
同时下载本子123, 章节456的命令
100118
```sh
@@ -142,7 +160,7 @@ jmcomic 123
142160

143161
- 不配置也能使用,十分方便
144162
- 配置可以从配置文件生成,支持多种文件格式
145-
- 配置点有:`请求域名` `客户端实现` `是否使用磁盘缓存` `同时下载的章节/图片数量` `图片格式转换` `下载路径规则` `请求元信息(headers,cookies,proxies`
163+
- 配置点有:`请求域名` `客户端实现` `是否使用磁盘缓存` `同时下载的章节/图片数量` `图片格式转换` `下载路径规则` `请求元信息(headers,cookies,proxies)` `中文繁/简转换`
146164
147165
- **可扩展性强**
148166

@@ -165,7 +183,7 @@ jmcomic 123
165183

166184
## 使用小说明
167185

168-
* Python >= 3.7
186+
* Python >= 3.7,建议3.9以上,因为jmcomic的依赖库可能会不支持3.9以下的版本。
169187
* 个人项目,文档和示例会有不及时之处,可以Issue提问
170188

171189
## 项目文件夹介绍

assets/docs/sources/option_file_syntax.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,23 @@ dir_rule:
109109
# 规则: 根目录 / 本子id / 章节序号 / 图片文件
110110
# rule: 'Bd / Aid / Pindex'
111111
# rule: 'Bd_Aid_Pindex'
112-
113112
# 默认规则是: 根目录 / 章节标题 / 图片文件
114-
rule: Bd_Ptitle
113+
rule: Bd / Ptitle
115114
# jmcomic v2.5.36 以后,支持使用python的f-string的语法组合文件夹名,下为示例
116115
# rule: Bd / Aauthor / (JM{Aid}-{Pindex})-{Pname}
117116
# {}大括号里的内容同样是写 Axxx 或 Pxxx,其他语法自行参考python f-string的语法
117+
# 另外,rule开头的Bd可忽略不写,因为程序会自动插入Bd
118+
119+
# normalize_zh: 可选。控制是否对目录/文件名中的中文进行繁简体规范化。
120+
# - None(默认):不做任何转换,保持历史行为
121+
# - zh-cn:将中文文本规范为简体
122+
# - zh-tw:将中文文本规范为繁体
123+
# 该功能依赖可选库 `zhconv`(非必需),若未安装或转换失败,程序会回退到原字符串并继续工作,不会影响下载流程。
124+
# 示例:
125+
# dir_rule:
126+
# base_dir: D:/a/b/c/
127+
# rule: Bd / Ptitle
128+
# normalize_zh: zh-cn
118129
```
119130

120131
## 3. option插件配置项
@@ -194,6 +205,15 @@ plugins:
194205
album_photo_dict:
195206
324930: 424507
196207

208+
before_album:
209+
- plugin: download_cover # 额外下载本子封面的插件
210+
kwargs:
211+
size: '_3x4' # 可选项,禁漫搜索页的封面图尺寸是 4x3,和详情页不一样,想下搜索页的封面就设置此项
212+
dir_rule: # 封面图存放路径规则,写法同上
213+
base_dir: D:/a/b/c/
214+
rule: '{Atitle}/{Aid}_cover.jpg'
215+
216+
197217
after_album:
198218
- plugin: zip # 压缩文件插件
199219
kwargs:
@@ -279,6 +299,8 @@ plugins:
279299
kwargs:
280300
pdf_dir: D:/pdf/ # pdf存放文件夹
281301
filename_rule: Pid # pdf命名规则,P代表photo, id代表使用photo.id也就是章节id
302+
encrypt: # pdf密码,可选配置项
303+
password: 123 # 密码
282304

283305
# img2pdf也支持合并整个本子,把上方的after_photo改为after_album即可。
284306
# https://github.com/hect0x7/JMComic-Crawler-Python/discussions/258

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

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ download_album(123, option)
3838
option.download_album(123)
3939
```
4040

41-
## 获取本子/章节/图片的实体类,下载图片
41+
## 获取本子/章节/图片的实体类,下载图片/封面图
4242

4343
```python
4444
from jmcomic import *
@@ -49,23 +49,26 @@ client = JmOption.default().new_jm_client()
4949
# 本子实体类
5050
album: JmAlbumDetail = client.get_album_detail('427413')
5151

52+
# 下载本子封面图,保存为 cover.png (图片后缀可指定为jpg、webp等)
53+
client.download_album_cover('427413', './cover.png')
54+
5255

5356
def fetch(photo: JmPhotoDetail):
5457
# 章节实体类
5558
photo = client.get_photo_detail(photo.photo_id, False)
5659
print(f'章节id: {photo.photo_id}')
57-
60+
5861
# 图片实体类
5962
image: JmImageDetail
6063
for image in photo:
6164
print(f'图片url: {image.img_url}')
62-
65+
6366
# 下载单个图片
6467
client.download_by_image_detail(image, './a.jpg')
6568
# 如果是已知未混淆的图片,也可以直接使用url来下载
6669
random_image_domain = JmModuleConfig.DOMAIN_IMAGE_LIST[0]
6770
client.download_image(f'https://{random_image_domain}/media/albums/416130.jpg', './a.jpg')
68-
71+
6972

7073
# 多线程发起请求
7174
multi_thread_launcher(
@@ -126,6 +129,8 @@ client = JmOption.default().new_jm_client()
126129

127130
# 分页查询,search_site就是禁漫网页上的【站内搜索】
128131
page: JmSearchPage = client.search_site(search_query='+MANA +无修正', page=1)
132+
print(f'结果总数: {page.total}, 分页大小: {page.page_size},页数: {page.page_count}')
133+
129134
# page默认的迭代方式是page.iter_id_title(),每次迭代返回 albun_id, title
130135
for album_id, title in page:
131136
print(f'[{album_id}]: {title}')
@@ -168,10 +173,10 @@ from jmcomic import *
168173

169174
option = JmOption.default()
170175
client = option.new_jm_client()
171-
client.login('用户名', '密码') # 也可以使用login插件/配置cookies
176+
client.login('用户名', '密码') # 也可以使用login插件/配置cookies
172177

173178
# 遍历全部收藏的所有页
174-
for page in cl.favorite_folder_gen(): # 如果你只想获取特定收藏夹,需要添加folder_id参数
179+
for page in client.favorite_folder_gen(): # 如果你只想获取特定收藏夹,需要添加folder_id参数
175180
# 遍历每页结果
176181
for aid, atitle in page.iter_id_title():
177182
# aid: 本子的album_id
@@ -183,9 +188,9 @@ for page in cl.favorite_folder_gen(): # 如果你只想获取特定收藏夹,
183188

184189
# 获取特定收藏夹的单页,使用favorite_folder方法
185190
page = client.favorite_folder(page=1,
186-
order_by=JmMagicConstants.ORDER_BY_LATEST,
187-
folder_id='0' # 收藏夹id
188-
)
191+
order_by=JmMagicConstants.ORDER_BY_LATEST,
192+
folder_id='0' # 收藏夹id
193+
)
189194
```
190195

191196
## 分类 / 排行榜
@@ -214,7 +219,7 @@ page: JmCategoryPage = cl.categories_filter(
214219
page=1,
215220
time=JmMagicConstants.TIME_ALL, # 时间选择全部,具体可以写什么请见JmMagicConstants
216221
category=JmMagicConstants.CATEGORY_ALL, # 分类选择全部,具体可以写什么请见JmMagicConstants
217-
order_by=JmMagicConstants.ORDER_BY_LATEST, # 按照观看数排序,具体可以写什么请见JmMagicConstants
222+
order_by=JmMagicConstants.ORDER_BY_VIEW, # 按照观看数排序,具体可以写什么请见JmMagicConstants
218223
)
219224

220225
# 月排行,底层实现也是调的categories_filter

assets/docs/sources/tutorial/4_module_custom.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ def custom_album_photo_image_detail_class():
102102
dir_rule:
103103
base_dir: ${workspace}
104104
rule: Bd_Acustom_Pcustom
105+
# 可选:对目录名进行繁/简体规范化(None/zh-cn/zh-tw),默认不启用
106+
# normalize_zh: zh-cn
105107
106108
上面的Acustom,Pcustom都是自定义字段
107109
如果你想要使用这种自定义字段,你就需要替换默认的实体类,方式如下

assets/docs/sources/tutorial/9_custom_download_dir_name.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,26 @@ D:/a/b/c/ddd/00003.webp
5858
除了Pxxx,你还可以写Axxx,表示这个章节所在的本子的属性xxx,详见本子实体类 JmAlbumDetail。
5959
6060
61+
## 1.1 简繁体统一(normalize_zh)
62+
63+
在一些源站中,同一作品或章节名称可能存在简体/繁体差异,导致在不同环境下生成重复或不一致的文件夹名。v2.6.10 引入了 `dir_rule.normalize_zh` 配置,用于可选地对目录名进行繁/简体规范化。
64+
65+
示例用法:
66+
67+
```yaml
68+
dir_rule:
69+
base_dir: D:/a/b/c/
70+
rule: Bd / Ptitle
71+
normalize_zh: zh-cn # 可选值:None(默认,不转换)/ zh-cn / zh-tw
72+
```
73+
74+
说明:
75+
76+
-`normalize_zh``zh-cn` 时,会把目录名中的中文规范为简体;为 `zh-tw` 时规范为繁体;为 `None` 或不配置时维持历史行为(不转换)。
77+
78+
- 该功能依赖可选库 `zhconv`(非必需),若未安装或转换失败,系统会回退为原始字符串并继续下载,不会导致失败。
79+
80+
6181
## 2. 自定义字段名
6282

6383
上述例子使用了title字段,如果你想自定义一个字段,然后在DirRule中使用自定义字段,该怎么做?

assets/option/option_test_api.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# GitHub Actions 测试用
22
# 移动端配置
33
dir_rule:
4+
normalize_zh: zh-cn
45
rule: Bd_Aauthor_Aid_Pindextitle
56

67
client:
@@ -25,4 +26,10 @@ plugins:
2526
- plugin: client_proxy
2627
kwargs:
2728
proxy_client_key: photo_concurrent_fetcher_proxy
28-
whitelist: [ api, ]
29+
whitelist: [ api, ]
30+
31+
- plugin: advanced_retry
32+
kwargs:
33+
retry_config:
34+
retry_rounds: 3 # 一共对域名列表重试3轮
35+
retry_domain_max_times: 5 # 当一个域名重试次数超过5次,忽略该域名,不再重试

0 commit comments

Comments
 (0)