├── .gitignore ├── README.md ├── cmpedu-downloader.py ├── cmpedu-downloader.user.js └── intro └── example.png /.gitignore: -------------------------------------------------------------------------------- 1 | .history -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cmpedu Downloader 2 | 3 | 机械工业出版社教育服务网资源下载,无需登录,无需教师权限,油猴脚本。 4 | 5 | ## 如何使用 6 | 7 | [点击安装油猴项目](https://greasyfork.org/scripts/483095) 8 | 9 | 进入书籍或资源详情页自动显示下载面板 10 | 11 | 支持以下网址格式: 12 | 13 | - `http://www.cmpedu.com/books/book/12345.htm` 14 | - `http://www.cmpedu.com/ziyuans/ziyuan/12345.htm` 15 | - `http://m.cmpedu.com/books/book/12345.htm` 16 | - `http://m.cmpedu.com/ziyuans/ziyuan/12345.htm` 17 | 18 | 19 |  20 | 21 | ## 免责声明 22 | 23 | **用途限制** 24 | 本项目仅供学习、研究及技术探讨使用,请勿将其用于任何违反法律法规或第三方服务条款的活动。 25 | 26 | **责任声明** 27 | 使用者须自行评估本程序的适用性和合法性。作者不对任何因使用本项目而导致的直接或间接后果负责,包括但不限于数据泄露、服务封禁或其他法律纠纷。 28 | 29 | **删除要求** 30 | 如果您选择下载或使用此代码,请在下载后 **24 小时内删除**。这是为了确保用户在合理时间内用于学习或研究目的,避免可能的滥用风险。 31 | 32 | 本项目与相关网站及其相关机构无任何关联。 33 | 34 | 本项目为开源项目,仅供技术交流使用。禁止将本程序用于商业目的或其他违反法律法规的行为。 35 | 36 | 用户在使用本程序时须严格遵守当地法律法规,任何违反法律的行为均由使用者自行承担。 37 | 38 | ## 侵权联系 39 | 40 | 如果您认为本项目侵犯了您的合法权益(如版权或知识产权),请通过以下方式联系我们,我们将在收到相关通知后尽快处理: 41 | 42 | 1. **电子邮件**: yanyao(#)email.com(请将 `#` 替换为 `@`) 43 | 2. **GitHub Issues**: 提交详细描述的 Issue,说明相关侵权行为。 44 | 45 | 我们将认真对待每一份投诉,并在确认后采取必要措施。 -------------------------------------------------------------------------------- /cmpedu-downloader.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup 3 | import re 4 | 5 | def get_all_resources(resource_divs): 6 | all_resources = [] 7 | for resource in resource_divs: 8 | resource_title = resource.find("div", class_="gjzy_listRTit").text.strip() 9 | resource_id = resource.find("a")["href"].split("/")[-1].split(".")[0] 10 | download_url = f"http://www.cmpedu.com/ziyuans/d_ziyuan.df?id={resource_id}" 11 | all_resources.append((resource_id, resource_title, download_url)) 12 | return all_resources 13 | 14 | def main(): 15 | while True: 16 | book_id = input("请输入BookID (输入 'exit' 退出程序): ") 17 | 18 | if book_id.lower() == 'exit': 19 | print("退出程序。") 20 | break 21 | 22 | url = f"http://www.cmpedu.com/ziyuans/index.htm?BOOK_ID={book_id}" 23 | 24 | try: 25 | response = requests.get(url) 26 | response.raise_for_status() 27 | 28 | soup = BeautifulSoup(response.text, 'html.parser') 29 | 30 | resource_divs = soup.find_all("div", class_="row gjzy_list") 31 | 32 | if resource_divs: 33 | print(f"\n资源目录在线查看:{url} \n") 34 | 35 | all_resources = get_all_resources(resource_divs) 36 | 37 | headers = { 38 | "Accept-Encoding": "gzip, deflate", 39 | "Connection": "keep-alive", 40 | "Accept": "text/html, */*; q=0.01", 41 | "User-Agent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", 42 | "Accept-Language": "en-US,en;q=0.9", 43 | "X-Requested-With": "XMLHttpRequest" 44 | } 45 | 46 | for resource_id, resource_title, download_url in all_resources: 47 | response = requests.get(download_url, headers=headers) 48 | if response.status_code == 200: 49 | download_links = re.findall(r'window\.location\.href=\'(https?://[^\'"]+)\'', response.text) 50 | if download_links: 51 | download_link = download_links[0] 52 | print(f"{resource_title} 下载链接: {download_link}") 53 | # try: 54 | # import webbrowser 55 | # webbrowser.open(download_link) 56 | # except Exception as e: 57 | # print(f"{resource_title} 打开下载链接失败: {e}") 58 | else: 59 | print(f"{resource_title} 下载链接未找到!") 60 | else: 61 | print(f"{resource_title} 下载请求失败! 状态码: {response.status_code}") 62 | 63 | else: 64 | print("没有找到资源信息。") 65 | 66 | except requests.exceptions.RequestException as e: 67 | print(f"发生请求错误: {e}") 68 | except Exception as e: 69 | print(f"发生错误: {e}") 70 | 71 | if __name__ == "__main__": 72 | main() 73 | -------------------------------------------------------------------------------- /cmpedu-downloader.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Cmpedu Resource Downloader 3 | // @namespace http://tampermonkey.net/ 4 | // @version 2.0 5 | // @description 机械工业出版社教育服务网资源下载,无需登录,无需教师权限,油猴脚本。 6 | // @author yanyaoli 7 | // @match *://*.cmpedu.com/ziyuans/ziyuan/* 8 | // @match *://*.cmpedu.com/books/book/* 9 | // @connect *.cmpedu.com 10 | // @grant GM_xmlhttpRequest 11 | // @grant GM_addStyle 12 | // ==/UserScript== 13 | 14 | (function() { 15 | 'use strict'; 16 | 17 | // 样式注入 18 | GM_addStyle(` 19 | .cmp-panel { position: fixed; top: 20px; right: 20px; width: 300px; max-height: 70vh; background: #ced6e0; border-radius: 12px; box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); z-index: 99999; font-family: 'Segoe UI', system-ui, sans-serif; overflow: hidden; transition: transform 0.2s ease; } 20 | .panel-header { padding: 16px; background: #a4b0be; border-bottom: 1px solid #747d8c; display: flex; justify-content: space-between; align-items: center; } 21 | .panel-title { margin: 0; font-size: 16px; color: #1a1a1a; font-weight: 600; } 22 | .close-btn { background: none; border: none; cursor: pointer; color: #6b7280; font-size: 24px; line-height: 1; padding: 4px; transition: color 0.2s; } 23 | .close-btn:hover { color: #1a1a1a; } 24 | .panel-content { padding: 16px; max-height: calc(70vh - 73px); overflow-y: auto; } 25 | .resource-item { padding: 12px 0; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #f0f0f0; cursor: pointer; } 26 | .resource-item:hover { color: #1e90ff; } 27 | .resource-item:last-child { border-bottom: none; } 28 | .skeleton { 29 | background: #f2f2f2; 30 | border-radius: 4px; 31 | height: 20px; 32 | width: 100%; 33 | margin-bottom: 12px; 34 | animation: pulse 1.5s infinite; 35 | } 36 | .skeleton:last-child { margin-bottom: 0; } 37 | .error-message { color: #dc3545; display: flex; align-items: center; gap: 8px; padding: 12px; background: #fff5f5; border-radius: 8px; margin: 8px 0; } 38 | @keyframes skeleton-loading { 39 | 0% { background-position: 200% 0; } 40 | 100% { background-position: -200% 0; } 41 | } 42 | @media (max-width: 480px) { .cmp-panel { width: 90%; right: 5%; left: auto; top: 10px; } } 43 | `); 44 | 45 | // 基础配置 46 | const isMobile = window.location.host.startsWith('m.'); 47 | const baseUrl = isMobile ? 'http://m.cmpedu.com' : 'http://www.cmpedu.com'; 48 | const panelId = "downloadPanel"; 49 | 50 | function extractBookId() { 51 | if (window.location.href.includes('books/book')) { 52 | return window.location.pathname.split("/").pop().split(".")[0]; 53 | } 54 | if (window.location.href.includes('ziyuans/ziyuan')) { 55 | const el = document.getElementById('BOOK_ID'); 56 | return el ? el.value : null; 57 | } 58 | return null; 59 | } 60 | 61 | function createPanel() { 62 | const panel = document.createElement('div'); 63 | panel.id = panelId; 64 | panel.className = 'cmp-panel'; 65 | panel.innerHTML = ` 66 |