利用AI生成批量下载LWN上的技术文章的脚本
LWN.net以技术深度、独立性及历史沉淀成为开源世界的“活档案”,其报道不仅是新闻,更是理解开源技术演进与社区文化的关键入口。对于开发者而言,它是技术洞察的“雷达”;对于企业,则是技术风险评估与决策的“智库”。
下面使用AI辅助我们写一个爬虫程序来爬其中的网页,为了防止对服务器造成负担,将访问间隔控制在20秒左右。
-
跟大模型的对话
https://yuanbao.tencent.com/bot/app/share/chat/39eBPtImuTNH -
目前支持下面的功能:
中断恢复能力
网络异常/程序崩溃后可从最后位置继续
自动跳过已完成文章(节省流量和时间)
精确进度追踪
字节级断点记录(非文件级)
实时保存进度(避免二次中断时丢失进度)
服务器兼容性
自动检测服务器是否支持Range请求
降级机制保障基础功能可用性
资源优化
避免重复下载已完成内容
智能排序任务(优先处理中断任务) -
参考脚本如下
lwn_to_pdf.py
#!/usr/bin/env python3 import os import sys import time import random import re import requests from bs4 import BeautifulSoup import json # 新增模块用于保存下载状态 # 配置参数 BASE_URL = "https://lwn.net/Kernel/Index/" OUTPUT_DIR = "lwn_kernel_pages3" REQUEST_INTERVAL = 20 # 基础请求间隔(秒) RANDOM_RANGE = 5 # 随机延迟范围(±秒) STATE_FILE = os.path.join(OUTPUT_DIR, "download_state.json") # 断点续传状态文件[2,3](@ref) # 创建输出目录 os.makedirs(OUTPUT_DIR, exist_ok=True) def load_download_state(): """加载下载状态""" if os.path.exists(STATE_FILE): try: with open(STATE_FILE, 'r', encoding='utf-8') as f: return json.load(f) except: return {"completed": [], "in_progress": {}} return {"completed": [], "in_progress": {}} # {completed: [id1, id2], in_progress: {id: {title, url, downloaded}}}[2](@ref) def save_download_state(state): """保存下载状态""" with open(STATE_FILE, 'w', encoding='utf-8') as f: json.dump(state, f, indent=2) def fetch_page(url, resume_position=0): """ 带断点续传的页面请求 :param resume_position: 续传起始位置(字节)[1,3](@ref) """ headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36", "Accept": "text/html; charset=utf-8", } # 添加断点续传头部[1,3](@ref) if resume_position > 0: headers['Range'] = f'bytes={resume_position}-' try: response = requests.get(url, headers=headers, stream=True, timeout=30) response.raise_for_status() # 处理断点续传响应(206状态码)[3](@ref) if resume_position > 0 and response.status_code != 206: print("⚠️ 服务器不支持断点续传,将重新下载") return None, 0 # 自动检测编码 if response.encoding == 'ISO-8859-1': response.encoding = response.apparent_encoding or 'utf-8' return response.text, response.headers.get('Content-Length', 0) except Exception as e: print(f"❌ 请求失败 {url}: {str(e)}") return None, 0 def extract_article_links(html): """精确提取文章链接并捕获文章ID""" soup = BeautifulSoup(html, "html.parser") articles = [] ids = [] for entry in soup.find_all("p", class_="IndexEntry"): link = entry.find("a", href=True) if not link or not link["href"].startswith("/Articles/"): continue # 构造完整URL article_url = "https://lwn.net" + link["href"] # 提取文章ID article_id = "" match = re.search(r'/Articles/(\d+)/?', link["href"]) if match: article_id = match.group(1) if article_id in ids: continue ids.append(article_id) # 清理标题 title = link.text.strip().replace("/", "_").replace(":", " -")[:100] articles.append({ "id": article_id, "title": title, "url": article_url }) return articles def save_webpage(html, article, format_type="html"): """保存网页内容(添加文章ID前缀)""" try: # 生成带ID前缀的文件名 base_name = f"{article['id']}_{article['title']}" if format_type == "formatted.html": filename = f"{base_name}_formatted.html" else: filename = f"{base_name}.html" output_path = os.path.join(OUTPUT_DIR, filename) # 写入文件 if format_type == "formatted.html": soup = BeautifulSoup(html, 'html.parser') with open(output_path, 'w', encoding='utf-8') as f: f.write(soup.prettify()) else: with open(output_path, 'w', encoding='utf-8') as f: f.write(html) print(f"✅ 保存成功: {filename}") return True except Exception as e: print(f"❌ 保存失败 {article['title']}: {str(e)}") return False def main(): # 加载下载状态[2](@ref) state = load_download_state() print(f"📊 恢复下载状态: 已完成 {len(state['completed'])} 篇, 进行中 {len(state['in_progress'])} 篇") # 抓取索引页 print("🔍 正在获取索引页...") html, _ = fetch_page(BASE_URL) if not html: print("⛔ 索引页获取失败,请检查网络或反爬限制") return # 解析文章列表 all_articles = extract_article_links(html) print(f"📚 共找到 {len(all_articles)} 篇文章") # 过滤已完成的文章 pending_articles = [a for a in all_articles if a['id'] not in state['completed']] print(f"⏳ 待处理文章: {len(pending_articles)} 篇") # 处理中断的文章 for article_id, data in state['in_progress'].items(): print(f"\n🔁 恢复中断的下载: {data['title']}") pending_articles.insert(0, { "id": article_id, "title": data['title'], "url": data['url'], "resume_position": data.get('downloaded', 0) }) # 逐篇处理 for idx, article in enumerate(pending_articles): article_id = article['id'] print(f"\n📄 处理第 {idx+1}/{len(pending_articles)} 篇: [{article_id}] {article['title']}") print(f"🔗 文章链接: {article['url']}") # 更新状态为"进行中" if article_id not in state['in_progress']: state['in_progress'][article_id] = { "title": article['title'], "url": article['url'], "downloaded": 0 } save_download_state(state) # 获取续传位置[1](@ref) resume_position = state['in_progress'][article_id].get('downloaded', 0) if resume_position > 0: print(f"⏩ 从 {resume_position} 字节处续传...") # 获取文章HTML(支持断点续传) article_html, content_length = fetch_page(article['url'], resume_position) # 更新下载进度 if article_html: downloaded_size = resume_position + len(article_html.encode('utf-8')) state['in_progress'][article_id]['downloaded'] = downloaded_size save_download_state(state) # 保存为原始HTML + 美化版HTML save_webpage(article_html, article, "html") # save_webpage(article_html, article, "formatted.html") # 更新状态为"已完成" state['completed'].append(article_id) del state['in_progress'][article_id] save_download_state(state) else: print("⛔ 下载失败,将在下次继续尝试") # 动态请求间隔 delay = REQUEST_INTERVAL + random.uniform(-RANDOM_RANGE, RANDOM_RANGE) print(f"⏳ 等待 {delay:.1f} 秒...") time.sleep(delay) print("\n🎉 所有文章保存完成!") print(f"💾 文件保存在: {os.path.abspath(OUTPUT_DIR)}") # 清理状态文件 # if os.path.exists(STATE_FILE): # os.remove(STATE_FILE) if __name__ == "__main__": main() -
下面是状态文件
download_state.json
{ "completed": [ "1000654", "1000933", "100148", "1001526", "1002371", "100303", "1003059", "100321", "1004029", "1004455", "1004998", "1005222", "1005651", "1005662", "1006378", "1006805", "1007947", "1008399", "1009039", "1009298", "1009509", "1010667", "1011366", "1011680", "101210", "101215", "101230", "1012490", "1012990", "1013408", "1013649", "1013892", "1014220", "1014440", "1015000", "1015320", "1015409", "1015414", "1015551", "1015747", "1015762", "1015997", "1016001", "1016009", "1016011", "1016013", "1016015", "1016105", "1016119", "1016124", "1016133", "1016136", "1016243", "1016406", "1016408", "1016416", "1016426", "1016519", "1016525", "1016674", "1016712", "1016722", "1016724", "1016842", "1016844", "1016853", "1016856", "1016860", "1016879", "1017116", "1017128", "1017439", "1017449", "1017477", "1017549", "1017573", "1017705", "1017947", "1018320", "1018334", "1018341", "1018475", "1018486", "1018493", "1018494", "1018642", "1019230", "1019522", "1019885", "1020170", "1020437", "1020596", "1020664", "1021332", "1022034", "1022054", "102232", "1022414", "102246", "1022512", "102253", "1022655", "1022718", "1023085", "1023502", "1023575", "1023646", "1023689", "1024160", "1024202", "1024402", "1024757", "1025257", "1025268", "1025650", "1026337", "1026558", "1027096", "102976", "103160", "103183", "103203", "103209", "103858", "104179", "104333", "104343", "104393", "105021", "105168", "105366", "106010", "106177", "106353", "106419", "107269", "107303", "107314", "108216", "108484", "108595", "109400", "109458", "109475", "109505", "110277", "110432", "110468", "111226", "111247", "111408", "112391", "112396", "112531", "112566", "113349", "113555", "114596", "114626", "114770", "115405", "115554", "115651", "115720", "116810", "117736", "117749", "117881", "118750", "118785", "118835", "118952", "119652", "119682", "120614", "120647", "120797", "120850", "121566", "121618", "121656", "121845", "122477", "122579", "122764", "123737", "124560", "124703", "124747", "125488", "125621", "125831", "126763", "126795", "126808", "126823", "126943", "126986", "127018", "127556", "127669", "127698", "127858", "128644", "128681", "128741", "128853", "129476", "129480", "129511", "129703", "130506", "130555", "130696", "130746", "131657", "131802", "131856", "132196", "132796", "132804", "133295", "133649", "133848", "134460", "134484", "134513", "134700", "135283", "135321", "135472", "135568", "136273", "136308", "136425", "137278", "137306", "137439", "138042", "138063", "138174", "138969", "139118", "139123", "139595", "139784", "139884", "139916", "140333", "14035", "140787", "140815", "143390", "143447", "143474", "144096", "144100", "144102", "144107", "144109", "144110", "144269", "144272", "144273", "144274", "144277", "144278", "144279", "144281", "144681", "144765", "145008", "145036", "145135", "145194", "145973", "146079", "146094", "146104", "146689", "147014", "147043", "14776", "147879", "147901", "147983", "148697", "148973", "148987", "149756", "149877", "149888", "150580", "150652", "150675", "1511", "151204", "152436", "152462", "152548", "152635", "153203", "153322", "153353", "153366", "154277", "154557", "154580", "154602", "155344", "155351", "155510", "156063", "156144", "156325", "156921", "157066", "157151", "157208", "157949", "157951", "158211", "159077", "159101", "159110", "159313", "160138", "160157", "160201", "160380", "160944", "160953", "161190", "161204", "162860", "162890", "162966", "163842", "163881", "164121", "164887", "165039", "166172", "166195", "167034", "167270", "167897", "168093", "168894", "168972", "169140", "169961", "170003", "170212", "170822", "170954", "171017", "171838", "171941", "172149", "172844", "172986", "173735", "173740", "173882", "174494", "174641", "174660", "175432", "175706", "176453", "176635", "177118", "178199", "178253", "178634", "179305", "179361", "179492", "180375", "181169", "181508", "182060", "182369", "182847", "182874", "183053", "183105", "183693", "183734", "183894", "184118", "184495", "184673", "184750", "184879", "185500", "185666", "186331", "186427", "186438", "187321", "187336", "187490", "190169", "190222", "190966", "191004", "191080", "191649", "191650", "191652", "191653", "191654", "191657", "191659", "191737", "191782", "191822", "191923", "191924", "191926", "191929", "191931", "191932", "192410", "192632", "192767", "193516", "193663", "193691", "194443", "194543", "194729", "195416", "195643", "195805", "196292", "196444", "196641", "196721", "197299", "197409", "197433", "198202", "198344", "198380", "198988", "199004", "199110", "200059", "200073", "200213", "201111", "201195", "202449", "202838", "202847", "203562", "203725", "203924", "204545", "204682", "204935", "205624", "205644", "206014", "206765", "207030", "208117", "208139", "208312", "209101", "209257", "209587", "211279", "211505", "211883", "212724", "212794", "213672", "213798", "214457", "215075", "215113", "215868", "215996", "216200", "216794", "217084", "217484", "217866", "218766", "218798", "219794", "219954", "220677", "220897", "221097", "221913", "222773", "222860", "222877", "223185", "223839", "223899", "224760", "224772", "224829", "224865", "225714", "225881", "226054", "226710", "226756", "227533", "227818", "227937", "228143", "22818", "229740", "229774", "229873", "229984", "230574", "230975", "231585", "231672", "232247", "232492", "232575", "232757", "233315", "233462", "233479", "234133", "234441", "234617", "235023", "235164", "236038", "236206", "236843", "236920", "237104", "237722", "237768", "238923", "238948", "238969", "239238", "239336", "239633", "239962", "240253", "240474", "240571", "240667", "240758", "241311", "241915", "241980", "242107", "242608", "242625", "242744", "242765", "243704", "243795", "243851", "243949", "244531", "244536", "244595", "244640", "244829", "245533", "245600", "245671", "246201", "246272", "246337", "246565", "247072", "247126", "247243", "247582", "248268", "248376", "248388", "248400", "248878", "248929", "248931", "249054", "249080", "249104", "249246", "250210", "250335", "250424", "250480", "251413", "251469", "251573", "252562", "252716", "252742", "253425", "253651", "254559", "254711", "254856", "255327", "255529", "255650", "256368", "256519", "257297", "257417", "257541", "258238", "258516", "258550", "259068", "260041", "260068", "260172", "260795", "260880", "260916", "260918", "261473", "261626", "261804", "262464", "262528", "262554", "263130", "263329", "263343", "264090", "264231", "264440", "265220", "265240", "265257", "265285", "266153", "266274", "266320", "266721", "266914", "267013", "267849", "267896", "267968", "268783", "268923", "269120", "270081", "270089", "270939", "270960", "271614", "271688", "271762", "271796", "271817", "272048", "272693", "273030", "273731", "273822", "274008", "274695", "274755", "274988", "275808", "275954", "276025", "276731", "276856", "277833", "277872", "278016", "278647", "278965", "279077", "279229", "280034", "280058", "280279", "281029", "281109", "281157", "281938", "281965", "283066", "283103", "283161", "283793", "283854", "284037", "284104", "284472", "284767", "284886", "284932", "285088", "285594", "286233", "286472", "286558", "287155", "287289", "287435", "287906", "287924", "288056", "288233", "289013", "289064", "289137", "289990", "290141", "290227", "291033", "291091", "291292", "291630", "291826", "292650", "292872", "293575", "293658", "294465", "294642", "294667", "294675", "295545", "295568", "295587", "296419", "296578", "296588", "296738", "297500", "297529", "297770", "298510", "298570", "298587", "298589", "298592", "298596", "298685", "298832", "298840", "299483", "300066", "300070", "300202", "300992", "30107", "301192", "302043", "302061", "302251", "302754", "303270", "303609", "304105", "304188", "304592", "304845", "305083", "305740", "305782", "305919", "306601", "306690", "306704", "307482", "307713", "307746", "308409", "308426", "308445", "308566", "309094", "309298", "309400", "310260", "310391", "310434", "311502", "311630", "311850", "312074", "312641", "312708", "313437", "313521", "313621", "313682", "314772", "314808", "314848", "315022", "315686", "315974", "316806", "316940", "317787", "317793", "317814", "318611", "318699", "318705", "319544", "319686", "319860", "320472", "320508", "320556", "320721", "321660", "321663", "321696", "322666", "322668", "322777", "322823", "323929", "324046", "324291", "324989", "325180", "325369", "325921", "326471", "326552", "327004", "327601", "327738", "327740", "328363", "328436", "328490", "328572", "329266", "329428", "329464", "329543", "330378", "330402", "330589", "330866", "331615", "331808", "331818", "3327", "332839", "332974", "333007", "333620", "333742", "333783", "334546", "334649", "334721", "334747", "334854", "335698", "335768", "335812", "335942", "336224", "336255", "336262", "336953", "337680", "337765", "338063", "338435", "339337", "339361", "339399", "340080", "340370", "340400", "341033", "341110", "341352", "341826", "342330", "342420", "342892", "343766", "343828", "344003", "344038", "345076", "345273", "345296", "346219", "346470", "346584", "3467", "347511", "347573", "347619", "348357", "348445", "348719", "348886", "349970", "350123", "350219", "351422", "351480", "351499", "351543", "352644", "352863", "353044", "353050", "353411", "353501", "354690", "354842", "354851", "354861", "354865", "355416", "355700", "355923", "355934", "356378", "356576", "356776", "356899", "357464", "357471", "357480", "357481", "357487", "357658", "357767", "357800", "357805", "358910", "358940", "359158", "359208", "359219", "360047", "360199", "360328", "360699", "360955", "360958", "361445", "361453", "361457", "362179", "362339", "362357", "362371", "363349", "363456", "363490", "363572", "363575", "364515", "364583", "364584", "364742", "365443", "365833", "365835", "366436", "366648", "366717", "366796", "366915", "366987", "367787", "367895", "368706", "368730", "368869", "369511", "369549", "369567", "369609", "370322", "370419", "370423", "371210", "371276", "371320", "371501", "371538", "371986", "372321", "372384", "373405", "373842", "374424", "374574", "374633", "374794", "375096", "375335", "375855", "375888", "376508", "376606", "376849", "377103", "377109", "377766", "377895", "377953", "378044", "378641", "378859", "378884", "378903", "378911", "379748", "379869", "379903", "380150", "380835", "380931", "381064", "381158", "381164", "382257", "382299", "382428", "382554", "382559", "383162", "383362", "383363", "384093", "384118", "384132", "384139", "384146", "384855", "384936", "385081", "385103", "385949", "386090", "386139", "387083", "387196", "387231", "387246", "387250", "387257", "388109", "388118", "388131", "388188", "388296", "388959", "388978", "389081", "389400", "389407", "389932", "390323", "390369", "390392", "390427", "390634", "391222", "391230", "391245", "391372", "392136", "392154", "392293", "392307", "393008", "393144", "393171", "393288", "393314", "393694", "394170", "394211", "394298", "394672", "394702", "395712", "395961", "396020", "396561", "396634", "396702", "396773", "397422", "397442", "397574", "398470", "398503", "398601", "398684", "399052", "399148", "399313", "400074", "400541", "400629", "400651", "400746", "401548", "401738", "401769", "401911", "401915", "402287", "402512", "403012", "403836", "403891", "404043", "404103", "404993", "405076", "405118", "405346", "40611", "406246", "406466", "406491", "407379", "407495", "407525", "408428", "408439", "408845", "409256", "409681", "409689", "410200", "410606", "410763", "410856", "410874", "410895", "411590", "411845", "411929", "412072", "412131", "412459", "412638", "412639", "412685", "412744", "412745", "412746", "412747", "412748", "412749", "412750", "412847", "413036", "413046", "413059", "413061", "413102", "414016", "414223", "414264", "414537", "414618", "415714", "415740", "415889", "416494", "416690", "417037", "417647", "417772", "417809", "417989", "418853", "418884", "419161", "419713", "419811", "419855", "419961", "420019", "420407", "420544", "420623", "420658", "420691", "420799", "421601", "421680", "422420", "422477", "422487", "422649", "423417", "423541", "423584", "423619", "423777", "423994", "424496", "424657", "424696", "425583", "425862", "425870", "425990", "426013", "426921", "426947", "426961", "427104", "427113", "427961", "428100", "428140", "428220", "428230", "428584", "429295", "429321", "429345", "429912", "429925", "430462", "432114", "432223", "432234", "433568", "433601", "433854", "433904", "434637", "434821", "434833", "435022", "435716", "435894", "435917", "436041", "436047", "436871", "437014", "437066", "437162", "437981", "438182", "438256", "439169", "439298", "439314", "439472", "440064", "440221", "440255", "440347", "441018", "441209", "441232", "441438", "442113", "442229", "442355", "443099", "443241", "443510", "443531", "444288", "444336", "444503", "444745", "444910", "445066", "446297", "446317", "446493", "446528", "446618", "447405", "447435", "447650", "448499", "448502", "448505", "449448", "449460", "449585", "449725", "450286", "450291", "450460", "450658", "451243", "451365", "451985", "452117", "452184", "452293", "452748", "452866", "452884", "453002", "453700", "454389", "454390", "454399", "454427", "454716", "454795", "456132", "456146", "456217", "456731", "456762", "456904", "457635", "457667", "457674", "458610", "458625", "458652", "458729", "458805", "458809", "459420", "459545", "459585", "459795", "460597", "460644", "460826", "461461", "461552", "461592", "461696", "462437", "462543", "462669", "463357", "463517", "463575", "463683", "464233", "464235", "464268", "464276", "464288", "464292", "464294", "464296", "464298", "464834", "465066", "465160", "465317", "465358", "465738", "466230", "466304", "466468", "467328", "467480", "467509", "468683", "468759", "468896", "469662", "469775", "469805", "470656", "470681", "470820", "470906", "471973", "472030", "472071", "472852", "472984", "472998", "473220", "474067", "474088", "474268", "474645", "474819", "474915", "475043", "475405", "475678", "476263", "476947", "477067", "478111", "478440", "478657", "479653", "479841", "479886", "480055", "480095", "481055", "482168", "482344", "483078", "483101", "484196", "484203", "484251", "484337", "484527", "485058", "485593", "486301", "486304", "486306", "486311", "486401", "486858", "487417", "487437", "487701", "488131", "488709", "488906", "489665", "490291", "491310", "491510", "491653", "491722", "492125", "492296", "492676", "492959", "494028", "494158", "494252", "494993", "495304", "495543", "496193", "496400", "496509", "497024", "497106", "497218", "498116", "498128", "498283", "498693", "499190", "499293", "500212", "500355", "500382", "500443", "501492", "501501", "501696", "502472", "502612", "502624", "503430", "503660", "503677", "504744", "504814", "504970", "505683", "506148", "506244", "507065", "507115", "507239", "507794", "507852", "507986", "508790", "508865", "508991", "509433", "509577", "510202", "511105", "511254", "511259", "511421", "512487", "512548", "512788", "513789", "514054", "514063", "514898", "514901", "514985", "515007", "515528", "515529", "516334", "516439", "516529", "516531", "516533", "516535", "516537", "516538", "516539", "516540", "516541", "516542", "516908", "517375", "517465", "517475", "517564", "518275", "518329", "518345", "518942", "518953", "518988", "519010", "519883", "519919", "520012", "520076", "520198", "520704", "520857", "522093", "522135", "522262", "522507", "523367", "524329", "524742", "524952", "524977", "525459", "525592", "525651", "525675", "526983", "527191", "527342", "527373", "528031", "528078", "528107", "528617", "528893", "529313", "529461", "529954", "531077", "531114", "531148", "531254", "531381", "531419", "531752", "531853", "531939", "532593", "532714", "532748", "532771", "532778", "532866", "533499", "533632", "534682", "534735", "535034", "535075", "536173", "536293", "536363", "537110", "537422", "537562", "538898", "539082", "539179", "539262", "539840", "539892", "540087", "540287", "540994", "541005", "541037", "542327", "542466", "542629", "542707", "543273", "543408", "544298", "544399", "544520", "545119", "545244", "545668", "546537", "546664", "546686", "547073", "547439", "547559", "547782", "547903", "548091", "548092", "548098", "548102", "548108", "548109", "548112", "548116", "548118", "548180", "548189", "548294", "548295", "548296", "548347", "548348", "548351", "548352", "548353", "548368", "548510", "548834", "548909", "548936", "548937", "548938", "548939", "548940", "549203", "549477", "549580", "550205", "550463", "550555", "550621", "550901", "551284", "551314", "551401", "551896", "551969", "552095", "552789", "552885", "552904", "553047", "553199", "553693", "554822", "554910", "554956", "555968", "556186", "556244", "557082", "557132", "557314", "557478", "558126", "558284", "558305", "558940", "559061", "559113", "560392", "560424", "560523", "561359", "561462", "561650", "562211", "562294", "562488", "563178", "563185", "563285", "563977", "564095", "564120", "564854", "564978", "565097", "565121", "565469", "565715", "565734", "566122", "566123", "566169", "566546", "567055", "567086", "567894", "568076", "568870", "568891", "568984", "569134", "569635", "569686", "569704", "569861", "570338", "570353", "570386", "570406", "570483", "571379", "571414", "571934", "571935", "571977", "571980", "571991", "571995", "571997", "572003", "572063", "572068", "572099", "572114", "572125", "572127", "572128", "572129", "572692", "572740", "572788", "572911", "573092", "573272", "573409", "574222", "574317", "574439", "574962", "574965", "575460", "575497", "575531", "575672", "575846", "576276", "576486", "577164", "577218", "577370", "577432", "577961", "578295", "578852", "579009", "579081", "580186", "580194", "580451", "580893", "581558", "581657", "582352", "582712", "582862", "583681", "584020", "585415", "585439", "585782", "586427", "586838", "586904", "588086", "588300", "588444", "588799", "589260", "589475", "590243", "590354", "590378", "590928", "590960", "590991", "591690", "591779", "591782", "591959", "591961", "591978", "591985", "591990", "591995", "591998", "592011", "592042", "592045", "592061", "592116", "592989", "593690", "593918", "594725", "594864", "595565", "595638", "595652", "596618", "596854", "597407", "597529", "597632", "598460", "599580", "599755", "599795", "600250", "600359", "600419", "600502", "600568", "600644", "601152", "601726", "601799", "601840", "602212", "602479", "602650", "603116", "603131", "603252", "603762", "603983", "604015", "604287", "604413", "604515", "604686", "605039", "605128", "606004", "606089", "606141", "606238", "606699", "606925", "606995", "607117", "607627", "607741", "608425", "608434", "608497", "608748", "608914", "608917", "608933", "608945", "608954", "608959", "608968", "608992", "609463", "609561", "609571", "609904", "610174", "610972", "611226", "612021", "612100", "612153", "612483", "612878", "613006", "614057", "614348", "615086", "615238", "615327", "615809", "615825", "616241", "616859", "617140", "617383", "617599", "618074", "618333", "618421", "619058", "619068", "619146", "619355", "619514", "619738", "620827", "621006", "621046", "621612", "624045", "624126", "624258", "625077", "625146", "625224", "625969", "626150", "626544", "626665", "627202", "627232", "627419", "628531", "628628", "629152", "629155", "629742", "629965", "630115", "630727", "630762", "631509", "631631", "631853", "632520", "632528", "632761", "633096", "633422", "634391", "634471", "634649", "634803", "635354", "635522", "635771", "636017", "636096", "636162", "636226", "636234", "636288", "636301", "636331", "636334", "636549", "636730", "636797", "636943", "636967", "636972", "636973", "636978", "637035", "637079", "637151", "637211", "637428", "637431", "637435", "637436", "637437", "637909", "638546", "638613", "638722", "638908", "639333", "639427", "639543", "640113", "640297", "640357", "641016", "641247", "641275", "642039", "642069", "642166", "642202", "643165", "643234", "643376", "643797", "643892", "644079", "644906", "645115", "645720", "645810", "645823", "646617", "646942", "646950", "647616", "647757", "648154", "648292", "648313", "648400", "648995", "649111", "649115", "649652", "649729", "650299", "650333", "650538", "650786", "650917", "65136", "651629", "65163", "651645", "651700", "65178", "65195", "652156", "652468", "652677", "653071", "653326", "653382", "653466", "653585", "654071", "65437", "654418", "654633", "654783", "655366", "655479", "656115", "656197", "656267", "656286", "656324", "656731", "656807", "657012", "657139", "657325", "657341", "657939", "657999", "658081", "65832", "658333", "658497", "659214", "659490", "659523", "660331", "660404", "660452", "66091", "661357", "661357", "661424", "661448", "661978", "662147", "662219", "662701", "662703", "662820", "662825", "662833", "662839", "662882", "662907", "662911", "662930", "662946", "662958", "663742", "663879", "663956", "664461", "664645", "664688", "665299", "666220", "666509", "666550", "667059", "667156", "667210", "667593", "667790", "668083", "668126", "66829", "668870", "668876", "669015", "670087", "670209", "670231", "670237", "671470", "671496", "67163", "671649", "67175", "67194", "67216", "672344", "672457", "672576", "673312", "673597", "673641", "674085", "674303", "674308", "674752", "674943", "674949", "675056", "676101", "676737", "676803", "676806", "677764", "677839", "678011", "679031", "679289", "679308", "679940", "680121", "680566", "680705", "680708", "680985", "680996", "68104", "68118", "68149", "681539", "682302", "682391", "682459", "682538", "682582", "683118", "683476", "683504", "684264", "684288", "684300", "684366", "684437", "684465", "684611", "684614", "684616", "684826", "684828", "684829", "684830", "684832", "684864", "684866", "684916", "684923", "684926", "684934", "684945", "685107", "685108", "685431", "685499", "685769", "685791", "685894", "685928", "685978", "686033", "686106", "686150", "686690", "686697", "686789", "686808", "686943", "687494", "687496", "687617", "688130", "688217", "688809", "689257", "689395", "689856", "689907", "690079", "690679", "691102", "691128", "691882", "691887", "692208", "692546", "692704", "692705", "692866", "692953", "693027", "693038", "69402", "694062", "69419", "694209", "694755", "694800", "694880", "69523", "695257", "695294", "695355", "69575", "695991", "695993", "696073", "696216", "696624", "696716", "696720", "696856", "697191", "697278", "697366", "697979", "698014", "698073", "698090", "698315", "698452", "698724", "699094", "699551", "699784", "699819", "699820", "700489", "700530", "700647", "701165", "701263", "701304", "701639", "701650", "702177", "702339", "702375", "702590", "703005", "703110", "703574", "703749", "703779", "703785", "703876", "703890", "704231", "704478", "704479", "704613", "70465", "70473", "704843", "704920", "705220", "705224", "705228", "705262", "705269", "705270", "705758", "705884", "705938", "706327", "706374", "706498", "70680", "707520", "707602", "708087", "708179", "708266", "708679", "708680", "708891", "709017", "709202", "709556", "709849", "710493", "710494", "710545", "711075", "711167", "711234", "711653", "712161", "712467", "713076", "713175", "713803", "713890", "714396", "714511", "71472", "715051", "715161", "715781", "715811", "715955", "716148", "716302", "716303", "716982", "717076", "71710", "717221", "717293", "71732", "71742", "717555", "717601", "717614", "717650", "717656", "717699", "717707", "717754", "717755", "717767", "717797", "717950", "717953", "718062", "718064", "718102", "718198", "718204", "718212", "718275", "718628", "718632", "718638", "718639", "718640", "718734", "718800", "718802", "718803", "718804", "718888", "719772", "720226", "720227", "720313", "720336", "720550", "720675", "721074", "721573", "721581", "721848", "722183", "722267", "722293", "722512", "722804", "723057", "723070", "723317", "723561", "724198", "724307", "724319", "724502", "724643", "725238", "725254", "725376", "725725", "725832", "725860", "726021", "726481", "726580", "726816", "726917", "726950", "727322", "727385", "727703", "727852", "728339", "728675", "728795", "72894", "728942", "72905", "729215", "72929", "729653", "729812", "72982", "730217", "730509", "730531", "731052", "731082", "731706", "731794", "732107", "732201", "732420", "732740", "732952", "733175", "733405", "733463", "733846", "734039", "734453", "734765", "735589", "735887", "735902", "736348", "736534", "736578", "737093", "737530", "737662", "737666", "737822", "738216", "738222", "738225", "738235", "738449", "73847", "738694", "73897", "738975", "739183", "739341", "740064", "740146", "740157", "740455", "740621", "741171", "741261", "741369", "74138", "74149", "741494", "741878", "742082", "742672", "742702", "743265", "743363", "743714", "743740", "743946", "744047", "744287", "744507", "744522", "745073", "745590", "745817", "746129", "746551", "746780", "746791", "747256", "747551", "747633", "747640", "748074", "748198", "748582", "748642", "748879", "749064", "749108", "749217", "749530", "749676", "749707", "749888", "749900", "750054", "750215", "750313", "750730", "750774", "750845", "750928", "751061", "751374", "751482", "75174", "751974", "75198", "752063", "752188", "75233", "752408", "752422", "752552", "752564", "752587", "752588", "752613", "752614", "752621", "752683", "752952", "752964", "752977", "752985", "753027", "753058", "753078", "753154", "753162", "753167", "753171", "753261", "753267", "753269", "753272", "753273", "753276", "753277", "753473", "753480", "753481", "753601", "753650", "753652", "754504", "754505", "754506", "754507", "754508", "754681", "754923", "755276", "755277", "755593", "755919", "756031", "756233", "756565", "756625", "756627", "756898", "757042", "757122", "757123", "757124", "757187", "757239", "757342", "757643", "75780", "758245", "758324", "758353", "758594", "758677", "758963", "759188", "75920", "75928", "759423", "75944", "759499", "75951", "759781", "75990", "760045", "760345", "760584", "760690", "760714", "761118", "761215", "761939", "761992", "762043", "762355", "762510", "762566", "762570", "763056", "763058", "763106", "763603", "763641", "763729", "764057", "764200", "764209", "764325", "764482", "764593", "764647", "764664", "765108", "765965", "766089", "766699", "766768", "767281", "767398", "767547", "767635", "767885", "767987", "768418", "769117", "769253", "769417", "769471", "769477", "770079", "77074", "770750", "77106", "771169", "771441", "771621", "77190", "771974", "772565", "772882", "772960", "773118", "773198", "773459", "773605", "774114", "774411", "774440", "774743", "775264", "775440", "775618", "775698", "775872", "775971", "776034", "776435", "776688", "776703", "776721", "776801", "777036", "777212", "777421", "778437", "779120", "779472", "77972", "779738", "77981", "779997", "780271", "780364", "780556", "780703", "780710", "780985", "781283", "782381", "782489", "782511", "782876", "783084", "783578", "783673", "783973", "784041", "784124", "784267", "784574", "784674", "784831", "784964", "785263", "785709", "786044", "786172", "786258", "786487", "786558", "786638", "787131", "787166", "787187", "787210", "787217", "787233", "787272", "787308", "787326", "787338", "787388", "787418", "787434", "787473", "787611", "787614", "787626", "787629", "787630", "787636", "787705", "787740", "787748", "787754", "787856", "787963", "787973", "788292", "788333", "788335", "788380", "788532", "788721", "788851", "788938", "789023", "789024", "789038", "789153", "789159", "789225", "789304", "789538", "789600", "789603", "789623", "789640", "789641", "790185", "790235", "790464", "790831", "790920", "790985", "791284", "791409", "79155", "791606", "79185", "791863", "792124", "792256", "792471", "792502", "792628", "792733", "793246", "793253", "79326", "793282", "793629", "793749", "794364", "794707", "794846", "794934", "794944", "795128", "795637", "796000", "796328", "796687", "796868", "797309", "797613", "797963", "798157", "798230", "798258", "798505", "798748", "799134", "799166", "799218", "799262", "799331", "799425", "799454", "799557", "800452", "800500", "800501", "800509", "800916", "800946", "801157", "801319", "801871", "802128", "802360", "802376", "802469", "80250", "802797", "802884", "803070", "803258", "803347", "803619", "803695", "803823", "803890", "804050", "804119", "80412", "804143", "804511", "804658", "80472", "804906", "804982", "805097", "805114", "805235", "805317", "806010", "806466", "806576", "806980", "807108", "808048", "808503", "808575", "808896", "808997", "80911", "809125", "809333", "809545", "809841", "810076", "810077", "810404", "810414", "810639", "810663", "810780", "811230", "811528", "811631", "812231", "812325", "812438", "812504", "812707", "812719", "813114", "813172", "813201", "813261", "813350", "81357", "813646", "813827", "814535", "815118", "815342", "815491", "81560", "815908", "816085", "816162", "816298", "816313", "816388", "816850", "816854", "816918", "816934", "817472", "817905", "817988", "818388", "818714", "818842", "818977", "819237", "819625", "819834", "820000", "820321", "820432", "820570", "820575", "820659", "820823", "820825", "820830", "820870", "820872", "820882", "821123", "821158", "821578", "821723", "821813", "821817", "822052", "822077", "822256", "822362", "822521", "822527", "822744", "82305", "823513", "824380", "82461", "824855", "82486", "82495", "82525", "825415", "825536", "826053", "826313", "826554", "827180", "827596", "827735", "828056", "828120", "828385", "828477", "828705", "829212", "829733", "829858", "830154", "830300", "830660", "830666", "830964", "830979", "831207", "831540", "831678", "832121", "832959", "833696", "833840", "834085", "834157", "834289", "834504", "834785", "835342", "835426", "835594", "83588", "836144", "83633", "836503", "836693", "836911", "837033", "837566", "837816", "838339", "838807", "838819", "839216", "839737", "839772", "840129", "840416", "841062", "841916", "842122", "842385", "842415", "842842", "843163", "843326", "844224", "844539", "844875", "844976", "845120", "845448", "845507", "84566", "84583", "845831", "846403", "846700", "847057", "847451", "847481", "847951", "847973", "84836", "848431", "849125", "849237", "849531", "849538", "849638", "849876", "850202", "851076", "851090", "851184", "851531", "851813", "852112", "852138", "852662", "853039", "853308", "853423", "853489", "853637", "853717", "854054", "85443", "854536", "854645", "855049", "855140", "855226", "855328", "855943", "856005", "85631", "856312", "856514", "856685", "856931", "857133", "857148", "857215", "857228", "857765", "857862", "858023", "85878", "85908", "859679", "859908", "860037", "860262", "860419", "860597", "860607", "860989", "861248", "861251", "861431", "861695", "862018", "862611", "862707", "863071", "863505", "863729", "863753", "864184", "864363", "864521", "864603", "864947", "865216", "865256", "865918", "866112", "866493", "866582", "866709", "86715", "867168", "867185", "867540", "867818", "867821", "868070", "868221", "868505", "86859", "868598", "869145", "86923", "869317", "869428", "869942", "870045", "870269", "870418", "870555", "871113", "871195", "871237", "871866", "871982", "871989", "872209", "872649", "873066", "873244", "873334", "873672", "874283", "874643", "874683", "874846", "875135", "87538", "875587", "876209", "876288", "87684", "877062", "877200", "87729", "877308", "877603", "877607", "877845", "87814", "878205", "878768", "879398", "879724", "880367", "880498", "880699", "880909", "881039", "881597", "881675", "881827", "882426", "882799", "883104", "883352", "883454", "884104", "884448", "884787", "884875", "885220", "885729", "885818", "885941", "886494", "88666", "886708", "88680", "887207", "887559", "88767", "887753", "887842", "887974", "88807", "888715", "888736", "888741", "888914", "889266", "889475", "889593", "889607", "889760", "889924", "890025", "890224", "890449", "890957", "892216", "892611", "892743", "893024", "893512", "893565", "893726", "893906", "894098", "894374", "894378", "894379", "894390", "894531", "894546", "894557", "894589", "894598", "894626", "894629", "894849", "894859", "895111", "895217", "895266", "895431", "895439", "895444", "895453", "895540", "895556", "89560", "89577", "895800", "89586", "895907", "89597", "896055", "896140", "896153", "896255", "896267", "896410", "896523", "896670", "896738", "896746", "896829", "896918", "897061", "897202", "897260", "897263", "897420", "897786", "897915", "897917", "898040", "898262", "898766", "899274", "899281", "899303", "899543", "899743", "900099", "900749", "901059", "901284", "901834", "902094", "902466", "902585", "902854", "903487", "903580", "903855", "904032", "904210", "904293", "904776", "905370", "905777", "905931", "906097", "906496", "906511", "906660", "906852", "907685", "907876", "908026", "90818", "908268", "908324", "908347", "908464", "90870", "908817", "90894", "909095", "909109", "90913", "909245", "909469", "909611", "909625", "909980", "910312", "910435", "910608", "910762", "911219", "911914", "912355", "912775", "913291", "913568", "914030", "914031", "914458", "914632", "914878", "915005", "915163", "915320", "915435", "915728", "917096", "917097", "917733", "917762", "918106", "918146", "91829", "918344", "91870", "918893", "919008", "919059", "919143", "919570", "91959", "919683", "920158", "920259", "920384", "920891", "921088", "921266", "921511", "922405", "922851", "923237", "923410", "923846", "924128", "924384", "924746", "925371", "925540", "926020", "926041", "926118", "92617", "926240", "926649", "926782", "926882", "92727", "927463", "927491", "927569", "927595", "928026", "928328", "928510", "928795", "929582", "929746", "930068", "930173", "930481", "930667", "931282", "931406", "931416", "931421", "931528", "931658", "931662", "931668", "931769", "931773", "931789", "931794", "931809", "931812", "931920", "931933", "931943", "931949", "932060", "932070", "932077", "932079", "932201", "932209", "932215", "932298", "932386", "932396", "932398", "932402", "932415", "932648", "932748", "932900", "933015", "933182", "933437", "933616", "933867", "934047", "934094", "934114", "934176", "934415", "934460", "934469", "934561", "934679", "934692", "934941", "935195", "935260", "935602", "93574", "935934", "93604", "936113", "93617", "936418", "936628", "936728", "937006", "937239", "937247", "937326", "937416", "937433", "937830", "937839", "937943", "938236", "938422", "938435", "938637", "939097", "939217", "939389", "939538", "939842", "939973", "940403", "940686", "940704", "94071", "940808", "940944", "940973", "941614", "941675", "941745", "941764", "942954", "943239", "943245", "943758", "94384", "94386", "944115", "944199", "944214", "944686", "944895", "945320", "945422", "94559", "94560", "94561", "945646", "94565", "94566", "94569", "94571", "94572", "94573", "94574", "94590", "946041", "946254", "946389", "946394", "946870", "947173", "948037", "948129", "948408", "948870", "948970", "949277", "949294", "949957", "949960", "950466", "950567", "950569", "951313", "951337", "951550", "951846", "952029", "952034", "952146", "952942", "953116", "95312", "953141", "953144", "95334", "953438", "95347", "953794", "954770", "955001", "955376", "955708", "956765", "956900", "957187", "957188", "958072", "958178", "958438", "959189", "960041", "960088", "961121", "961884", "961941", "961978", "962782", "963281", "963734", "963749", "964106", "964239", "964381", "964793", "965141", "96554", "965541", "965837", "96587", "96621", "966618", "967049", "969062", "969185", "969379", "969383", "969923", "970070", "970216", "970565", "970907", "97154", "971825", "972081", "972605", "972710", "97346", "973565", "973687", "973702", "973964", "974102", "974126", "974138", "974219", "974223", "974363", "974367", "974380", "974387", "974390", "974392", "974487", "974491", "974512", "974515", "974517", "974518", "974575", "974578", "974587", "974630", "974636", "974826", "974848", "974860", "974869", "974937", "974939", "974943", "974945", "974958", "97518", "97537", "975444", "975830", "975863", "976071", "976125", "976355", "976836", "976856", "977013", "977310", "977394", "977486", "977815", "977993", "978189", "978335", "978711", "978736", "978738", "978846", "979166", "979549", "979683", "980330", "980447", "980558", "981155", "981371", "981392", "981559", "981854", "982034", "982085", "982099", "982605", "982887", "983105", "983169", "983186", "983714", "98379", "983965", "98420", "984313", "98445", "984556", "98463", "984839", "986174", "986892", "988438", "988638", "989272", "989528", "990273", "990379", "990599", "990750", "990802", "990918", "991033", "991062", "99120", "991205", "991301", "991399", "992055", "99232", "992411", "992455", "992693", "992991", "993163", "993337", "993785", "993828", "994322", "995397", "996344", "997094", "997563", "997850", "997959", "998221", "998623", "998783", "998990", "99933", "999770" ], "in_progress": { "1027811": { "title": "Kernel API specification and validation", "url": "https://lwn.net/Articles/1027811/", "downloaded": 0 }, "1029189": { "title": "SFrame-based stack unwinding for the kernel", "url": "https://lwn.net/Articles/1029189/", "downloaded": 0 }, "1029077": { "title": "Toward the unification of kselftests and KUnit", "url": "https://lwn.net/Articles/1029077/", "downloaded": 0 } } } -
上面生成的html文件的文件名有的无法被window识别,然后又让AI写了下面的脚本,对指定目录下的html文件的文件名进行处理,并将处理后的文件拷贝到新的目录下:
fix_filenames.py
#!/usr/bin/env python3 import os import re import argparse import shutil import unicodedata from pathlib import Path def sanitize_filename(filename: str) -> str: """ 生成兼容Windows的文件名(保留非拉丁字符) 参数: filename: 原始文件名 返回: str: 安全文件名 """ base, ext = os.path.splitext(filename) normalized = unicodedata.normalize('NFKC', base) # 全角转半角处理 safe_name = re.sub(r'[<>:"/\\|?*\x00-\x1F\x7F]', '_', normalized) # 过滤非法字符 safe_name = safe_name.strip('. ') # 移除首尾空格和点 # 处理Windows保留文件名(如CON, PRN等) windows_reserved = {'CON', 'PRN', 'AUX', 'NUL', 'COM1', 'LPT1'} if safe_name.upper() in windows_reserved: safe_name = '_' + safe_name # 空文件名保护 if not safe_name: safe_name = 'untitled' # 文件名长度截断(Windows最大255字符) max_length = 255 - len(ext) return safe_name[:max_length] + ext if len(safe_name) > max_length else safe_name + ext def process_and_copy_files(src_dir: str, dest_dir: str): """ 处理文件并拷贝到目标目录(自动创建目标目录) 参数: src_dir: 源目录路径 dest_dir: 目标目录路径 """ # 自动递归创建目标目录[7](@ref) Path(dest_dir).mkdir(parents=True, exist_ok=True) # 遍历源目录所有HTML文件 for root, _, files in os.walk(src_dir): for filename in files: if filename.lower().endswith(('.html', '.htm')): src_path = Path(root) / filename safe_name = sanitize_filename(filename) dest_path = Path(dest_dir) / safe_name # 处理文件名冲突(自动添加序号)[5](@ref) counter = 1 while dest_path.exists(): stem, ext = os.path.splitext(safe_name) dest_path = Path(dest_dir) / f"{stem}_{counter}{ext}" counter += 1 # 拷贝文件(保留元数据)[2,5](@ref) shutil.copy2(str(src_path), str(dest_path)) print(f"已拷贝: {src_path} → {dest_path}") if __name__ == "__main__": # 命令行参数解析 parser = argparse.ArgumentParser( description="HTML文件名处理器 - 安全拷贝文件到目标目录", formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument('-s', '--source', required=True, help="源目录路径(包含待处理的HTML文件)") parser.add_argument('-o', '--output', required=True, help="目标目录路径(处理后的文件保存位置)") args = parser.parse_args() # 验证源目录有效性 if not Path(args.source).is_dir(): print(f"错误:源目录不存在 - {args.source}") exit(1) # 执行处理 process_and_copy_files(args.source, args.output) print(f"\n✅ 处理完成!共处理 {len(list(Path(args.source).rglob('*.html')))} 个文件") print(f"输出目录: {Path(args.output).resolve()}")
本文来自博客园,作者:dolinux,未经同意,禁止转载

浙公网安备 33010602011771号