mirror of
https://github.com/JoeanAmier/XHS-Downloader.git
synced 2025-12-26 04:48:05 +08:00
feat: 支持按作者归档保存作品文件
BREAKING CHANGE: 新增配置文件参数:account_archive Closes #226 Closes #229
This commit is contained in:
parent
ea63059dbf
commit
c2fa98bb51
11
README.md
11
README.md
@ -214,6 +214,7 @@ async def example():
|
||||
"""通过代码设置参数,适合二次开发"""
|
||||
# 示例链接
|
||||
demo_link = "https://www.xiaohongshu.com/explore/XXX?xsec_token=XXX"
|
||||
|
||||
# 实例对象
|
||||
work_path = "D:\\" # 作品数据/文件保存根路径,默认值:项目根路径
|
||||
folder_name = "Download" # 作品文件储存文件夹名称(自动创建),默认值:Download
|
||||
@ -232,9 +233,12 @@ async def example():
|
||||
live_download = False # 图文动图文件下载开关
|
||||
download_record = True # 是否记录下载成功的作品 ID
|
||||
language = "zh_CN" # 设置程序提示语言
|
||||
account_archive = True # 是否将每个作者的作品存至单独的文件夹
|
||||
read_cookie = None # 读取浏览器 Cookie,支持设置浏览器名称(字符串)或者浏览器序号(整数),设置为 None 代表不读取
|
||||
|
||||
# async with XHS() as xhs:
|
||||
# pass # 使用默认参数
|
||||
|
||||
async with XHS(
|
||||
work_path=work_path,
|
||||
folder_name=folder_name,
|
||||
@ -254,6 +258,7 @@ async def example():
|
||||
download_record=download_record,
|
||||
language=language,
|
||||
read_cookie=read_cookie,
|
||||
account_archive=account_archive,
|
||||
) as xhs: # 使用自定义参数
|
||||
download = True # 是否下载作品文件,默认值:False
|
||||
# 返回作品详细信息,包括下载地址
|
||||
@ -376,6 +381,12 @@ async def example():
|
||||
<td align="center">true</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">account_archive</td>
|
||||
<td align="center">bool</td>
|
||||
<td align="center">是否将每个作者的作品储存至单独的文件夹;文件夹名称为作者昵称或者作者 ID</td>
|
||||
<td align="center">false</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">language</td>
|
||||
<td align="center">str</td>
|
||||
<td align="center">设置程序语言,目前支持:<code>zh_CN</code>、<code>en_US</code></td>
|
||||
|
||||
11
README_EN.md
11
README_EN.md
@ -218,6 +218,7 @@ async def example():
|
||||
"""通过代码设置参数,适合二次开发"""
|
||||
# 示例链接
|
||||
demo_link = "https://www.xiaohongshu.com/explore/XXX?xsec_token=XXX"
|
||||
|
||||
# 实例对象
|
||||
work_path = "D:\\" # 作品数据/文件保存根路径,默认值:项目根路径
|
||||
folder_name = "Download" # 作品文件储存文件夹名称(自动创建),默认值:Download
|
||||
@ -236,9 +237,12 @@ async def example():
|
||||
live_download = False # 图文动图文件下载开关
|
||||
download_record = True # 是否记录下载成功的作品 ID
|
||||
language = "zh_CN" # 设置程序提示语言
|
||||
account_archive = True # 是否将每个作者的作品存至单独的文件夹
|
||||
read_cookie = None # 读取浏览器 Cookie,支持设置浏览器名称(字符串)或者浏览器序号(整数),设置为 None 代表不读取
|
||||
|
||||
# async with XHS() as xhs:
|
||||
# pass # 使用默认参数
|
||||
|
||||
async with XHS(
|
||||
work_path=work_path,
|
||||
folder_name=folder_name,
|
||||
@ -258,6 +262,7 @@ async def example():
|
||||
download_record=download_record,
|
||||
language=language,
|
||||
read_cookie=read_cookie,
|
||||
account_archive=account_archive,
|
||||
) as xhs: # 使用自定义参数
|
||||
download = True # 是否下载作品文件,默认值:False
|
||||
# 返回作品详细信息,包括下载地址
|
||||
@ -380,6 +385,12 @@ async def example():
|
||||
<td align="center">true</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">account_archive</td>
|
||||
<td align="center">bool</td>
|
||||
<td align="center">Whether to save each author's works into a separate folder; the folder name will be the author's nickname or author ID</td>
|
||||
<td align="center">false</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">language</td>
|
||||
<td align="center">str</td>
|
||||
<td align="center">Set program language. Currently supported: <code>zh_CN</code>, <code>en_US</code></td>
|
||||
|
||||
52
example.py
52
example.py
@ -28,30 +28,32 @@ async def example():
|
||||
live_download = False # 图文动图文件下载开关
|
||||
download_record = True # 是否记录下载成功的作品 ID
|
||||
language = "zh_CN" # 设置程序提示语言
|
||||
account_archive = True # 是否将每个作者的作品存至单独的文件夹
|
||||
read_cookie = None # 读取浏览器 Cookie,支持设置浏览器名称(字符串)或者浏览器序号(整数),设置为 None 代表不读取
|
||||
|
||||
# async with XHS() as xhs:
|
||||
# pass # 使用默认参数
|
||||
|
||||
async with XHS(
|
||||
work_path=work_path,
|
||||
folder_name=folder_name,
|
||||
name_format=name_format,
|
||||
user_agent=user_agent,
|
||||
cookie=cookie,
|
||||
proxy=proxy,
|
||||
timeout=timeout,
|
||||
chunk=chunk,
|
||||
max_retry=max_retry,
|
||||
record_data=record_data,
|
||||
image_format=image_format,
|
||||
folder_mode=folder_mode,
|
||||
image_download=image_download,
|
||||
video_download=video_download,
|
||||
live_download=live_download,
|
||||
download_record=download_record,
|
||||
language=language,
|
||||
read_cookie=read_cookie,
|
||||
work_path=work_path,
|
||||
folder_name=folder_name,
|
||||
name_format=name_format,
|
||||
user_agent=user_agent,
|
||||
cookie=cookie,
|
||||
proxy=proxy,
|
||||
timeout=timeout,
|
||||
chunk=chunk,
|
||||
max_retry=max_retry,
|
||||
record_data=record_data,
|
||||
image_format=image_format,
|
||||
folder_mode=folder_mode,
|
||||
image_download=image_download,
|
||||
video_download=video_download,
|
||||
live_download=live_download,
|
||||
download_record=download_record,
|
||||
language=language,
|
||||
read_cookie=read_cookie,
|
||||
account_archive=account_archive,
|
||||
) as xhs: # 使用自定义参数
|
||||
download = True # 是否下载作品文件,默认值:False
|
||||
# 返回作品详细信息,包括下载地址
|
||||
@ -62,13 +64,13 @@ async def example():
|
||||
async def test():
|
||||
url = ""
|
||||
async with XHS(
|
||||
download_record=False,
|
||||
# image_format="PNG",
|
||||
# image_format="WEBP",
|
||||
# image_format="JPEG",
|
||||
# image_format="HEIC",
|
||||
# image_format="AVIF",
|
||||
# image_format="AUTO",
|
||||
download_record=False,
|
||||
# image_format="PNG",
|
||||
# image_format="WEBP",
|
||||
# image_format="JPEG",
|
||||
# image_format="HEIC",
|
||||
# image_format="AVIF",
|
||||
# image_format="AUTO",
|
||||
) as xhs:
|
||||
print(
|
||||
await xhs.extract(
|
||||
|
||||
@ -24,8 +24,8 @@ class Setting(Screen):
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
data: dict,
|
||||
self,
|
||||
data: dict,
|
||||
):
|
||||
super().__init__()
|
||||
self.data = data
|
||||
@ -129,7 +129,7 @@ class Setting(Screen):
|
||||
value=self.data["record_data"],
|
||||
),
|
||||
Checkbox(
|
||||
_("作品文件夹归档模式"),
|
||||
_("作品归档保存模式"),
|
||||
id="folder_mode",
|
||||
value=self.data["folder_mode"],
|
||||
),
|
||||
@ -157,6 +157,11 @@ class Setting(Screen):
|
||||
id="download_record",
|
||||
value=self.data["download_record"],
|
||||
),
|
||||
Checkbox(
|
||||
_("作者归档保存模式"),
|
||||
id="account_archive",
|
||||
value=self.data["account_archive"],
|
||||
),
|
||||
classes="horizontal-layout",
|
||||
),
|
||||
Container(
|
||||
@ -229,6 +234,7 @@ class Setting(Screen):
|
||||
"video_download": self.query_one("#video_download").value,
|
||||
"live_download": self.query_one("#live_download").value,
|
||||
"download_record": self.query_one("#download_record").value,
|
||||
"account_archive": self.query_one("#account_archive").value,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -100,6 +100,7 @@ class XHS:
|
||||
live_download=False,
|
||||
folder_mode=False,
|
||||
download_record=True,
|
||||
account_archive=False,
|
||||
language="zh_CN",
|
||||
read_cookie: int | str = None,
|
||||
_print: bool = True,
|
||||
@ -125,6 +126,7 @@ class XHS:
|
||||
live_download,
|
||||
download_record,
|
||||
folder_mode,
|
||||
account_archive,
|
||||
_print,
|
||||
)
|
||||
self.html = Html(self.manager)
|
||||
@ -170,6 +172,7 @@ class XHS:
|
||||
u,
|
||||
container["动图地址"],
|
||||
index,
|
||||
self.CLEANER.filter_name(container["作者昵称"]) or container["作者ID"],
|
||||
name,
|
||||
container["作品类型"],
|
||||
log,
|
||||
|
||||
@ -63,23 +63,25 @@ class Download:
|
||||
self.image_download = manager.image_download
|
||||
self.video_download = manager.video_download
|
||||
self.live_download = manager.live_download
|
||||
self.account_archive = manager.account_archive
|
||||
|
||||
async def run(
|
||||
self,
|
||||
urls: list,
|
||||
lives: list,
|
||||
index: list | tuple | None,
|
||||
name: str,
|
||||
nickname: str,
|
||||
filename: str,
|
||||
type_: str,
|
||||
log,
|
||||
bar,
|
||||
) -> tuple[Path, list[Any]]:
|
||||
path = self.__generate_path(name)
|
||||
path = self.__generate_path(nickname, filename)
|
||||
if type_ == _("视频"):
|
||||
tasks = self.__ready_download_video(
|
||||
urls,
|
||||
path,
|
||||
name,
|
||||
filename,
|
||||
log,
|
||||
)
|
||||
elif type_ == _("图文"):
|
||||
@ -88,7 +90,7 @@ class Download:
|
||||
lives,
|
||||
index,
|
||||
path,
|
||||
name,
|
||||
filename,
|
||||
log,
|
||||
)
|
||||
else:
|
||||
@ -107,8 +109,13 @@ class Download:
|
||||
tasks = await gather(*tasks)
|
||||
return path, tasks
|
||||
|
||||
def __generate_path(self, name: str):
|
||||
path = self.manager.archive(self.folder, name, self.folder_mode)
|
||||
def __generate_path(self, nickname:str, filename: str):
|
||||
if self.account_archive:
|
||||
folder = self.folder.joinpath(nickname)
|
||||
folder.mkdir(exist_ok=True)
|
||||
else:
|
||||
folder = self.folder
|
||||
path = self.manager.archive(folder, filename, self.folder_mode)
|
||||
path.mkdir(exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
@ -65,6 +65,7 @@ class Manager:
|
||||
live_download: bool,
|
||||
download_record: bool,
|
||||
folder_mode: bool,
|
||||
account_archive:bool,
|
||||
_print: bool,
|
||||
):
|
||||
self.root = root
|
||||
@ -115,6 +116,7 @@ class Manager:
|
||||
self.image_download = self.check_bool(image_download, True)
|
||||
self.video_download = self.check_bool(video_download, True)
|
||||
self.live_download = self.check_bool(live_download, True)
|
||||
self.account_archive = self.check_bool(account_archive, False)
|
||||
|
||||
def __check_path(self, path: str) -> Path:
|
||||
if not path:
|
||||
|
||||
@ -27,6 +27,7 @@ class Settings:
|
||||
"live_download": False,
|
||||
"folder_mode": False,
|
||||
"download_record": True,
|
||||
"account_archive": False,
|
||||
"language": "zh_CN",
|
||||
}
|
||||
encode = "UTF-8-SIG" if system() == "Windows" else "UTF-8"
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
**项目更新内容:**
|
||||
|
||||
1. 增加对 `JPEG` 和 `HEIC` 图片格式的支持
|
||||
2. 优化 `headers` 处理逻辑
|
||||
3. 支持 `SOCKS` 代理
|
||||
2. 支持按作者归档保存作品文件
|
||||
3. 优化 `headers` 处理逻辑
|
||||
4. 支持 `SOCKS` 代理
|
||||
|
||||
**注意:**
|
||||
|
||||
<p><strong>配置文件新增参数 <code>account_archive</code>,旧版本更新需要手动添加配置内容:<code>"account_archive": false</code>;或者直接删除旧版配置文件后再运行程序!</strong></p>
|
||||
|
||||
*****
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user