尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Python+Selenium实现智能学时管理:浏览器自动化实战与防检测策略

Python+Selenium实现智能学时管理:浏览器自动化实战与防检测策略
📅 发布时间:2026/7/17 7:42:04

1. 项目概述与核心需求解析

最近在技术社区和论坛里,经常看到有朋友在讨论如何“解放双手”,处理一些重复性的网页操作任务。其中,一个高频出现的场景就是在线课程的学时管理。很多继续教育、职业培训平台都要求学员完成一定的在线视频观看时长,但手动挂机不仅耗时,还容易因为网络波动、页面卡顿导致学时记录失败。基于这个普遍痛点,我结合自己多年的自动化测试和脚本开发经验,用Python和一点点JavaScript,配合Selenium这个老牌浏览器自动化工具,折腾出了一个相对智能的学时管理脚本。这本质上是一个**浏览器自动化(Browser Automation)**项目,核心目标不是“作弊”,而是将人从枯燥、重复的“点击-等待-刷新”循环中解放出来,确保学习进程的稳定推进,尤其适合课程内容已掌握、仅需完成形式上学时要求的场景。

这个脚本的核心思路是模拟一个真实用户的操作:打开浏览器,登录学习平台,找到课程列表,逐个进入课程播放页面,然后智能地维持播放状态。它需要处理各种意外情况,比如弹窗广告、睡眠检测、页面超时、验证码(虽然复杂的验证码通常需要更高级的方案)等。整个方案建立在Selenium WebDriver的基础上,用Python作为主控逻辑语言,并在必要时注入JavaScript来执行一些Selenium原生API不太方便或无法实现的操作。对于有Python和Web基础的朋友来说,实现起来并不复杂,但其中有很多细节和“坑”需要提前注意,这也是本文想重点分享的。

2. 技术选型与工具链搭建

为什么选择Python + Selenium + JS这个组合?这是经过实际场景权衡后的结果。

2.1 核心工具:Selenium WebDriver

Selenium是Web自动化测试的事实标准,但它绝不仅限于测试。它的优势在于:

  • 跨浏览器:通过对应的WebDriver(如ChromeDriver、GeckoDriver),可以控制Chrome、Firefox、Edge等主流浏览器,模拟真实环境。
  • 元素定位强大:支持通过ID、Name、XPath、CSS Selector等多种方式定位页面元素,这对于操作复杂的网页结构至关重要。
  • 模拟真实交互:可以执行点击、输入、滚动等几乎所有用户操作,比单纯的HTTP请求模拟(如requests库)更能应对依赖JavaScript渲染的现代网页。
  • 生态成熟:社区活跃,遇到问题容易找到解决方案。

对于挂课场景,我们需要的正是这种能“看到”页面并与之“交互”的能力,而不是简单的接口调用。

2.2 主控语言:Python

Python几乎是自动化脚本的首选,原因如下:

  • 语法简洁:代码可读性高,开发效率快,适合快速构建原型和处理复杂逻辑。
  • 库生态丰富:除了Selenium (selenium),还需要处理等待(WebDriverWait)、异常、时间调度(time,schedule)等,Python都有成熟的内置库或第三方库支持。
  • 易于集成:如果需要后续加入日志记录、邮件通知、配置文件管理等功能,Python都能轻松实现。

2.3 辅助利器:JavaScript

Selenium虽然强大,但有些操作通过注入JavaScript来执行会更加直接和高效,尤其是在处理某些原生事件或获取/修改DOM属性时。例如:

  • 直接执行播放:driver.execute_script("document.querySelector('video').play()")
  • 修改视频播放速率(如果需要快速过掉已掌握内容):driver.execute_script("document.querySelector('video').playbackRate = 2.0")
  • 检测视频播放状态:driver.execute_script("return document.querySelector('video').ended")

2.4 环境准备清单

在开始编码前,需要准备好以下环境,我以Windows系统下的Chrome浏览器为例:

  1. 安装Python:从官网下载3.7及以上版本安装,务必勾选“Add Python to PATH”。
  2. 安装Selenium库:在命令行中运行pip install selenium。
  3. 下载浏览器驱动:
    • 查看你的Chrome浏览器版本(在地址栏输入chrome://version/)。
    • 访问ChromeDriver官网或国内镜像站,下载与你的Chrome浏览器大版本号完全一致的ChromeDriver。
    • 将下载的chromedriver.exe文件放在一个固定目录(如C:\WebDriver\),并将该目录添加到系统的PATH环境变量中。这是最稳妥的方式,可以避免后续代码中指定路径的麻烦。

注意:浏览器和驱动版本的匹配是新手最容易踩的坑之一。版本不匹配会导致Selenium无法启动浏览器。建议定期更新驱动以匹配浏览器自动升级。

3. 脚本核心架构与设计思路

一个健壮的挂课脚本不能是简单的线性操作,必须考虑容错、恢复和日志。我的脚本核心架构分为以下几个模块,如下图所示(逻辑流程):

graph TD A[脚本启动] --> B[初始化配置<br>读取账号/课程列表]; B --> C{登录平台}; C -- 成功 --> D[遍历课程列表]; C -- 失败 --> E[记录日志并告警] --> Z[脚本结束]; subgraph D [核心播放循环] D1[进入课程页面] --> D2{检测页面状态与元素}; D2 -- 正常 --> D3[执行播放操作<br>(点击/JS注入)]; D2 -- 异常(弹窗/卡死) --> D4[异常处理程序] --> D2; D3 --> D5[进入监控循环]; subgraph D5 [监控循环] D5_1[等待N秒] --> D5_2{检测播放状态}; D5_2 -- 播放中 --> D5_3{检测学时进度}; D5_2 -- 已停止/出错 --> D5_4[尝试恢复播放] --> D5_1; D5_3 -- 未完成 --> D5_1; D5_3 -- 已完成 --> D6[记录进度并退出循环]; end end D6 --> F{还有下一门课?}; F -- 是 --> D; F -- 否 --> G[生成学习报告] --> Z;

3.1 配置管理模块

硬编码账号密码和URL是极不安全的做法。我使用config.ini文件或config.py来管理配置。

; config.ini 示例 [Platform] login_url = https://your-learning-platform.com/login username = your_username password = your_password [Browser] headless = False ; 是否无头模式,调试时建议False window_size = 1920,1080 implicitly_wait = 10 ; 隐式等待时间(秒) [Behavior] course_list = course_id_1, course_id_2 ; 课程ID列表 check_interval = 60 ; 监控播放状态的间隔(秒) playback_rate = 1.0 ; 播放速率,1.0为正常速度

在Python中,使用configparser库来读取这些配置。

3.2 浏览器驱动与会话管理模块

这是脚本的引擎。我通常会封装一个浏览器工具类,负责驱动的初始化、退出和提供一些常用方法。

from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options import configparser class BrowserManager: def __init__(self, config): self.config = config self.driver = None def start(self): chrome_options = Options() if self.config.getboolean('Browser', 'headless'): chrome_options.add_argument('--headless') # 无头模式,不显示GUI chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') # 防止被检测为自动化工具(重要!) chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option('useAutomationExtension', False) chrome_options.add_argument('--disable-blink-features=AutomationControlled') # 使用Service指定驱动路径(如果PATH已配置,可省略) # service = Service(executable_path='C:/WebDriver/chromedriver.exe') # self.driver = webdriver.Chrome(service=service, options=chrome_options) self.driver = webdriver.Chrome(options=chrome_options) # 执行CDP命令,进一步隐藏自动化特征 self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', { 'source': ''' Object.defineProperty(navigator, 'webdriver', { get: () => undefined }); ''' }) self.driver.implicitly_wait(self.config.getint('Browser', 'implicitly_wait')) self.driver.set_window_size(*map(int, self.config['Browser']['window_size'].split(','))) return self.driver def quit(self): if self.driver: self.driver.quit()

3.3 登录与认证模块

不同平台的登录方式千差万别,可能是表单提交,也可能是扫码。核心是定位到用户名、密码输入框和提交按钮。这里必须使用显式等待(Explicit Wait),确保元素加载完成再操作。

from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def login(driver, config): driver.get(config['Platform']['login_url']) try: # 等待用户名输入框出现 username_input = WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.ID, "username")) # 根据实际页面元素ID修改 ) username_input.send_keys(config['Platform']['username']) password_input = driver.find_element(By.ID, "password") password_input.send_keys(config['Platform']['password']) submit_button = driver.find_element(By.XPATH, "//button[@type='submit']") submit_button.click() # 等待登录成功后的某个标志性元素出现,例如用户头像 WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.CLASS_NAME, "user-avatar")) ) print("登录成功!") return True except Exception as e: print(f"登录失败: {e}") # 这里可以截图保存,方便排查 driver.save_screenshot('login_failed.png') return False

3.4 课程播放与状态维护模块

这是最核心的部分。其逻辑是:进入播放页 -> 寻找视频元素 -> 开始播放 -> 循环监控。

  • 寻找并操作视频元素:现代网页的视频播放器可能是<video>标签,也可能是基于Flash或特殊播放器(如DPlayer、ckplayer)。对于HTML5的<video>,我们可以用JS直接控制。对于复杂播放器,可能需要模拟点击其自带的播放按钮。
def play_course(driver, course_url, check_interval, playback_rate): driver.get(course_url) time.sleep(5) # 等待页面初步加载 # 方案1:尝试通过JS直接控制HTML5 video标签 try: # 设置播放速率 driver.execute_script(f"document.querySelector('video').playbackRate = {playback_rate};") # 开始播放 driver.execute_script("document.querySelector('video').play();") print("通过JS启动视频播放。") except Exception as js_e: print(f"JS控制失败,尝试查找播放按钮: {js_e}") # 方案2:查找并点击播放按钮 try: # 这里的定位器需要根据实际页面调整,可能需要用XPath或CSS Selector play_button = WebDriverWait(driver, 15).until( EC.element_to_be_clickable((By.XPATH, "//div[@class='play-btn']")) ) play_button.click() print("通过点击播放按钮启动视频。") except Exception as click_e: print(f"无法找到或点击播放按钮: {click_e}") return False # 进入监控循环 return monitor_playback(driver, check_interval) def monitor_playback(driver, interval): """监控视频播放状态""" while True: time.sleep(interval) # 每隔一段时间检查一次 try: # 检查视频是否仍在播放(非结束状态) is_ended = driver.execute_script("return document.querySelector('video').ended;") current_time = driver.execute_script("return document.querySelector('video').currentTime;") duration = driver.execute_script("return document.querySelector('video').duration;") print(f"监控点: 当前时间 {current_time:.1f}s, 总时长 {duration:.1f}s, 是否结束: {is_ended}") if is_ended: print("视频播放结束。") # 检查是否有“下一节”按钮并点击,或者退出循环 # ... break # 检查页面是否有“继续学习”或“确认”弹窗(防睡眠) if check_and_handle_popup(driver): continue # 可以添加其他检查,比如网络断开、页面崩溃等 except Exception as e: print(f"监控过程中发生异常: {e}") # 尝试恢复,比如刷新页面并重新播放 if not recover_playback(driver): print("恢复播放失败,退出本课程。") break return True

3.5 异常处理与恢复模块

网络环境不稳定,平台也可能有防挂机机制。一个健壮的脚本必须能处理:

  • 弹窗处理:如“您还在学习吗?”的确认框。需要定期查找并点击。
  • 播放中断:视频卡住、页面崩溃。通过try...except捕获异常,并尝试刷新页面、重新登录或重新播放。
  • 元素定位失败:页面结构可能变化。需要准备多套定位策略,并记录日志。
def check_and_handle_popup(driver): """检查并处理常见弹窗""" popup_selectors = [ (By.XPATH, "//button[contains(text(), '继续学习')]"), (By.XPATH, "//div[@class='confirm-dialog']//button[contains(text(), '确定')]"), (By.CLASS_NAME, "el-button--primary"), # 示例:Element UI的主按钮 ] for by, selector in popup_selectors: try: # 快速查找,不使用隐式等待 element = driver.find_element(by, selector) if element.is_displayed(): element.click() print(f"检测并点击了弹窗按钮: {selector}") time.sleep(2) return True except: continue return False def recover_playback(driver): """尝试恢复播放""" try: driver.refresh() time.sleep(8) # 等待刷新后页面加载 # 重新尝试播放逻辑(可以调用play_course中的部分代码) driver.execute_script("document.querySelector('video').play();") print("已刷新页面并尝试重新播放。") return True except Exception as e: print(f"恢复播放失败: {e}") return False

3.6 日志与报告模块

记录脚本运行状态至关重要,方便事后排查问题和验证学习进度。可以使用Python内置的logging模块。

import logging from datetime import datetime def setup_logging(): logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(f'learning_bot_{datetime.now().strftime("%Y%m%d")}.log'), logging.StreamHandler() # 同时输出到控制台 ] ) return logging.getLogger(__name__) # 在脚本中使用 logger = setup_logging() logger.info("开始处理课程《Python高级编程》") logger.warning("检测到弹窗,已处理") logger.error("登录失败,请检查网络或账号")

4. 完整脚本实现与关键代码解析

将上述模块组合起来,就构成了主程序。下面是一个简化但可运行的核心流程示例。

# main.py import time import configparser from browser_manager import BrowserManager from login import login from course_player import play_course, monitor_playback from utils import setup_logging def main(): logger = setup_logging() config = configparser.ConfigParser() config.read('config.ini') browser_manager = BrowserManager(config) driver = None try: driver = browser_manager.start() logger.info("浏览器启动成功。") # 1. 登录 if not login(driver, config): logger.error("登录失败,脚本终止。") return # 2. 获取课程列表 course_ids = config['Behavior']['course_list'].split(',') base_course_url = "https://your-platform.com/course/{}" # 根据实际URL模式修改 # 3. 遍历课程 for idx, course_id in enumerate(course_ids): course_url = base_course_url.format(course_id.strip()) logger.info(f"开始学习课程 [{idx+1}/{len(course_ids)}]: {course_url}") success = play_course( driver, course_url, check_interval=config.getint('Behavior', 'check_interval'), playback_rate=config.getfloat('Behavior', 'playback_rate') ) if success: logger.info(f"课程 {course_id} 学习完成或已达到目标。") else: logger.warning(f"课程 {course_id} 学习过程中断或失败。") # 短暂间隔,避免请求过于频繁 time.sleep(5) logger.info("所有课程学习任务已完成!") except KeyboardInterrupt: logger.info("用户中断脚本执行。") except Exception as e: logger.exception(f"脚本运行过程中发生未预期异常: {e}") finally: if driver: browser_manager.quit() logger.info("浏览器已关闭。") if __name__ == "__main__": main()

关键点解析:

  1. config.ini的使用:将所有可配置项外置,使得脚本无需修改代码即可适应不同的账号、课程和平台(只要页面结构类似)。
  2. 浏览器启动选项:--disable-blink-features=AutomationControlled和CDP命令是为了避免被网站检测到自动化工具。一些教育平台会检测navigator.webdriver属性,这些设置可以将其隐藏。
  3. 显式等待 vs 隐式等待:WebDriverWait是显式等待,用于在特定条件(如元素出现、可点击)满足后再进行下一步,更精确可靠。implicitly_wait是隐式等待,是全局设置,在查找元素时如果未立即找到会轮询等待一段时间。最佳实践是使用显式等待,并设置一个较短的隐式等待作为兜底。
  4. JavaScript注入:driver.execute_script()是Selenium与页面深度交互的利器。它可以直接在浏览器上下文中执行JS代码,用于获取信息或执行操作,效率往往比多次调用Selenium API更高。
  5. 异常处理的层级:在try...except块中,应尽可能捕获具体的异常,并在except块中进行有针对性的恢复操作,而不是简单地打印错误。

5. 高级优化与防检测策略

基础脚本能跑起来,但在实际对抗中,平台方会有各种反自动化措施。我们需要让脚本行为更接近真人。

5.1 模拟人类操作节奏

真人不会以固定的、毫秒级精确的间隔操作。引入随机延迟和随机动作。

import random def human_like_delay(min_sec=1, max_sec=3): """模拟人类操作间隔""" time.sleep(random.uniform(min_sec, max_sec)) def human_like_click(element): """模拟人类点击(先移动鼠标到元素上)""" # Selenium的click()已经比较自然,但可以加入更复杂的模拟 # 例如使用ActionChains from selenium.webdriver.common.action_chains import ActionChains actions = ActionChains(driver) actions.move_to_element(element).pause(random.uniform(0.1, 0.5)).click().perform()

5.2 随机化浏览行为

在监控间隔期间,可以随机执行一些无关但自然的操作,如轻微滚动、鼠标移动。

def random_browsing_behavior(driver): """执行随机浏览行为""" behaviors = [ lambda: driver.execute_script("window.scrollBy(0, arguments[0]);", random.randint(50, 200)), lambda: driver.execute_script("window.scrollBy(0, arguments[0]);", -random.randint(50, 200)), # 模拟鼠标在页面某区域移动(需要更复杂的JS或ActionChains) ] if random.random() > 0.7: # 30%的概率执行一次随机行为 random.choice(behaviors)() print("执行了一次随机浏览行为。")

5.3 使用更隐蔽的浏览器模式

  • 用户数据目录:启动浏览器时指定一个真实的用户数据目录(--user-data-dir),这样浏览器会加载真实的Cookies、历史记录,更像一个常驻用户。
    chrome_options.add_argument(f"--user-data-dir=C:\\Users\\YourName\\AppData\\Local\\Google\\Chrome\\User Data\\TestProfile")
  • 禁用自动化特征:如前所述,必须使用excludeSwitches和CDP命令。
  • 代理IP:如果平台对同一IP长时间访问有限制,可以考虑使用代理池。但这会增加复杂性和成本。

5.4 应对智能验证码

如果平台在检测到异常行为后弹出验证码(如滑块、点选),简单的Selenium脚本就很难处理了。这时需要考虑:

  1. 降低被检测概率:通过上述所有优化手段,尽量模拟真人。
  2. 集成打码平台:商业打码平台提供API,可以将验证码图片发送过去,返回识别结果或操作坐标。但这需要额外费用,且违反平台规则的风险极高。
  3. 人工介入:设计脚本在遇到验证码时暂停,发出通知(如邮件、微信),等待人工处理后再继续。这保证了脚本的可用性,但失去了全自动的意义。

重要提醒:使用自动化脚本完成学习平台强制要求的行为,可能违反平台的服务条款。轻则学习记录被清空、账号被封禁,重则可能涉及相关责任。此脚本仅用于技术学习与研究自动化测试、浏览器控制等知识,请务必在符合平台规则和法律法规的前提下谨慎使用。理解原理后,你可以将这套技术应用于合法的自动化场景,如自动测试网站功能、定时抓取公开数据、自动完成日常重复性报表操作等。

6. 常见问题排查与实战心得

在实际部署和运行过程中,你几乎一定会遇到下面这些问题。这里是我踩过坑后的经验总结。

6.1 元素定位失败(NoSuchElementException)

这是最常见的问题。

  • 原因1:页面未加载完成。解决方案:在操作前增加等待。优先使用WebDriverWait配合EC.presence_of_element_located或EC.element_to_be_clickable。
  • 原因2:元素在iframe或shadow DOM内。解决方案:需要先切换到对应的iframe (driver.switch_to.frame(frame_element)),或使用JavaScript穿透shadow DOM。
  • 原因3:页面结构动态变化,定位器失效。解决方案:准备更健壮的定位器,如使用相对路径的XPath(避免绝对路径),或使用多个属性组合定位。同时,将定位器字符串也放到配置文件中,便于修改。
  • 原因4:页面有多个匹配元素。解决方案:使用find_elements获取列表,再按索引或条件筛选。

6.2 浏览器被检测为自动化工具

表现为登录失败、页面跳转异常或直接提示“请勿使用自动化工具”。

  • 解决方案:务必应用第5节中提到的所有防检测策略。特别是excludeSwitches和CDP命令。也可以尝试使用undetected-chromedriver这样的第三方库,它专门用于规避检测。

6.3 脚本运行一段时间后浏览器崩溃或无响应

  • 原因1:内存泄漏。Selenium和浏览器本身长时间运行可能积累内存。解决方案:定期重启浏览器。可以设计为每完成3-5门课程,就完全退出并重启一次浏览器实例。
  • 原因2:页面JavaScript内存泄漏或死循环。解决方案:脚本监控到页面长时间无响应(如通过检查视频时间是否在增长)时,主动刷新页面。
  • 原因3:网络不稳定。解决方案:在try...except中增加更广泛的异常捕获(如TimeoutException,WebDriverException),并在异常处理中尝试刷新或重启。

6.4 如何判断一门课程是否真的学完了?

单纯监控视频播放结束video.ended可能不够,因为有些平台在视频结束后需要手动点击“下一节”或“完成”按钮。

  • 解决方案:在监控循环中,除了检查视频状态,还要定期扫描页面是否出现了“下一节”、“本章测试”、“已完成”等标志性元素或文本。一旦发现,就触发相应的点击操作,并更新课程进度状态。

6.5 多课程、长时间运行的稳定性

如果需要挂很多门课,或者一次运行超过10小时:

  • 使用任务队列:将课程列表放入队列,即使中间某门课失败,也能记录日志并继续下一门。
  • 完善的日志系统:记录每个关键步骤的时间、状态和可能的错误信息。日志要包含足够上下文,方便离线分析。
  • 设计状态持久化:将当前学习进度(如学到第几门课、该课程的当前播放位置)定期保存到文件或数据库。这样即使脚本崩溃重启,也能从断点继续,而不是从头开始。
  • 外部监控与告警:脚本可以集成简单的邮件或即时通讯工具(如Server酱、钉钉机器人)的报警功能。当脚本连续失败、长时间无进度更新或最终完成时,发送通知。

6.6 我的实战心得

  1. 先手动,后自动:在写任何代码之前,手动在浏览器里完整走一遍流程。用开发者工具(F12)仔细观察每个步骤的页面变化、网络请求、元素属性。这是编写正确定位器和逻辑的基础。
  2. 循序渐进,分模块测试:不要试图一次性写完整个脚本。先写登录模块,测试通过;再写进入课程页模块,测试通过;最后写播放监控模块。每个模块都单独运行验证。
  3. 多用time.sleep调试,少用time.sleep上线:在调试阶段,可以用time.sleep(10)来暂停,方便你观察页面状态。但在最终脚本中,应尽可能用WebDriverWait替代固定的sleep,使脚本更高效、更健壮。
  4. 准备好应对变化:网站前端是经常变化的。你的脚本今天能用,下个月可能就失效了。因此,代码结构要清晰,将易变的元素定位器集中管理,便于维护。
  5. 伦理与风险意识:再次强调,请务必了解你所自动化平台的相关规定。技术本身是中立的,但应用场景有边界。将这个项目视为一次对Selenium、Web自动化和反检测技术的深度实践,其技术价值远大于“挂课”这个具体应用本身。

相关新闻

  • 如何快速掌握猫抓浏览器资源嗅探工具:新手完全指南
  • Windows Server 2022版本选择与部署全攻略
  • 拳皇15下载斗神再临-燃魂之战+全DLC

最新新闻

  • eBPF 运行时架构:Verifier、JIT、Map 与加载流程
  • CANN/asc-devkit DropOut API文档
  • 中国车牌生成器实战指南:高效解决车牌识别数据稀缺难题
  • 昇腾CANN Rint临时空间大小接口
  • CANN/asc-devkit Tanh接口
  • 从C++到Qt桌面开发:核心机制、实战避坑与项目构建全指南

日新闻

  • 佛山青少年训练营推荐:军博营地实力顶尖 - 秋山寄远
  • 如何快速上手PvZ2 Gardendless:免费Web版植物大战僵尸2完整指南
  • jiuwen-deepsearch核心功能详解:规划-检索-反思三合一智能工作流

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号