From acb43dadc5414193b48777dad0d8ff25baa523f3 Mon Sep 17 00:00:00 2001 From: badhope Date: Wed, 4 Mar 2026 16:09:01 +0800 Subject: [PATCH] Add comprehensive tools collection with web spider and system management tools --- comprehensive-tools/README.md | 68 ++++++++ .../__pycache__/main.cpython-314.pyc | Bin 0 -> 7004 bytes .../__pycache__/spider.cpython-314.pyc | Bin 0 -> 4879 bytes .../__pycache__/system_tools.cpython-314.pyc | Bin 0 -> 5003 bytes comprehensive-tools/main.py | 152 ++++++++++++++++++ comprehensive-tools/spider.py | 81 ++++++++++ comprehensive-tools/system_tools.py | 97 +++++++++++ comprehensive-tools/test.py | 48 ++++++ 8 files changed, 446 insertions(+) create mode 100644 comprehensive-tools/README.md create mode 100644 comprehensive-tools/__pycache__/main.cpython-314.pyc create mode 100644 comprehensive-tools/__pycache__/spider.cpython-314.pyc create mode 100644 comprehensive-tools/__pycache__/system_tools.cpython-314.pyc create mode 100644 comprehensive-tools/main.py create mode 100644 comprehensive-tools/spider.py create mode 100644 comprehensive-tools/system_tools.py create mode 100644 comprehensive-tools/test.py diff --git a/comprehensive-tools/README.md b/comprehensive-tools/README.md new file mode 100644 index 0000000..649ef99 --- /dev/null +++ b/comprehensive-tools/README.md @@ -0,0 +1,68 @@ +# 综合工具集合 + +本项目提供了一个综合性的工具集合,包含两个主要功能模块:网络爬虫工具和系统管理工具。 + +## 功能模块 + +### 1. 网络爬虫工具 +- 支持自定义URL输入和爬取规则配置 +- 包含数据提取、存储和导出功能 +- 实现基本的反爬机制和错误处理 +- 支持JSON和CSV格式数据导出 + +### 2. 系统管理工具 +- 批处理文本文件自动强制删除功能 +- 文件强制删除的安全确认机制 +- 系统强制关机功能及定时关机选项 +- 系统重启功能及定时重启选项 + +## 安装依赖 + +```bash +pip install requests beautifulsoup4 +``` + +## 使用方法 + +1. 运行主程序 + +```bash +python main.py +``` + +2. 选择功能模块 + +### 网络爬虫工具使用示例 + +1. 选择"1. 网络爬虫工具" +2. 选择"1. 开始爬取" +3. 输入起始URL,例如:`https://example.com` +4. 根据提示设置爬取规则(可选) +5. 爬取完成后选择是否保存数据及保存格式 + +### 系统管理工具使用示例 + +1. 选择"2. 系统管理工具" +2. 选择相应的功能: + - "1. 批量删除文本文件":删除指定目录下的所有文本文件 + - "2. 删除指定文件":删除用户指定的文件 + - "3. 关闭系统":关闭计算机 + - "4. 重启系统":重启计算机 + +## 注意事项 + +- 网络爬虫工具遵循robots.txt规则,请勿用于非法爬取 +- 系统管理工具的关机和重启功能需要管理员权限 +- 批量删除文件时请谨慎操作,建议先备份重要数据 + +## 代码结构 + +- `main.py`:主程序,提供用户界面 +- `spider.py`:网络爬虫模块 +- `system_tools.py`:系统管理工具模块 +- `test.py`:测试文件 +- `README.md`:使用说明 + +## 贡献 + +欢迎提交问题和改进建议。 diff --git a/comprehensive-tools/__pycache__/main.cpython-314.pyc b/comprehensive-tools/__pycache__/main.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f92abd9f08bb755c6b7c6d1c2ebcdb5d197b4b62 GIT binary patch literal 7004 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 literal 0 HcmV?d00001 diff --git a/comprehensive-tools/__pycache__/spider.cpython-314.pyc b/comprehensive-tools/__pycache__/spider.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0800d98da8a7e162e12e655811652d423eae27f GIT binary patch literal 4879 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 VWkAoD=$VJ~7)7=1AOa0O{{;d83+Mm< literal 0 HcmV?d00001 diff --git a/comprehensive-tools/__pycache__/system_tools.cpython-314.pyc b/comprehensive-tools/__pycache__/system_tools.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6a1d8f521736fc3ee090ec33767637f708f9055 GIT binary patch literal 5003 zcmeHLYitwQ6~1H7_!Y-?V#j$W1BMV2NLUE31j1uUC{SoRq-NWuYZ-e&rt5gTcg7oH zX@MVI5!$T??6yfCQcblIX1k9_NL4FTiPEjqp92^YhEzgY9_1g9NQ>y7o;%}loNOrl z(O*@sHvQUg(OD2e$&J|PM3@M~par(e=+hP6R! zazwR-!$Lxk!(r7|C=cp+ zf>4s_FNpRUr&V}@P%kmPsD+sJ{AO3>XO8(1szV{V*Sbg)h9P)68%%~qBRa4ho|y`o z9YnL=Zs>8Q5aWb*yWVVQBrPFJZ;3HK-?!&kj@~kiQ0(8YfLXAD6A0C!SL_>Z>*DtH zeaEV_)w>MIUXQ`e_sie}jJ-6XgZ?7FL^!$+c4zDsvEF@&r-hDjE zCuKoQsAfsVK^rFFqB;g(Ibq^OQkek}M|n&x6n2wIdtp+wM#aQ{fQM9ymq=7MH8ruM zVKPvi`s%|(UQ(-yp`v((1d`-~@I8g@mHS4m(`DXK%a_%G(S0-Cit)|oHjj6m>&gVD zylZZF*Gzl-@~r|OZnYNn=9S-$(~)~hXl`>w(sxmokZn04A) zGrs-Y_78SsqB(DH+E+7v@Z7=7R;9H|S-vCZ+j+-V_k^~WZZq6~Y^Hk3+j7I(GDC#V zAIt=A`PSU``N#L2-!~!Te9hCI%5m2@*ThK96P)o>OxQEQOs(Qyd)w3cG=OSWJXwRv zY9=;kzL6bJ+#40!#^-Z(Kr8?$M}??`Va=IZ0U%ou316lo zR$;s!Qh+sNT?$~iLKqj;2AXx~Kpg z^t1ba`1H{)e*{4E@YkQ{aFnjtBVax%i+E%njXK!*2u;(i@^LwB=^-%1rYl&PKMtTp zqHrEzf(}eF1177-1o3bU5S1Q|#NSeFfG5(hAP-`)Y?c0@C;&jj`2=1LV*@4Z05JMG za03x@5I^~7r?Du?Dh(0@K{NoMweIUMQF$~XM+d`sNGP%qC`OEz2sMLa>2n~b(0zB= z+2J$8XHT3tF(FL3n{T+AXPjk~)s2p|7EDKz$ z{B32n`u4I7*PZpFdnTB>RrO=^w6~I=N5((pZO(a{r+p1mzLnQ~D?d7V@z{l97vmS= zlkGQ~x^DY+%rdCD;i(xdZ=Z7@yKBtyp)}F)!AZrxN?El{ac$4px~ARUDK~rF&1PzD zx;H4c4Va+bg1{wJjaC(XrUh<@DqQhaE&SlA-nc^WB+YQ?L1%F*)FCFV4gu(f@GVqL zP^IQ=H6o44lMeZlnqt<$t4(y^_5A}>zX%q2Yr><2@IqMb( zr&zt_^%eCBz>D)+6jZ|Y&G|5fwc7%y|J8b>OX)$)QK)pF=76hT2Nh`189Dmsg%Af- zLrId}L6Z~HxuTlEl_L9l@ZROeGH#dNTFKjN$2w?J1oTGY{7<*U|*E55)X+uCbhPNQ(Q=6<(>w;#yi7dmkc2G4Z#NkU0?1M2TbzL4MWMK$u z2r16jsiNz={NvavA61WyrE-_kBp<{%VXo@Krv&7gkAljFLRygQY zgWFh9SYM}FTMPq>CN~oU9|Jjs9=Uxp{#vE(@J)Z;=-z3!|LnVG-u=nROd#i8NwTbe zb6WYXEl>9yZ{_nDcNHXi&?U&TZnA9B ztdzIsoE!h{ts)uSUj1U0VCA0!ZM)Z@YrYyn*Ok2PGhgd;z3w*u#mxZ!e_Z&V!iC4D zfBInT^E@uJzZ4fRFUb)M9}q8tg)%NLQG^PWdT{8dU|0Z9!0X|b;SE6gFi8jLY8?sk zA_NPHU?3mwZ5We)!drmMg8;_xnS?NWmm$0p$l`!?&+0|t+LGOy-8y+dDc_lM?)vYC>)LE2dsr!dE$3W6AFg;0**8ghhk{g3(A0xT z0t%LpKS2oQ!Ji&RJ@iO>-TkO#57ekE#A@4UlIDh*pYdT0x6m6IK#4U4(Q3 zQ7ut self.max_depth or start_url in self.visited_urls: + return [] + + self.visited_urls.add(start_url) + print(f'Crawling: {start_url}') + + try: + time.sleep(random.uniform(1, 3)) # 反爬机制 + response = requests.get(start_url, headers=self.headers, proxies=self.proxies, timeout=10, verify=False) # 禁用SSL验证 + response.raise_for_status() + except Exception as e: + print(f'Error crawling {start_url}: {e}') + return [] + + soup = BeautifulSoup(response.text, 'html.parser') + data = [] + + if rules: + for rule in rules: + elements = soup.select(rule['selector']) + for element in elements: + item = {} + if 'extract' in rule: + for key, extractor in rule['extract'].items(): + if extractor == 'text': + item[key] = element.get_text(strip=True) + elif extractor.startswith('attr:'): + attr = extractor.split(':', 1)[1] + item[key] = element.get(attr, '') + data.append(item) + + links = [] + for a in soup.find_all('a', href=True): + href = a['href'] + absolute_url = urljoin(start_url, href) + parsed_url = urlparse(absolute_url) + if parsed_url.scheme in ['http', 'https']: + links.append(absolute_url) + + for link in links[:10]: # 限制爬取链接数量 + data.extend(self.crawl(link, rules, depth + 1)) + + return data + + def save_to_json(self, data, filename): + with open(filename, 'w', encoding='utf-8') as f: + json.dump(data, f, ensure_ascii=False, indent=2) + + def save_to_csv(self, data, filename): + if not data: + return + + keys = data[0].keys() + with open(filename, 'w', newline='', encoding='utf-8') as f: + writer = csv.DictWriter(f, fieldnames=keys) + writer.writeheader() + writer.writerows(data) diff --git a/comprehensive-tools/system_tools.py b/comprehensive-tools/system_tools.py new file mode 100644 index 0000000..f800654 --- /dev/null +++ b/comprehensive-tools/system_tools.py @@ -0,0 +1,97 @@ +import os +import shutil +import subprocess +import time +import ctypes + +class SystemTools: + def __init__(self): + pass + + def delete_files(self, file_paths, force=False): + """删除文件列表""" + deleted = [] + failed = [] + + for file_path in file_paths: + if not os.path.exists(file_path): + failed.append((file_path, 'File not found')) + continue + + if not force: + confirm = input(f'Are you sure you want to delete {file_path}? (y/n): ') + if confirm.lower() != 'y': + failed.append((file_path, 'User cancelled')) + continue + + try: + if os.path.isdir(file_path): + shutil.rmtree(file_path) + else: + os.remove(file_path) + deleted.append(file_path) + print(f'Deleted: {file_path}') + except Exception as e: + failed.append((file_path, str(e))) + print(f'Failed to delete {file_path}: {e}') + + return {'deleted': deleted, 'failed': failed} + + def batch_delete_text_files(self, directory, force=False): + """批量删除目录中的文本文件""" + if not os.path.exists(directory): + print(f'Directory not found: {directory}') + return {'deleted': [], 'failed': []} + + text_files = [] + for root, dirs, files in os.walk(directory): + for file in files: + if file.endswith('.txt'): + text_files.append(os.path.join(root, file)) + + print(f'Found {len(text_files)} text files to delete') + return self.delete_files(text_files, force) + + def shutdown_system(self, force=False, timeout=0): + """关闭系统""" + if not force: + confirm = input('Are you sure you want to shutdown the system? (y/n): ') + if confirm.lower() != 'y': + print('Shutdown cancelled') + return False + + if timeout > 0: + print(f'System will shutdown in {timeout} seconds...') + time.sleep(timeout) + + try: + if os.name == 'nt': # Windows + subprocess.run(['shutdown', '/s', '/t', '0'], check=True) + else: # Unix-like + subprocess.run(['shutdown', '-h', 'now'], check=True) + return True + except Exception as e: + print(f'Error shutting down system: {e}') + return False + + def restart_system(self, force=False, timeout=0): + """重启系统""" + if not force: + confirm = input('Are you sure you want to restart the system? (y/n): ') + if confirm.lower() != 'y': + print('Restart cancelled') + return False + + if timeout > 0: + print(f'System will restart in {timeout} seconds...') + time.sleep(timeout) + + try: + if os.name == 'nt': # Windows + subprocess.run(['shutdown', '/r', '/t', '0'], check=True) + else: # Unix-like + subprocess.run(['shutdown', '-r', 'now'], check=True) + return True + except Exception as e: + print(f'Error restarting system: {e}') + return False diff --git a/comprehensive-tools/test.py b/comprehensive-tools/test.py new file mode 100644 index 0000000..a6d8606 --- /dev/null +++ b/comprehensive-tools/test.py @@ -0,0 +1,48 @@ +from spider import WebSpider +from system_tools import SystemTools + +# 测试网络爬虫 +def test_spider(): + print('测试网络爬虫...') + spider = WebSpider() + spider.set_max_depth(1) + + # 测试简单爬取 + url = 'https://example.com' + data = spider.crawl(url) + print(f'爬取到 {len(data)} 条数据') + + # 测试带规则的爬取 + rules = [{ + 'selector': 'a', + 'extract': { + 'text': 'text', + 'href': 'attr:href' + } + }] + data_with_rules = spider.crawl(url, rules) + print(f'带规则爬取到 {len(data_with_rules)} 条数据') + + # 测试保存功能 + if data_with_rules: + spider.save_to_json(data_with_rules, 'test_spider.json') + spider.save_to_csv(data_with_rules, 'test_spider.csv') + print('数据已保存到 test_spider.json 和 test_spider.csv') + +# 测试系统管理工具 +def test_system_tools(): + print('\n测试系统管理工具...') + system_tools = SystemTools() + + # 创建测试文件 + with open('test_file.txt', 'w') as f: + f.write('测试文件') + + # 测试删除文件 + result = system_tools.delete_files(['test_file.txt'], force=True) + print(f'删除文件结果: {result}') + +if __name__ == '__main__': + test_spider() + test_system_tools() + print('\n测试完成!')