import requests
import parsel
import re
import os
import time
import urllib.parse
import random
import signal
def change(content):
"""解密字体加密""" # 看到这里不要慌,后面有教大家如何去生产对应的解码
word_data = {58344: 'd', 58345: '在', 58346: '主', 58347: '特', 58348: '家', 58349: '军', 58350: '然', 58351: '表',
58352: '场', 58353: '4', 58354: '要', 58355: '只', 58356: 'v', 58357: '和', 58359: '6', 58360: '别',
58361: '还', 58362: 'g', 58363: '现', 58364: '儿', 58365: '岁', 58368: '此', 58369: '象', 58370: '月',
58371: '3', 58372: '出', 58373: '战', 58374: '工', 58375: '相', 58376: 'o', 58377: '男', 58378: '直',
58379: '失', 58380: '世', 58381: 'f', 58382: '都', 58383: '平', 58384: '文', 58385: '什', 58386: 'v',
58387: 'o', 58388: '将', 58389: '真', 58390: 't', 58391: '那', 58392: '当', 58394: '会', 58395: '立',
58396: '些', 58397: 'u', 58398: '是', 58399: '十', 58400: '张', 58401: '学', 58402: '气', 58403: '大',
58404: '爱', 58405: '两', 58406: '命', 58407: '全', 58408: '后', 58409: '东', 58410: '性', 58411: '通',
58412: '被', 58413: '1', 58414: '它', 58415: '乐', 58416: '接', 58417: '而', 58418: '感', 58419: '车',
58420: '山', 58421: '公', 58422: '了', 58423: '常', 58424: '以', 58425: '何', 58426: '可', 58427: '话',
58428: '先', 58429: 'p', 58430: 'i', 58431: '4', 58432: '轻', 58433: 'm', 58434: '士', 58435: 'w',
58436: '着', 58437: '变', 58438: '尔', 58439: '快', 58440: 'l', 58441: '个', 58442: '说', 58443: '少',
58444: '色', 58445: '里', 58446: '安', 58447: '花', 58448: '远', 58449: '7', 58450: '难', 58451: '师',
58452: '放', 58453: 't', 58454: '报', 58455: '认', 58456: '面', 58457: '道', 58458: 's', 58460: '克',
58461: '地', 58462: '度', 58463: 'l', 58464: '好', 58465: '机', 58466: 'u', 58467: '民', 58468: '写',
58469: '把', 58470: '万', 58471: '同', 58472: '水', 58473: '新', 58474: '没', 58475: '书', 58476: '电',
58477: '吃', 58478: '像', 58479: '斯', 58480: '5', 58481: '为', 58482: 'y', 58483: '白', 58484: '几',
58485: '日', 58486: '教', 58487: '看', 58488: '但', 58489: '第', 58490: '加', 58491: '候', 58492: '作',
58493: '上', 58494: '拉', 58495: '住', 58496: '有', 58497: '法', 58498: 'r', 58499: '事', 58500: '应',
58501: '位', 58502: '利', 58503: '你', 58504: '声', 58505: '身', 58506: '国', 58507: '问', 58508: '马',
58509: '女', 58510: '他', 58511: 'y', 58512: '比', 58513: '父', 58514: 'x', 58515: 'a', 58516: 'h',
58517: 'n', 58518: 's', 58519: 'x', 58520: '边', 58521: '美', 58522: '对', 58523: '所', 58524: '金',
58525: '活', 58526: '回', 58527: '意', 58528: '到', 58529: 'z', 58530: '从', 58531: 'j', 58532: '知',
58533: '又', 58534: '内', 58535: '因', 58536: '点', 58537: 'q', 58539: '定', 58540: '8', 58541: 'R',
58542: 'b', 58543: '正', 58544: '或', 58545: '夫', 58546: '向', 58547: '德', 58548: '听', 58549: '更',
58551: '得', 58552: '告', 58553: '并', 58554: '本', 58555: 'q', 58556: '过', 58557: '记', 58558: 'l',
58559: '让', 58560: '打', 58561: 'f', 58562: '人', 58563: '就', 58564: '者', 58565: '去', 58566: '原',
58567: '满', 58568: '体', 58569: '做', 58570: '经', 58571: 'K', 58572: '走', 58573: '如', 58574: '孩',
58575: 'c', 58576: 'g', 58577: '给', 58578: '使', 58579: '物', 58581: '最', 58582: '笑', 58583: '部',
58585: '员', 58586: '等', 58587: '受', 58588: 'k', 58589: '行', 58591: '条', 58592: '果', 58593: '动',
58594: '光', 58595: '门', 58596: '头', 58597: '见', 58598: '往', 58599: '自', 58600: '解', 58601: '成',
58602: '处', 58603: '天', 58604: '能', 58605: '于', 58606: '名', 58607: '其', 58608: '发', 58609: '总',
58610: '母', 58611: '的', 58612: '死', 58613: '手', 58614: '入', 58615: '路', 58616: '进', 58617: '心',
58618: '来', 58619: 'h', 58620: '时', 58621: '力', 58622: '多', 58623: '开', 58624: '已', 58625: '许',
58626: 'd', 58627: '至', 58628: '由', 58629: '很', 58630: '界', 58631: 'n', 58632: '小', 58633: '与',
58634: 'z', 58635: '想', 58636: '代', 58637: '么', 58638: '分', 58639: '生', 58640: '口', 58641: '再',
58642: '妈', 58643: '望', 58644: '次', 58645: '西', 58646: '风', 58647: '种', 58648: '带', 58649: 'j',
58651: '实', 58652: '情', 58653: '才', 58654: '这', 58656: 'e', 58657: '我', 58658: '神', 58659: '格',
58660: '长', 58661: '觉', 58662: '间', 58663: '年', 58664: '眼', 58665: '无', 58666: '不', 58667: '亲',
58668: '关', 58669: '结', 58670: '0', 58671: '友', 58672: '信', 58673: '下', 58674: '却', 58675: '重',
58676: '己', 58677: '老', 58678: '2', 58679: '音', 58680: '字', 58681: 'm', 58682: '呢', 58683: '明',
58684: '之', 58685: '前', 58686: '高', 58687: 'p', 58688: 'b', 58689: '目', 58690: '太', 58691: 'e',
58692: '9', 58693: '起', 58694: '棱', 58695: '她', 58696: '也', 58697: 'w', 58698: '用', 58699: '方',
58700: '子', 58701: '英', 58702: '每', 58703: '理', 58704: '便', 58705: '四', 58706: '数', 58707: '期',
58708: '中', 58709: 'c', 58710: '外', 58711: '样', 58712: 'a', 58713: '海', 58714: '们', 58715: '任',
58538: '三', 58590: '一'}
result = ''
for i in content:
code = ord(i)
if code in word_data:
result += word_data[code]
else:
result += i
return result
# 请求头
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
" Chrome/116.0.5845.97 Safari/537.36 Core/1.116.537.400 QQBrowser/19.4.6561.400" }
cookies=('x-web-secsdk-uid=6caa94ab-afcf-4fd4-afbb-8bc8452fe9be; Hm_lvt_2667d29c8e792e6fa9182c20a3013175=1753504097;'
' HMACCOUNT=3521586B2CBB60FD; s_v_web_id=verify_mdjr2cq7_0Awh10ms_xmxg_4RxP_ACcS_6L26t2CAuVN7;'
' csrf_session_id=42d699e530338ed5c27470544ca7f4d1; novel_web_id=7531242700978275891; gfkadpd=2503,36144;'
' serial_uuid=7531242700978275891; serial_webid=7531242700978275891; passport_csrf_token=456e18769bc01214ea4b162181d52c57; '
'passport_csrf_token_default=456e18769bc01214ea4b162181d52c57;'
' passport_mfa_token=Ci%2BRmTcFLTjXAtuCAzxfHTr5xzh%2FeJAq9pCuk%2FlI65%2BK0XFl43i3nA5U27bvl3phfBpKCjwAAAAAAAAAAAAAT0cRRwFSohWydrXo5%2B%2FUfenqaq2QfGYbBk2u8N3i7t0vf%2B%2Bba1Iwc%2FGAe5KLLYMdq50Q0eD3DRj2sdFsIAIiAQMlxlhx; d_ticket=40365a26b04ae00fd40c24bf84c595e569134; odin_tt=64775b0e5c16e19ea1dcfc0bc2803975e7fe1fa238f7079fad44eb74d422a92b13922f254dfe242c1a10e398110f4a81; n_mh=Q_Sm8BYjtPoAOYv_SaH5P9NQDPqDZ7xoQRgI2GvcfEw; sid_guard=4b4ce70ae45606de9ccf894f86577bf9%7C1753504126%7C5184000%7CWed%2C+24-Sep-2025+04%3A28%3A46+GMT; uid_tt=9828be745c0647d8029cb6544523a987; uid_tt_ss=9828be745c0647d8029cb6544523a987; sid_tt=4b4ce70ae45606de9ccf894f86577bf9; sessionid=4b4ce70ae45606de9ccf894f86577bf9; sessionid_ss=4b4ce70ae45606de9ccf894f86577bf9; session_tlb_tag=sttt%7C11%7CS0znCuRWBt6cz4lPhld7-f________-7F1LcICKBvVj_qj8slUjAFUXFSpOSZ6rZJkWDYtmHBVs%3D; is_staff_user=false; sid_ucp_v1=1.0.0-KGM1OTZmODRmM2NhMjEyNDE4ZjA1YzIzZjhlZDRjOWU0Yjg3ZWY4MTkKHQj_svrjugIQ_rKRxAYYxxMgDDC8gbzSBTgCQO8HGgJobCIgNGI0Y2U3MGFlNDU2MDZkZTljY2Y4OTRmODY1NzdiZjk; ssid_ucp_v1=1.0.0-KGM1OTZmODRmM2NhMjEyNDE4ZjA1YzIzZjhlZDRjOWU0Yjg3ZWY4MTkKHQj_svrjugIQ_rKRxAYYxxMgDDC8gbzSBTgCQO8HGgJobCIgNGI0Y2U3MGFlNDU2MDZkZTljY2Y4OTRmODY1NzdiZjk; Hm_lpvt_2667d29c8e792e6fa9182c20a3013175=1753505316; ttwid=1%7CYbkOCAUHGSmJvwiQZl87vIuNuIeLtgcPuvxpcdV-nME%7C1753505317%7Ca23a7bc2cffe611918008995cea7fdf595616ea6cfe9a04215858502f0d6a522')
cookies_jar=requests.cookies.RequestsCookieJar()
for cookie in cookies.split(';'):
key,value=cookie.split('=',1)
cookies_jar.set(key,value)
XS_id=input('id:')
# 目标小说目录页链接
link ='https://fanqienovel.com/page/'+XS_id # 下面会带大家如何去找,需要自行去替换
link_response = requests.get(url=link, headers=headers,cookies=cookies_jar)
link_data = link_response.text
# 提取小说名称
name = re.findall('"bookName":"(.*?)",', link_data)[0]
valid_name = re.sub(r'[\\/:*?"<>|]', '', name)
os.makedirs(valid_name, exist_ok=True)
# 提取章节ID列表(保持原有 chapter_id_list 逻辑)
chapter_id_list = re.findall('<a href="/reader/(\\d+)" class="chapter-item-title"', link_data)[1:]
CuoWu=[]
BIaoTi_url={}
Kuaijie={}
Hao=0
# 遍历章节
for chapter_id in chapter_id_list:
url = f'https://fanqienovel.com/reader/{chapter_id}'
try:
response = requests.get(url=url, headers=headers,cookies=cookies_jar, timeout=10)
response.raise_for_status() # 检查HTTP状态码
html = response.text
# 解析章节标题
selector = parsel.Selector(html)
title = selector.css('.muye-reader-title::text').get()
if not title:
print(f"⚠️ 章节 {chapter_id} 未找到标题,跳过...")
print(f"章节网址:https://fanqienovel.com/reader/{chapter_id}")
class TimeoutError(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutError()
def input_with_timeout(prompt, timeout, default):
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout)
try:
user_input = input(prompt)
signal.alarm(0) # 取消定时器
return user_input if user_input else default
except TimeoutError:
print(f"\n超时未输入,自动赋值为: {default}")
return default
except:
signal.alarm(0)
return default
if __name__ == "__main__":
BIaoTi = input_with_timeout(
"1.手动输入:\n2.继续\n请选择(10秒超时自动选2): ",
10,
"2"
)
if BIaoTi==1:
title=input("标题:")
else:
CuoWu.append(f'https://fanqienovel.com/reader/{chapter_id}')
continue
# 清理标题非法字符
valid_title = re.sub(r'[\\/:*?"<>|]', '', title)
JianZhi=[(valid_title,url)]
BIaoTi_url.update(JianZhi)
BiaoHao=[(Hao,valid_title)]
Kuaijie.update(BiaoHao)
while True:
# 获取用户输入并转换为整数
user_input = int(input("输入0退出: "))
# 检查退出条件
if user_input == 0:
print("程序已退出")
break # 跳出循环
Zhang=input("1.单章"
"2.部分"
"3.整本")
print(Kuaijie)
if Zhang==1:
XiaZai=input('章节序号:')
# 解析正文内容
content_list = selector.css('.muye-reader-content p::text').getall()
content = '\n\n'.join(content_list)
new_content = change(content)
# 写入章节文件
file_path = os.path.join(valid_name, f'{valid_title}.txt')
with open(file_path, 'w', encoding='utf-8') as f:
f.write(title + '\n\n')
f.write(new_content)
print(f"✅ 已保存章节: {valid_title}")
time.sleep(1) # 避免频繁请求
except Exception as e:
time.sleep(3)
print(f"❌ 章节 {chapter_id} 爬取失败: {str(e)}")
continue
print(f'《{valid_name}》共 {len(chapter_id_list)} 章节已保存完成')
File "E:\Python\py\番茄小说下载(不完整)小说名 - 副本.py", line 162
while True:
SyntaxError: expected 'except' or 'finally' block