Skip to content

Commit

Permalink
Merge pull request #8 from shing-yu/develop
Browse files Browse the repository at this point in the history
feat: v2.8.7
  • Loading branch information
shing-yu authored Jan 17, 2024
2 parents 9bc4942 + 7abd385 commit 8cf4ffc
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 208 deletions.
16 changes: 12 additions & 4 deletions EULA.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
# 最终用户许可协议(EULA)
版权所有 © 2023 星隅(shingyu)
版权所有 © 2023-2024 星隅(shingyu)
最后更新日期:
2023年11月23日
2024年1月11日

## 1. 引言

本许可协议(以下简称“协议”)是您(以下简称“用户”)与本爬虫程序(以下简称“软件”)之间的法律协议。一旦安装、复制或以其他方式使用本软件,即表示同意接受本协议各项条件的约束。如果用户不同意本协议的条件,用户有权选择不使用本软件。

## 2. 许可授权

本软件是基于GPLv3开源的,用户可以在GPLv3许可证的约束下,对本软件进行复制、分发和修改。如果用户违反GPLv3许可证的的任何条款,将视为违反本协议。
2.1 本软件是基于GPLv3开源的,用户可以在GPLv3许可证的约束下,对本软件进行复制、分发和修改。如果用户违反GPLv3许可证的的任何条款,将视为违反本协议。

2.2 附加条款 (依据 GPLv3 开源许可证第七条):

2.2.1 代下载服务:如果用户使用本软件提供代下载服务(无论有偿无偿),用户必须在服务开始前明确告知服务接收方本软件的开源地址,以及本软件遵循的 GPLv3 许可证和本附加条款。用户还必须保证服务接收方能够自由地获取、修改和再分发本软件的源代码,不受任何额外的限制或条件。(依据 GPLv3, 7(c))

2.2.2 版权声明:用户不得移除该程序所显示的及产生的文件内的版权声明. (依据 GPLv3, 7(b))

2.2.3 基于此程序开发的程序,如果公开发布,为保护API稳定性,不得使请求频率超过0.25秒一次。 (依据 GPLv3, 7)

## 3. 责任免除

Expand Down Expand Up @@ -51,4 +59,4 @@

## 9. 最终解释权

本协议的最终解释权归软件的作者或版权所有者所有。
本协议的最终解释权归软件的作者或版权所有者所有。
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**此项目是[fanqie-novel-download](https://github.com/xing-yv/fanqie-novel-download)的变体项目。**
它提供了一个简单的命令行界面,可以输入小说目录页面的URL并选择保存下载内容的编码格式。
本程序灵感即api均来源于ibxff所作用户脚本(MIT),你可以在[此处](https://greasyfork.org/zh-CN/scripts/479460)获取。
用户QQ4群(闲聊):854953755
QQ: 外1群:149050832 外2群:667146297 频道:https://pd.qq.com/s/hd0ciuont
感谢贡献(赞助)者们对本项目的支持,你可以在[此处](https://github.com/xing-yv/7mao-novel-downloader/blob/main/CONTRIBUTORS.md)获取贡献和赞助者名单。

## 特点
Expand Down Expand Up @@ -69,12 +69,6 @@
pip install -r requirements.txt
```

或(全部版本)

```shell
pip install -r requirements-all.txt
```

## 许可证

为保护此程序不被用于不良商业行为,
Expand Down Expand Up @@ -103,6 +97,10 @@ pip install -r requirements-all.txt

如果您遇到问题或有改进建议,请将其提交到此项目的[GitHub issues](https://github.com/xing-yv/7mao-novel-downloader/issues)页面。

## Star趋势

![Stars](https://api.star-history.com/svg?repos=shing-yu/7mao-novel-downloader&type=Date)

## 赞助

如果您想要支持我的开发,欢迎赞助,感谢您的支持!
Expand Down
13 changes: 0 additions & 13 deletions requirements-all.txt

This file was deleted.

91 changes: 80 additions & 11 deletions src/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def print_usage():
您可以使用此程序提供有偿代下载服务,但在提供服务的同时,必须向服务的接收者提供此程序的获取方式,
以便他们可以自由使用、修改和分发该软件,同时也必须遵守GPLv3协议的所有其他规定。
用户QQ4群(闲聊):854953755
QQ: 外1群:149050832 外2群:667146297
如果想要指定开始下载的章节,请在输入目录页链接时按Ctrl+C。
免责声明:
Expand Down Expand Up @@ -121,7 +121,7 @@ def start():
elif choice == '4':
mode = 1
clear_screen()
print("您已进入Debug模式,将会给出更多调试信息\n")
print("您已进入Debug模式,将会给出更多选项和调试信息\n")
break
elif choice == '5':
mode = 4
Expand Down Expand Up @@ -167,7 +167,7 @@ def start():
clear_screen()
contributors_url = 'https://gitee.com/xingyv1024/7mao-novel-downloader/raw/main/CONTRIBUTORS.md'
try:
contributors = requests.get(contributors_url)
contributors = requests.get(contributors_url, timeout=5)

# 检查响应状态码
if contributors.status_code == 200:
Expand Down Expand Up @@ -260,7 +260,7 @@ def get_parameter(retry):
# 不是则让用户输入小说目录页的链接
while True:
try:
page_url = input("请输入目录页链接\n")
page_url = input("请输入目录页或手机端分享链接(或书籍ID)\n")

# 预留七猫小说判断
# if "qimao" in page_url:
Expand All @@ -270,12 +270,26 @@ def get_parameter(retry):
# mode = 3
# elif "qimao" in page_url:

# 检查 url 是否是小说目录页面
if "/shuku/" not in page_url:
print("请输入正确的小说目录页面链接")
else:
book_id = re.search(r"/(\d+)", page_url).group(1)
break # 如果是正确的链接,则退出循环
# 检查 url 类型
try:
if page_url.isdigit():
book_id = page_url
page_url = "https://www.qimao.com/shuku/" + book_id + "/"
break

elif "www.qimao.com/shuku/" in page_url:
book_id = re.search(r"www.qimao.com/shuku/(\d+)", page_url).group(1)
page_url = "https://www.qimao.com/shuku/" + book_id + "/"
break # 如果是正确的链接,则退出循环

elif "app-share.wtzw.com" in page_url:
book_id = re.search(r"article-detail/(\d+)", page_url).group(1)
page_url = "https://www.qimao.com/shuku/" + book_id + "/"
break
else:
print(Fore.YELLOW + Style.BRIGHT + "请输入正确的小说目录页面或手机端分享链接(或书籍ID)")
except AttributeError:
print(Fore.YELLOW + Style.BRIGHT + "请输入正确的小说目录页面或手机端分享链接(或书籍ID)")
# 当用户按下Ctrl+C是,可以自定义起始章节id
except KeyboardInterrupt:
while True:
Expand All @@ -295,7 +309,7 @@ def get_parameter(retry):
while True:
if mode == 4:
break
txt_encoding_num = input("请输入保存文件所使用的编码(默认:1):1 -> utf-8 | 2 -> gb2312\n")
txt_encoding_num = input("请输入保存文件所使用的编码(默认:1):1 -> utf-8 | 2 -> gb2312 | 3-> 搜索编码\n")

if not txt_encoding_num:
txt_encoding_num = '1'
Expand All @@ -307,6 +321,9 @@ def get_parameter(retry):
elif txt_encoding_num == '2':
txt_encoding = 'gb2312'
break
elif txt_encoding_num == '3':
txt_encoding = get_more_encoding()
break
else:
print("输入无效,请重新输入。")

Expand Down Expand Up @@ -347,6 +364,58 @@ def get_parameter(retry):
perform_user_mode_action()


def get_more_encoding():
encodings = [
"utf-8", "ascii", "latin-1", "iso-8859-1", "utf-16",
"utf-16-le", "utf-16-be", "utf-32", "utf-32-le", "utf-32-be",
"cp1252", "cp437", "cp850", "cp866", "cp932",
"cp949", "cp950", "koi8-r", "koi8-u", "macroman",
"macintosh", "gb2312", "gbk", "gb18030", "big5",
"big5hkscs", "shift_jis", "euc_jp", "euc_kr", "iso2022_jp",
"iso2022_jp_1", "iso2022_jp_2", "iso2022_jp_2004", "iso2022_jp_3", "iso2022_jp_ext",
"shift_jis_2004", "shift_jisx0213", "euc_jis_2004", "euc_jisx0213", "latin_1",
"iso8859_2", "iso8859_3", "iso8859_4", "iso8859_5", "iso8859_6",
"iso8859_7", "iso8859_8", "iso8859_9", "iso8859_10", "iso8859_13",
"iso8859_14", "iso8859_15", "iso8859_16", "cp500", "cp720",
"cp737", "cp775", "cp852", "cp855", "cp857",
"cp858", "cp860", "cp861", "cp862", "cp863",
"cp864", "cp865", "cp869", "cp874", "cp875",
"cp1006", "cp1026", "cp1140", "cp1250", "cp1251",
"cp1253", "cp1254", "cp1255", "cp1256", "cp1257",
"cp1258", "cp65001", "hz", "iso2022_jp_2004", "iso2022_kr",
"iso8859_11", "iso8859_16", "johab", "ptcp154", "utf_7",
"utf_8_sig"
]

while True:
query = input("请输入你想要搜索的编码:")
query = query.lower()
import difflib
# 使用difflib库的get_close_matches方法找到相似的编码
similar_encodings = difflib.get_close_matches(query, encodings)

print("以下是与你的搜索内容相似的编码:")
for i, encoding in enumerate(similar_encodings):
print(f"{i + 1}. {encoding}")

while True:
choice_ = input("请选择一个编码, 输入r以重新搜索:")
if choice_ == "r":
clear_screen()
break
elif choice_.isdigit():
choice = int(choice_)
if choice > len(similar_encodings):
print("输入无效,请重新输入。")
continue
chosen_encoding = similar_encodings[choice - 1]
print(f"你选择的编码是:{chosen_encoding}")
return chosen_encoding
else:
print("输入无效,请重新输入。")
continue


def perform_user_mode_action():
global return_info
# 判断用户处于什么模式
Expand Down
2 changes: 1 addition & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import function as f
from sys import exit

version = "v2.8.6-post.1"
version = "v2.8.7"

# 检查EULA
f.check_eula()
Expand Down
53 changes: 52 additions & 1 deletion src/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
from Crypto.Util.Padding import unpad
from base64 import b64decode
import requests
from tqdm import tqdm
import hashlib
from colorama import Fore, Style, init

init(autoreset=True)


# 替换非法字符
Expand Down Expand Up @@ -76,7 +81,53 @@ def decrypt_qimao(content):
return fntxt


def get_qimao(book_id, chapter_id, sign):
def get_api(book_id, chapter):
# 获取章节标题
chapter_title = chapter.find("span", {"class": "txt"}).get_text().strip()
chapter_title = rename(chapter_title)

# 获取章节网址
chapter_url = chapter.find("a")["href"]

# 获取章节 id
chapter_id = re.search(r"/(\d+)-(\d+)/", chapter_url).group(2)

# 尝试获取章节内容
chapter_content = None
retry_count = 1
while retry_count < 4: # 设置最大重试次数
try:
param_string = f"chapterId={chapter_id}id={book_id}{sign_key}"
sign = hashlib.md5(param_string.encode()).hexdigest()
encrypted_content = send_request(book_id, chapter_id, sign)
except Exception as e:

tqdm.write(Fore.RED + Style.BRIGHT + f"发生异常: {e}")
if retry_count == 1:
tqdm.write(f"{chapter_title} 获取失败,正在尝试重试...")
tqdm.write(f"第 ({retry_count}/3) 次重试获取章节内容")
retry_count += 1 # 否则重试
continue

if "data" in encrypted_content and "content" in encrypted_content["data"]:
encrypted_content = encrypted_content['data']['content']
chapter_content = decrypt_qimao(encrypted_content)
chapter_content = re.sub('<br>', '\n', chapter_content)
break # 如果成功获取章节内容,跳出重试循环
else:
if retry_count == 1:
tqdm.write(f"{chapter_title} 获取失败,正在尝试重试...")
tqdm.write(f"第 ({retry_count}/3) 次重试获取章节内容")
retry_count += 1 # 否则重试

if retry_count == 4:
tqdm.write(f"无法获取章节内容: {chapter_title},跳过。")
return # 重试次数过多后,跳过当前章节

return chapter_title, chapter_content, chapter_id


def send_request(book_id, chapter_id, sign):
headers = {
"AUTHORIZATION": "",
"app-version": "51110",
Expand Down
48 changes: 7 additions & 41 deletions src/qimao_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,54 +130,20 @@ def download_novels(url, encoding, path_choice, folder_path, data_folder):
# 遍历每个章节链接
for chapter in tqdm(chapters):
time.sleep(1)
# 获取章节标题
chapter_title = chapter.find("span", {"class": "txt"}).get_text().strip()

# 获取章节网址
chapter_url = chapter.find("a")["href"]

# 获取章节 id
chapter_id = re.search(r"/(\d+)-(\d+)/", chapter_url).group(2)

# 尝试获取章节内容
chapter_content = None
retry_count = 1
while retry_count < 4: # 设置最大重试次数
try:
param_string = f"chapterId={chapter_id}id={book_id}{p.sign_key}"
sign = hashlib.md5(param_string.encode()).hexdigest()
encrypted_content = p.get_qimao(book_id, chapter_id, sign)
except Exception as e:

tqdm.write(Fore.RED + Style.BRIGHT + f"发生异常: {e}")
if retry_count == 1:
tqdm.write(f"{chapter_title} 获取失败,正在尝试重试...")
tqdm.write(f"第 ({retry_count}/3) 次重试获取章节内容")
retry_count += 1 # 否则重试
continue

if "data" in encrypted_content and "content" in encrypted_content["data"]:
encrypted_content = encrypted_content['data']['content']
chapter_content = p.decrypt_qimao(encrypted_content)
chapter_content = re.sub('<br>', '\n', chapter_content)
break # 如果成功获取章节内容,跳出重试循环
else:
if retry_count == 1:
tqdm.write(f"{chapter_title} 获取失败,正在尝试重试...")
tqdm.write(f"第 ({retry_count}/3) 次重试获取章节内容")
retry_count += 1 # 否则重试

if retry_count == 4:
tqdm.write(f"无法获取章节内容: {chapter_title},跳过。")
continue # 重试次数过多后,跳过当前章节
result = p.get_api(book_id, chapter)

if result is None:
continue
else:
chapter_title, chapter_text, chapter_id = result

# 去除其他 html 标签
# chapter_text = re.sub(r"</?\w+>", "", chapter_text)
#
# chapter_text = p.fix_publisher(chapter_text)

# 在小说内容字符串中添加章节标题和内容
content += f"\n\n\n{chapter_title}\n\n{chapter_content}"
content += f"\n\n\n{chapter_title}\n\n{chapter_text}"

# 打印进度信息
tqdm.write(f"已获取 {chapter_title}")
Expand Down
Loading

0 comments on commit 8cf4ffc

Please sign in to comment.