图形验证码识别全链路:选型、预处理与Web自动化框架集成

发布时间:2026/10/21 8:59:07
图形验证码识别全链路:选型、预处理与Web自动化框架集成 开头每次在 Web 自动化框架里跑到登录步骤就突然停住十有八九是撞上了图形验证码。这东西对真人来说有时都得眯着眼睛辨认对自动化脚本来说更是一道硬关卡。做测试的朋友应该都体会过运维环境功能可以关但预发布环境还关不掉验证码本身看着不难但脚本总是识别失败一失败就要等刷新、等下一次重试整个用例的执行时间直接翻倍。这篇文章我想把图形验证码处理这条链路完整拆开从验证码类型、方案选型、图像预处理、OCR 识别到和 Selenium、Playwright 这类 Web 自动化框架真正集成一次性讲透。适合正在维护自动化测试框架的测试开发、刚接触自动化的小白以及被验证码卡到头疼还找不到头绪的朋友。内容以实际项目为主所有步骤都能直接抄走用。1. 图形验证码为什么是自动化测试的拦路虎1.1 常见验证码类型与识别难度分级先给常见图形验证码做个分级我从实际项目里遇到的频率和识别难易程度出发列了一张表验证码类型典型样式识别难度自动化处理的常见问题纯数字 / 字母4位或6位字符较低字体扭曲、颜色干扰、字符粘连数字字母混合大小写随机组合中等容易把0认成O1认成l大小写敏感中文汉字2到4个词组较高字库覆盖不足生僻字识别率低数学运算83? 之类中等先识别再计算一步出错全错滑块验证拖动缺口到指定位置较高依赖轨迹模拟和缺口定位稳定性差点选文字 / 图像按顺序点击图中文字或物品很高需要目标检测模型辅助成本高极验 / 腾讯系行为验证混合图形行为轨迹很高需要逆向或专门的模拟策略维护成本高这里我重点展开纯图形验证码也就是“图片上画了几个字符让你输入”的这类。它是自动化测试中最常见、也是最容易通过技术手段解决的一类。滑块和点选类后续有机会单独写但它们背后的图像定位思路和图形验证码有互通之处。1.2 验证码在测试链路中的位置验证码几乎只出现在两类地方登录前和操作敏感动作前。登录前不用多说每次自动化用例要走完整登录流程就绕不开。敏感动作前的验证码更麻烦比如修改密码、绑定手机号、提交订单、领取优惠券触发时机不确定可能在用例中段突然弹出来。对自动化脚本来说验证码带来的影响不仅是“识别失败”而是整个用例的稳定性崩塌用例时间不可控。一次识别失败就要重新加载验证码、重新识别几轮下来用例超时。用例结果不可复现。同样的代码有时候识别成功有时候失败测试报告里飘红一片。大量用例被卡在登录层。尤其回归测试需要多账号登录每个账号跑一次登录就卡一次。所以验证码处理不是“锦上添花”的细节而是自动化框架能不能稳定跑下去的基础设施之一。1.3 为什么不能一刀切“绕过去”很多刚接触自动化的同学第一反应是能不能把验证码跳掉比如调用后门接口直接获取登录态。这在纯接口测试场景下完全可行但 Web 自动化测试的核心目标是验证前端流程、交互逻辑和联调结果如果你直接绕过登录页面跳转、Cookie 传递、权限控制这些环节就全部失去了验证意义。而且验证码出现的位置往往不只是登录还有下单确认、修改资料等业务环节。这些环节没法简单通过“跳过”处理必须让自动化具备“看到验证码并正确输入”的能力。这就是图形验证码识别处理存在的意义。2. 图形验证码处理方案选型与取舍2.1 四类主流方案对比我在不同项目里试过四类方案分别适用于不同阶段和不同环境这里先说结论再展开方案实现难度维护成本稳定性适用场景测试环境关闭验证码极低无100%开发测试环境、持续集成流水线万能验证码 / 固定验证码极低无100%所有非生产环境图像预处理 OCR中等中70%~95%图形验证码干扰不严重的场景第三方云端识别低高按量付费95%以上复杂验证码、生产环境联调先说前两个这两个方案往往是自动化的“保底手段”也是我接手任何一个新项目时最先确认的资源。2.2 测试环境关闭验证码与万能验证码关闭验证码的方式很多后台配置开关、通过接口开关、测试数据初始化时设置。最理想的是框架层面做一个基础抽象让代码自动判断当前环境如果是测试环境直接跳过验证码输入步骤否则才走 OCR 或标准识别流程。万能验证码也很常见。就是在验证码校验逻辑里预留一个超级账号或固定字符串测试时输入它无论后台生成什么验证码都能通过。这种方案的好处是代码根本不用改自动化脚本正常走输入流程区分度仅在于“输入的内容是万能值”。但要注意两点一是万能验证码千万不能上线到生产环境否则安全形同虚设二是如果测试环境偶尔因为数据初始化问题没有开启万能验证码脚本回像“谜语人”一样摸不着头脑得提前在配置中心里固定好。我不建议把这两类方案作为唯一方案。因为预发环境、灰度环境往往不会开放这类开关而那些环境恰恰是最需要跑完整回归的。所以一个好框架应当优先走“真实识别”并保留环境开关做兜底。2.3 图像预处理 OCR 的技术原理和应用边界OCR 识别图形验证码的原理并不神秘图像输入后先做预处理提升字符和背景的对比度再用 OCR 引擎把图像特征映射为文字最后配合后处理规则字符白名单、长度限制提升准确率。主流的 OCR 引擎是 Tesseract配合 Python 的 pytesseract 库适合中等干扰程度的验证码。判断适不适合的黄金准则验证码图片里有没有明显的干扰线、噪点或背景花纹。如果只是简单的扭曲字体比如深色字浅色底预处理之后识别率能到 90% 以上。如果是渐变背景加密集噪点识别率会掉到 50% 以下那就要考虑云端识别或另想办法。2.4 第三方云端识别如何选市面上现在有不少验证码识别服务它们通常提供 HTTP 接口把图片传上去返回文本结果。优点是识别率高、省掉模型训练成本缺点是按次计费、依赖外网内网隔离的项目没法用。实际项目中我通常这么衔接给 OCR 识别层做一个统一接口内部先跑 Tesseract如果结果的置信度不够或者连续重试仍然失败再调用云端接口。这样既控制了成本也保证了复杂场景下的成功率。2.5 底层框架与工具选型图形验证码识别的核心依赖无外乎三个截图工具、图像处理库、OCR 引擎。截图工具由自动化框架自带图像处理库我和大部分团队一样用 OpenCVOCR 引擎用 Tesseract这里先给出基础环境# 安装 Python 依赖 pip install opencv-python pytesseract requests # Ubuntu/Debian 安装 Tesseract 引擎并支持中文 apt-get install -y tesseract-ocr tesseract-ocr-chi-sim另外说一句如果你想识别效果再好一点可以下载训练好的专用数字验证码字库放到 Tesseract 的 tessdata 目录识别率和原版相比有质的提升。这个点我在后面的章节详细讲。3. 图形验证码识别核心链路从截屏到输出文本3.1 第一步拿到干净的验证码图片识别之前必须保证图片质量。很多自动化脚本识别率低不是算法不行而是截图环节就出了幺蛾子。我用 Selenium 和 Playwright 分别给出两个获取图片的方式。Selenium 获取验证码元素的 base64 截图import base64 from selenium.webdriver.common.by import By # 先确保页面结构加载完整 captcha_element driver.find_element(By.CSS_SELECTOR, img.captcha-img) # 方式一直接截图并保存为文件推荐 captcha_element.screenshot(captcha_raw.png) # 方式二截图后转成 base64 字符串方便直接扔给处理函数 screenshot_b64 captcha_element.screenshot_as_base64 raw_data base64.b64decode(screenshot_b64) with open(captcha_raw_base64.png, wb) as f: f.write(raw_data)Playwright 获取验证码元素截图# 使用 Playwright 的同步 API cap_locator page.locator(img#captcha-img) cap_locator.screenshot(pathcaptcha_raw_playwright.png) # 也可以直接截全页面然后裁剪但我更推荐直接对元素截图省掉坐标计算这里有几个注意事项是截图阶段很关键的等待验证码图片加载完成再截图。如果脚本点击“刷新验证码”后立刻截图很容易拍到旧图或半加载图识别出来的是上一个验证码后续输入必然失败。建议显式等待图片的 src 或 class 变化或者干脆固定等待 0.5~1 秒。用元素截图不要用全屏截图再裁剪。全屏截图依赖元素坐标如果页面有滚动或响应式布局变化坐标很容易偏移导致裁剪到旁边的广告位。图片可能带有 data URI 前缀。如果验证码图片直接是 base64 内嵌的src 以 data:image 开头那根本不需要浏览器截图直接把 base64 解码成文件即可速度和清晰度都有保障。3.2 第二步图像预处理这一步决定识别率上限拿到原始图像后不能直接扔给 OCR。原图往往有背景纹理、干扰线、字符颜色与背景接近等问题直接识别可能连 20% 都不到。我常用的预处理流程依次是灰度化、二值化、降噪、去边框或去干扰线。下面是一段我用 OpenCV 实现的预处理函数覆盖大部分图形验证码的清洗需求import cv2 import numpy as np def preprocess_captcha(image_path: str) - np.ndarray: 图形验证码预处理灰度 - 二值化 - 形态学降噪 # 1. 保持原始图像和通道信息 img cv2.imread(image_path) if img is None: raise ValueError(f无法读取图片: {image_path}) # 2. 灰度化去掉颜色保留亮度信息 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 3. 直方图均衡化增强字符与背景的对比度 gray cv2.equalizeHist(gray) # 4. 自适应二值化代替固定阈值适应不同亮度的验证码 binary cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, # 邻域大小可根据图片尺寸微调 15 # 常数 C越大越容易保留浅色字符 ) # 5. 形态学操作先腐蚀去掉细小的噪点再膨胀恢复字符粗细 kernel np.ones((3, 3), np.uint8) cleaned cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) cleaned cv2.medianBlur(cleaned, 3) return cleaned二值化是整条链路中最需要调参的一步。固定阈值 cv2.threshold 在统一背景下挺好用但验证码图片的背景色经常变化今天浅黄明天浅蓝固定阈值会导致字符被吞。自适应二值化通过局部邻域计算阈值对这种场景明显更稳。常见验证码适配的关键参数如下图像特点邻域大小blockSize常数 C推荐操作字符粗大、图片清晰1510直接自适应二值化即可背景干扰线密集3115先高斯模糊再二值化字符细长、容易断线1120二值化后额外做一次膨胀背景与字符颜色接近5110先做直方图均衡化如果你看到的验证码带明显的弧线干扰预处理阶段还可以加一步按连通域面积过滤只保留面积超过某个阈值的连通区域。干扰线通常是一条细长的连通域面积占比远小于字符区域过滤掉之后效果立竿见影。这个思路适合固定样式、干扰线位置相对稳定的验证码通用性稍差但对特定项目很有用。3.3 第三步用 Tesseract 做 OCR 识别预处理完的图片就可以喂给 Tesseract 了。这里说的“喂”不只是调一个函数关键是 Tesseract 的模式和参数设置。看一段代码import pytesseract from PIL import Image def recognize_captcha(processed_img: np.ndarray) - str: 将预处理后的图像识别为字符串 # OpenCV 的 BGR 数组先转成 PIL 的 RGB 格式 rgb_img cv2.cvtColor(processed_img, cv2.COLOR_BGR2RGB) pil_img Image.fromarray(rgb_img) # 给 Tesseract 一个字符白名单只允许大写字母和数字 config ( --psm 7 -c tessedit_char_whitelistABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz0123456789 ) text pytesseract.image_to_string(pil_img, configconfig) text text.strip().replace( , ).replace(\n, ) return text.upper()这里有一个核心参数 psmPage Segmentation Mode它告诉 Tesseract 图像应该按什么布局来切分。对图形验证码我强烈建议用--psm 7单行文本模式因为绝大多数验证码都是一行字符。如果同时出现多行词组的验证码可以用--psm 6。很多识别失败案例都是因为默认模式把验证码当成整页文档切分出来一堆乱七八糟的框。tessedit_char_whitelist的作用是告诉 Tesseract 只需要在这些字符里猜。如果明明是纯数字验证码你却允许字母参与猜测那么数字 8 被认成字母 B 的概率就会增高。所以白名单要精确纯数字验证码就只放0123456789。3.4 专用训练字库与二次校验对识别率迟迟上不去的场景可以自己训练 Tesseract 专用字库。这一步在小范围固定字体的验证码上非常有效能把识别率从 70% 拉到 95% 以上。训练流程大致是这样的收集 100~200 张同一款式的验证码图片并记录每张图片对应的真实文本就是每条验证码应该是什么。用收集的数据生成 Tesseract 的训练文件对每张图片做 box 标注可以用 JTessBoxEditor 工具可视化标框。执行tesseract训练命令生成 tr 文件、字体特征文件和最终 traineddata 文件。把训练好的 traineddata 放到 tessdata 目录并在调用时通过--traineddata指定。这个过程需要花一些时间但对固定业务系统来说性价比极高。我的建议是先判断验证码是不是内网业务系统里固定样式、长期不换的。如果是优先考虑训练专用字库而不是反复堆预处理参数。如果验证码样式经常换训练字库容易白费。另外OCR 识别出的结果不要直接拿去用加一层校验逻辑会更稳妥def validate_and_normalize(text: str, expected_length: int 4) - str: 校验识别结果如长度不对则返回空字符串让外层走重试 if len(text) ! expected_length: return # 常见误识别纠正数字 0 和字母 O、字母 I 和数字 1 等 # 如果业务是纯数字这里可以统一替换 text text.replace(O, 0).replace(I, 1).replace(l, 1) return text这一步属于经验积累不同项目的识别混淆点不一样。比如电商系统的纯数字验证码把 OCR 输出的全部非数字字符替换成数字是很常见的操作。如果业务允许大小写不敏感全部转大写也能救回一部分混淆结果。4. 在 Web 自动化框架中落地验证码处理4.1 统一封装一个验证码处理模块框架层落地时最忌讳把识别逻辑散落在各个用例里。我在项目中习惯把验证码处理抽象成一个独立模块统一暴露给自动化脚本调用。模块内部划分三层图片获取层负责从页面元素或接口响应中获取验证码图片识别层负责预处理 OCR 云端识别返回识别文本执行层负责输入验证码、点击提交、判断是否成功、失败重试。这样做的价值在于底层怎么识别对上层透明。今天用 Tesseract明天换成识别服务用例代码一行都不用改。4.2 在 Selenium 中实现完整登录流程下面给出一个在 Selenium 中完整处理图形验证码登录的例子from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time def solve_captcha_and_login(driver, username, password, is_test_envFalse): # 输入用户名和密码 driver.find_element(By.ID, username).send_keys(username) driver.find_element(By.ID, password).send_keys(password) # 定位验证码图片 captcha_img WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CSS_SELECTOR, img.captcha-img)) ) captcha_img.screenshot(captcha_cur.png) # 识别验证码文字 if is_test_env: captcha_code 1234 # 测试环境的万能验证码 else: processed preprocess_captcha(captcha_cur.png) captcha_code recognize_captcha(processed) # 校验长度如果异常则点击刷新并重新获取一次 if captcha_code is None or len(captcha_code) 4: driver.find_element(By.CSS_SELECTOR, a.refresh-captcha).click() time.sleep(0.5) driver.find_element(By.CSS_SELECTOR, img.captcha-img).screenshot(captcha_cur.png) processed preprocess_captcha(captcha_cur.png) captcha_code recognize_captcha(processed) # 输入验证码并登录 driver.find_element(By.ID, captcha).send_keys(captcha_code) driver.find_element(By.ID, loginBtn).click() # 真正的核心判断是否登录成功而不是猜时间 try: WebDriverWait(driver, 8).until( EC.visibility_of_element_located((By.CSS_SELECTOR, div.user-panel)) ) print(登录成功) return True except Exception: error driver.find_element(By.CSS_SELECTOR, span.login-error) print(f登录失败原因{error.text}) return False这段代码里有几个容易被忽略的细节值得单独拿出来讲获取验证码元素前要等待可见不要刚开始抢。如果页面有异步接口在生成验证码立刻截图会拍到旧图或者空白图这是 Selenium 新手最容易踩的坑。识别失败不是直接抛异常而是先刷新验证码再识别一次。很多验证码点击刷新后会生成新图再试一次往往就成功了。登录后的判断必须用显式等待。不能用time.sleep(5)然后看一眼页面就完事。页面加载快慢受网络影响sleep 长了浪费时间短了误报失败。用 WebDriverWait 等待登录成功后的标志元素才是靠谱的方式。4.3 在 Playwright 中实现自动识别Playwright 的 API 相比 Selenium 更简洁一些并且自动处理了等待逻辑示例代码可以更干净from playwright.sync_api import sync_playwright import time def playwright_login(): with sync_playwright() as p: browser p.chromium.launch(headlessFalse) page browser.new_page() page.goto(https://example.com/login) page.fill(#username, test_user) page.fill(#password, test_password) # 等待验证码图片稳定可见 captcha_locator page.locator(img.captcha-img) captcha_locator.wait_for(statevisible) captcha_locator.screenshot(pathcaptcha_pw.png) processed preprocess_captcha(captcha_pw.png) captcha_code recognize_captcha(processed) page.fill(#captcha, captcha_code) page.click(button:has-text(登录)) # 等待登录成功的标志元素出现超时会自动抛出异常 page.wait_for_selector(div.user-panel, timeout8000) print(登录成功) browser.close()Playwright 自带的wait_for_selector实际上兼了 Selenium 里 WebDriverWait 的作用代码少了一截。如果你负责的项目已经切到 Playwright建议优先用它的自动等待能力不要再手写 sleep这会让用例稳定很多。4.4 重试策略与用例级自愈不管识别算法调得多好验证码识别都不可能做到 100%。所以自动化框架在处理验证码时必须内建重试机制。我的经验是做成三层重试识别前重试预处理结果如果明显异常比如 OCR 返回空、返回长度不等于验证码位数直接刷新验证码重来不进入填写流程。登录后重试填写验证码后点击登录如果页面提示“验证码错误”自动刷新验证码并重新执行一次填充。注意此时账号密码可以不用重新输入但有些系统会在登录提交失败后清空密码框所以重试流程里要考虑重新填一遍。用例级重试整个登录步骤连续失败超过 3 次后终止用例并标记失败同时截图存档。不要无限制重试下去否则一个故障用例会白白消耗十几分钟。我给团队常用的次数阈值是单次验证码识别重试最多 3 次超过即走用例级自愈或失败。这个阈值既给了验证码算法自我纠正的空间也保证了整体用例的执行时间不会因为服务偶发抖动而失控。4.5 多账号与并行执行时的特别注意事项回归测试经常要跑几十个账号并行登录验证码模块在并发行下会遇到两个额外问题。第一个是浏览器上下文隔离。Selenium Grid 下每个节点是独立浏览器进程验证码截图和登录态不会互相污染这还好。但如果你在同一个浏览器进程里用多标签页并行登录验证码的 Cookie 和页面状态可能串台强烈建议每个并行任务使用独立浏览器上下文。Playwright 的browser.new_context()天然支持这个隔离性极佳。第二个是验证码刷新时机。并行跑同一个系统的用例时如果多台机器同时刷新验证码后端接口可能会有频率限制导致一部分刷新请求失败返回旧图。这个问题的表象是识别结果总是对不上。排查思路是看后端验证码刷新接口的日限量告警或者在框架里给验证码刷新动作加一个全局互斥锁 / 小延时。个人经验是小规模并行加 200~500 毫秒的随机延时就能缓解真正的大并发还得从后端接口限流入手。5. 常见问题排查与实战避坑5.1 识别率低问题到底出在哪一环碰到“验证码识别率老上不去”的情况我整理了问题定位速查表现象可能原因排查方向OCR 总是输出空字符串预处理过度字符被吞掉二值化阈值过大减少常数 C检查形态学操作是否腐蚀过度OCR 输出乱码干扰线太多增加降噪步骤先高斯模糊再接二值化使用连通域过滤长度对字符错一半字体不在 Tesseract 训练范围训练专用字库缩小白名单范围识别正确却登录失败验证码时效太短或请求带着旧 Cookie缩短截图到输入的间隔登录前刷新 Cookie偶发失败重试即成功网络延迟导致图片半加载在截图前等待图片加载完成的信号别用固定 sleep验证码刷新后永远失败后端缓存旧图查看接口是否设置了 CDN 缓存头测试环境可请求禁用如果用这个表逐项排查大部分识别率问题都能找到答案。这里顺便说一句遇到问题时先记录验证码图片和识别结果对比着看比凭空想象高效得多。我习惯在处理函数里默认保存最近 50 张验证码原图和预处理结果图排查问题时有据可查这个习惯帮过大忙。5.2 识别正确但登录总失败的细节坑这是最让人抓狂的情况OCR 输出的文本肉眼看着完全正确但系统就是提示验证码错误。我遇到过一种典型的“隐性时效”场景。页面刚打开时加载了一个验证码脚本把页面晾了很久才开始操作等填完账号密码验证码早已过期。表面上你看不到任何提示但提交时后端发现验证码过期就返回错误。解决办法是在登录流程中先填账号密码再截图验证码截完图立刻填中间不要夹带其它耗时操作。还有一种是验证码校验绑定的是登录请求的 Session Cookie。如果自动化脚本在“获取验证码”和“提交验证码”之间不小心发起了一个会刷新 Session 的请求比如点了一下页面其他区域触发了异步刷新后端认为会话变了旧验证码就失效了。排查方式是在提交时对比验证码刷新前后请求的 Cookie 是否有变化如果有就该在代码里避免这类额外请求。5.3 固定 sleep 的滥用怎么破代码里写time.sleep(2)等待验证码加载是所有自动化工程师都干过的事。sleep 确实是调试阶段最简单的办法但它有两个先天缺陷无谓等待和误判成功。网络好的时候 2 秒是多余的网络差的时候 2 秒又不够。而且 sleep 不校验结果只要过了时间就继续往下走哪怕图片还是空白。我更推荐的做法是围绕验证码自身的特点做轮询式等待。比如验证码图片的 src 里通常带时间戳或随机参数可以用 Playwright 或 Selenium 的条件等待轮询判断这个 src 是否从“旧值”变成了“新值”。如果验证码图片接口的响应包含Set-Cookie还可以在代码层面显式等待验证码接口的响应完成然后再截图。这样既快又稳。5.4 并行跑用例时的验证码冲突这里再补充一个实战场景。某次大规模回归框架并行跑 20 个账号结果有一小部分用例登录后进入了别人的会话排查到最后发现是登录用例里用了共享的一个静态变量在保存验证码 Cookie并行执行时变量被覆盖了。这种低级错误在并发场景下特别容易暴露。解决办法是验证码相关的 Cookie、验证码文本、处理进度等状态一律保存在“当前任务上下文”对象里不要放模块级全局变量。框架如果用线程池跑用例务必要让每个线程有独立的上下文实例。不要问我为什么强调这点团队里已经不止一次在这上面栽跟头了。5.5 识别服务不可用时的降级策略如果你的框架接入了云端识别服务还会遇到外网 API 超时、限流或故障的情况。测试总不能因为一个外部服务挂了就全线红。我给框架设计的降级顺序是本地 Tesseract 优先识别失败才请求云端云端超时或返回异常自动切换回本地 OCR 结果本地和云端都不理想走万能验证码仅限非生产环境所有手段都用完仍失败标记为“可重试失败”由用例级 Runner 整体重跑该用例。这套降级策略我要求所有接入验证码模块的团队都落地。它的好处是把外部依赖的影响控制在最小范围测试平台不会因为验证码识别服务间歇性故障而大面积报红。写在最后图形验证码识别这件事说到底没有银弹。不同项目用的验证码风格千差万别今天解决了的方案明天系统升级验证码加了两条干扰线识别率可能又掉一半。我个人的体会是处理这类问题要抓住关键环节先把图片拿干净再把预处理参数调准最后用重试和降级把成功率兜起来。这三点做好大部分图形验证码场景都能稳定跑起来。如果验证码升级到滑块验证、点选验证这类更复杂的形式很多团队选择在测试环境关掉验证码或者在框架里引入专门的验证码识别服务来应对这些方案我在文中的选型部分都有提到。对大多数做 Web 自动化的人来说先把手头图形验证码的处理链路打通已经能解决绝大多数登录难、被卡住的问题了。希望这篇攻略能让你少走几步弯路。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询