news 2026/10/26 13:56:05

jsoup分页爬取实战:绕过反爬、会话管理与断点续爬

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
jsoup分页爬取实战:绕过反爬、会话管理与断点续爬

简介:本资源是一份基于Java的jsoup分页爬虫实战项目,面向Java初学者及网页数据采集入门开发者,解决结构化HTML页面多页批量抓取与解析的核心问题。项目完整封装了URL参数构造、CSS选择器精准提取、分页循环控制、异常重试机制及基础数据清洗逻辑,覆盖从单页解析到全站分页遍历的典型开发流程。压缩包共16个文件,含7个核心jar包(如jsoup-1.9.2.jar、WebCollector-2.52.jar等)、1个主程序Java源码、1个编译后class文件、2个Eclipse工程配置文件(.classpath、.project)及日志与偏好设置相关文件,整体3.08MB,结构清晰,开箱即用。目前已有1082人学习下载,读者可直接运行调试、理解分页请求调度原理、掌握jsoup与常见工具库的协同用法,并借鉴其工程组织方式与错误处理设计思路。

1. jsoup分页爬取网页:不是写个for循环就完事,而是要稳住连接、绕过反爬、对齐页码逻辑

你是不是也试过用 jsoup 写了个for (int i = 1; i <= 100; i++) { Document doc = Jsoup.connect("https://xxx/list?page=" + i).get(); },跑着跑着第17页就卡死、第42页返回空列表、第68页突然跳转到登录页?这不是代码写错了,是没把「分页爬取」当成一个状态可控的会话过程来设计。jsoup 本身不带分页管理能力,它只是个 HTML 解析器;真正决定能不能稳定拿到100页数据的,是你怎么构造请求头、怎么识别真实页码跳转逻辑、怎么处理服务器返回的“假分页”(比如页码参数无效但URL变了)、以及如何在连接中断后精准续爬。这份实战笔记拆解的是某高校课程设计中真实落地的 jsoup 分页爬取方案——它跑通了含动态页码校验、Referer 防盗链、Cookie 会话维持、响应体空值熔断的完整链路。适合正在做课程作业、毕设数据采集或轻量级竞品监控的开发者,尤其当你发现目标网站没有 API、又不想上 Selenium 这种重型方案时,这套纯 jsoup 的轻量级分页架构,就是你该抄的第一份作业。


2. 分页爬取的本质:不是遍历页码,而是模拟人眼+人手的翻页行为

2.1 为什么不能直接拼接 page 参数?——三类典型分页机制拆解

很多新手以为分页就是 URL 里有个?page=1,改成?page=2就能翻页。实际线上网站至少存在三类分页逻辑,直接硬改参数大概率失败:

  • 服务端静态分页:URL 参数真实生效,如/list?page=5&size=20,后台 SQL 直接LIMIT 80,20。这是最理想情况,但占比不足30%;
  • 前端 JavaScript 渲染分页:页面初始只加载第1页,点击“下一页”时通过 AJAX 请求/api/items?page=2,返回 JSON 数据再渲染 DOM。此时用 jsoup 直接 GET 原 URL 永远只能拿到第1页;
  • 服务端动态页码校验:URL 看似支持page=100,但服务端会校验当前用户权限、访问频次、Referer 头、甚至 Cookie 中的 session token。传入非法页码可能返回 302 跳转、403 拒绝或静默返回第1页内容。

提示:判断分页类型最简单的方法是——打开浏览器开发者工具(F12),切到 Network 标签页,手动点几次“下一页”,观察触发的是 HTML 页面跳转(Document 类型),还是 XHR/Fetch 请求(XHR 类型)。前者可用 jsoup,后者需提取接口并模拟请求。

2.2 jsoup 分页爬取的最小可行架构:四层责任分离

我们不写“万能爬虫”,而是构建一个职责清晰、可调试、可续爬的分页流程。核心是四层抽象:

层级职责关键实现要点
页码生成器(PageGenerator)输出合法页码序列,支持跳过、断点续爬、页码去重不依赖 URL 拼接,而是从上一页 HTML 中解析<a href="/list?page=2">下一页</a>或 JSON 接口中的"next_page": 2
请求装配器(RequestBuilder)封装 User-Agent、Referer、Cookie、超时、重试策略必须复用 Connection 对象,避免每次 new Jsoup.connect() 丢失会话上下文
响应处理器(ResponseHandler)判定响应有效性:HTTP 状态码、HTML 结构完整性、业务字段存在性例如检查doc.select("div.item").size() == 0即视为本页无数据,应终止而非继续
结果收集器(ResultCollector)统一结构化存储,支持内存缓存 + 文件落盘 + 断点快照每爬完一页立即写入临时文件,记录当前页码和时间戳,防止中断丢进度

这个架构不是炫技,而是为后续排查留出明确切口:如果爬到第53页失败,你能快速定位是页码生成错了(查 PageGenerator 日志)、请求被拦了(看 RequestBuilder 发出的 Header)、还是页面结构突变(用 ResponseHandler 的 debug 模式打印原始 HTML)。

2.3 实战:从首页提取真实下一页链接(非 URL 拼接)

很多网站的“下一页”按钮 href 是相对路径或 JS 跳转,直接拼page=2会 404。正确做法是从 HTML 中解析真实跳转地址,并用 jsoup 的abs:语法转为绝对 URL:

// 假设已获取首页 Document 对象 Document firstPage = Jsoup.connect("https://example.com/list") .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") .timeout(10000) .get(); // 解析“下一页”链接:兼容多种写法 Elements nextLinks = firstPage.select("a:contains(下一页), a:contains(Next), link[rel=next]"); String nextPageUrl = null; for (Element link : nextLinks) { String href = link.attr("href"); if (!href.isEmpty() && !href.startsWith("javascript:")) { nextPageUrl = link.absUrl("href"); // 自动补全为绝对 URL break; } } if (nextPageUrl != null) { System.out.println("真实下一页地址:" + nextPageUrl); // https://example.com/list?page=2 } else { System.out.println("未找到下一页链接,尝试 fallback 逻辑..."); }

这段代码的关键在于link.absUrl("href")—— 它会自动将href="/list?page=2"补全为https://example.com/list?page=2,无需手动拼域名。而:contains()选择器能同时匹配中文“下一页”和英文“Next”,比硬编码select("a.page-next")更鲁棒。如果你的目标网站用<button onclick="goPage(2)">,那就得换策略:用正则从onclick属性里提取数字,或直接分析其 JS 逻辑(这时建议退一步,用浏览器自动化工具)。


3. 请求头与会话管理:让 jsoup 像真实浏览器一样“记住自己”

3.1 必须携带的三大请求头及其业务意义

jsoup 默认请求头极简(只有User-Agent: Java/1.8.0_XXX),而现代网站普遍校验以下三项:

  • User-Agent:声明客户端身份。若缺失或过于简单(如Java),部分网站直接返回 403;
  • Referer:标识来源页面。例如从/list点击进入/detail/123,服务端会校验 Referer 是否为/list,否则拒绝访问;
  • Cookie:维持登录态或防刷 Token。即使未登录,某些网站也会下发sessionid或cf_clearance(Cloudflare 验证)。

下面是一段生产环境验证过的请求头装配模板:

Connection connection = Jsoup.connect(url) .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8") .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8") .header("Accept-Encoding", "gzip, deflate") .header("Connection", "keep-alive") .header("Upgrade-Insecure-Requests", "1") .header("Sec-Fetch-Dest", "document") .header("Sec-Fetch-Mode", "navigate") .header("Sec-Fetch-Site", "same-origin") .timeout(15000); // 关键:复用同一 Connection 实例的 cookieStore if (cookieStore != null) { connection.cookies(cookieStore); }

注意两点:
①header("Sec-Fetch-*")系列是 Chromium 新增的安全头,部分网站(尤其是用了 Cloudflare 的)会校验它,缺失可能导致 403;
②.cookies(cookieStore)是复用 Cookie 的核心——cookieStore是一个Map<String, String>,你在登录页或首页成功请求后,用connection.response().cookies()提取并保存它,后续所有请求都带上,才能维持会话。

3.2 如何安全地维持登录态?——从登录页提取隐藏字段 + 模拟表单提交

假设目标网站需要登录才能查看分页列表。别用“账号密码硬编码”,而是走标准表单提交流程:

// 1. 先 GET 登录页,提取隐藏字段(如 csrf_token) Connection loginPageConn = Jsoup.connect("https://example.com/login") .userAgent(USER_AGENT) .timeout(10000) .method(Connection.Method.GET); Document loginPage = loginPageConn.get(); Map<String, String> cookies = loginPageConn.response().cookies(); // 提取隐藏字段 String csrfToken = loginPage.select("input[name=csrf_token]").attr("value"); String returnUrl = loginPage.select("input[name=return_url]").attr("value"); // 2. POST 登录表单 Connection loginPostConn = Jsoup.connect("https://example.com/login") .userAgent(USER_AGENT) .cookies(cookies) // 携带上一步的 cookies .data("username", "your_user") .data("password", "your_pass") .data("csrf_token", csrfToken) .data("return_url", returnUrl) .timeout(15000) .method(Connection.Method.POST); Response loginResponse = loginPostConn.execute(); Map<String, String> newCookies = loginResponse.cookies(); // 3. 验证登录是否成功:检查重定向目标或页面标题 if (loginResponse.statusCode() == 200) { Document postLoginDoc = loginResponse.parse(); if (postLoginDoc.title().contains("欢迎回来")) { System.out.println("登录成功,新 Cookies 已更新"); cookieStore = newCookies; // 更新全局 cookieStore } }

这段代码的价值在于:它不依赖任何外部库,纯 jsoup 实现登录态接管。关键点是两次请求间cookies的传递,以及对csrf_token这类防重放字段的动态提取——这比写死 Cookie 字符串可靠十倍。

3.3 超时与重试策略:别让单页失败拖垮整个流程

网络抖动、服务端限流很常见。jsoup 默认无重试,需手动封装:

public Document fetchWithRetry(String url, Map<String, String> cookies, int maxRetries) { for (int i = 0; i <= maxRetries; i++) { try { Connection conn = Jsoup.connect(url) .userAgent(USER_AGENT) .cookies(cookies) .timeout(12000) .followRedirects(true); Response response = conn.execute(); if (response.statusCode() == 200) { return response.parse(); } else if (response.statusCode() == 429 || response.statusCode() == 403) { // 遇到限流,指数退避 Thread.sleep((long) Math.pow(2, i) * 1000); continue; } else { throw new IOException("HTTP " + response.statusCode()); } } catch (Exception e) { if (i == maxRetries) throw e; Thread.sleep(2000); } } return null; }

这里用了指数退避(Exponential Backoff):第一次失败等2秒,第二次等4秒,第三次等8秒……避免集中重试触发更严限流。同时捕获429 Too Many Requests和403 Forbidden,这两者往往是反爬信号,比单纯超时更值得警惕。


4. 避坑:分页爬取中五个血泪经验总结

4.1 现象:爬到第N页后,所有后续页都返回第1页内容

原因:服务端做了页码有效性校验,当传入page=100但实际总页数只有50时,它不报错,而是静默重定向回第1页(302),而 jsoup 默认followRedirects(true)会自动跳转,导致你以为爬到了第100页,实际内容全是第1页的。
解决:关闭自动跳转,手动检查响应头:

Response response = conn.execute(); if (response.statusCode() == 302) { String location = response.header("Location"); if (location.contains("page=1")) { System.out.println("检测到页码越界,终止分页"); break; // 退出循环 } }

4.2 现象:本地测试正常,部署到服务器后大量 403

原因:服务器出口 IP 被目标网站拉黑,或服务器系统时间与 NTP 不同步,导致 Cookie 中的expires时间校验失败。
解决:

  • 在服务器执行ntpdate -u ntp.aliyun.com同步时间;
  • 为 jsoup 请求显式设置Date头(虽非常规,但部分网站校验):
    .header("Date", new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'").format(new Date()))

4.3 现象:doc.select("div.item")返回空集合,但浏览器能看到数据

原因:数据由 JavaScript 动态注入,jsoup 获取的是初始 HTML,不含 JS 渲染后的内容。
解决:先确认是否真为 JS 渲染(见 2.1 节 Network 分析)。若是,放弃 jsoup,改用 Puppeteer 或 Playwright;若只是懒加载(如滚动触发动态请求),可尝试在 URL 后加?__a=1或?raw=1参数获取原始 JSON 接口。

4.4 现象:爬取速度越来越慢,最后卡死

原因:jsoup 默认使用java.net.HttpURLConnection,其连接池未配置,每次请求新建 TCP 连接,且未复用 Keep-Alive。
解决:强制启用连接复用,并设置最大连接数:

System.setProperty("http.maxConnections", "20"); // 并在每个 Connection 中显式设置: .connTimeout(10000) .maxBodySize(0) // 取消响应体大小限制

4.5 现象:Cookie 有时失效,登录态突然丢失

原因:Cookie 中的Expires或Max-Age过期,或服务端下发了Set-Cookie: sessionid=xxx; Path=/; HttpOnly; Secure,而你的请求未走 HTTPS(Secure 属性要求),导致浏览器/Jsoup 不发送该 Cookie。
解决:

  • 所有请求必须用https://开头;
  • 每次请求后,用response.cookies()覆盖旧 Cookie 存储,确保始终用最新有效期的 Cookie;
  • 对关键 Cookie(如sessionid)做存在性校验:
    if (!newCookies.containsKey("sessionid")) { throw new RuntimeException("Session lost! Re-login required."); }

5. 断点续爬与增量采集:让爬虫具备“重启不丢进度”的工业级健壮性

5.1 设计可序列化的进度快照:不只是记页码

“断点续爬”常被简化为“记下当前页码”,但真实场景中,页码只是冰山一角。一次完整的分页任务需持久化至少五项状态:

字段类型说明示例
current_pageint当前待爬页码(下次启动从此开始)57
last_success_timelong上次成功爬取的时间戳(毫秒)1715234567890
cookiesMap<String,String>当前有效 Cookie(Base64 编码存储){"sessionid":"abc123","csrftoken":"xyz789"}
user_agentString当前使用的 UA(应对 UA 轮换策略)"Mozilla/5.0 (Mac)...Chrome/120"
crawl_statsMap<String,Object>统计信息:成功页数、失败页数、总耗时{"success":56,"fail":1,"total_ms":245678}

我们用 JSON 文件存储这些状态,文件名固定为crawl_progress.json,每次爬完一页就原子写入:

public void saveProgress(int currentPage, Map<String, String> cookies, String userAgent, Map<String, Object> stats) { Map<String, Object> progress = new HashMap<>(); progress.put("current_page", currentPage); progress.put("last_success_time", System.currentTimeMillis()); progress.put("cookies", cookies); progress.put("user_agent", userAgent); progress.put("crawl_stats", stats); try (FileWriter writer = new FileWriter("crawl_progress.json")) { writer.write(new ObjectMapper().writeValueAsString(progress)); writer.flush(); } catch (IOException e) { System.err.println("保存进度失败:" + e.getMessage()); } }

注意:ObjectMapper来自 Jackson 库,需添加依赖com.fasterxml.jackson.core:jackson-databind。不要用Properties或纯文本,JSON 支持嵌套结构,未来扩展字段零成本。

5.2 启动时自动恢复:三步校验法确保状态可信

不是所有crawl_progress.json都能直接信任。我们实施三步校验:

  1. 文件存在且可读:基础 IO 检查;
  2. JSON 结构完整:必须包含current_page和cookies字段;
  3. Cookie 有效性验证:用当前 Cookie 访问一个轻量接口(如/api/ping或首页),检查是否返回 200 且含预期内容。
public Progress loadProgress() { File progressFile = new File("crawl_progress.json"); if (!progressFile.exists()) return new Progress(1, new HashMap<>(), USER_AGENT); try { String json = Files.readString(progressFile.toPath()); JsonNode node = new ObjectMapper().readTree(json); // 步骤2:字段校验 if (!node.has("current_page") || !node.has("cookies")) { System.out.println("进度文件字段缺失,重置为第1页"); return new Progress(1, new HashMap<>(), USER_AGENT); } int page = node.get("current_page").asInt(); Map<String, String> cookies = new ObjectMapper() .convertValue(node.get("cookies"), new TypeReference<Map<String, String>>() {}); String ua = node.has("user_agent") ? node.get("user_agent").asText() : USER_AGENT; // 步骤3:Cookie 有效性验证(GET 首页) Document testDoc = Jsoup.connect("https://example.com/list") .userAgent(ua) .cookies(cookies) .timeout(8000) .get(); if (testDoc.select("title").text().contains("登录")) { System.out.println("Cookie 已失效,清空并重登"); return new Progress(1, new HashMap<>(), ua); } System.out.println("进度恢复成功:从第" + page + "页继续"); return new Progress(page, cookies, ua); } catch (Exception e) { System.err.println("加载进度失败,重置:" + e.getMessage()); return new Progress(1, new HashMap<>(), USER_AGENT); } }

这个设计让爬虫具备“自我康复”能力:即使进程被 kill、服务器宕机、Cookie 过期,重启后都能自动识别异常并安全降级,而不是带着失效凭证一路狂奔到 403。

5.3 增量采集:只爬新数据,避免重复入库

分页爬取常用于监控类场景(如商品价格、新闻标题),需识别“哪些是新增条目”。通用做法是为每条数据生成唯一指纹(fingerprint),基于内容哈希:

public String generateFingerprint(Element item) { // 提取关键字段:标题、发布时间、摘要前100字 String title = item.select("h2.title").text().trim(); String pubTime = item.select("span.time").text().trim(); String summary = item.select("p.desc").text().substring(0, Math.min(100, item.select("p.desc").text().length())).trim(); // 拼接后 SHA-256 String raw = title + "|" + pubTime + "|" + summary; try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(raw.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(hash); } catch (Exception e) { return UUID.randomUUID().toString(); // 降级 } }

然后维护一个本地HashSet<String>存储已爬指纹,或写入 SQLite 表fingerprint_history (fp TEXT PRIMARY KEY, crawled_at TIMESTAMP)。每次解析出新条目,先查指纹是否存在,不存在才入库并记录:

String fp = generateFingerprint(item); if (!seenFingerprints.contains(fp)) { seenFingerprints.add(fp); saveToDatabase(item); // 保存业务数据 saveFingerprint(fp); // 保存指纹快照 }

这样,哪怕你每天运行一次全量分页爬取,也只会入库当天新增的条目,彻底告别“重复插入”和“去重清洗”的脏活。


6. 验证爬取质量:用三类黄金指标守住数据底线

6.1 构建可执行的爬取质量校验清单

写完爬虫不等于结束,上线前必须跑通一套验证流程。我给自己定的铁律是:不通过这三项校验,绝不接入下游业务。

校验项方法合格标准不合格后果
结构稳定性校验对连续5页的 HTML,统计doc.select("div.item").size()的方差方差 < 2(即每页条目数波动 ≤1)页面结构突变,XPath/JQuery 选择器需重构
内容完整性校验抽样检查每页前3条数据的title、url、pub_time字段是否非空100% 非空率字段提取逻辑有缺陷,需加!text().isEmpty()判空
分页连贯性校验解析每页的“下一页”链接,检查其page参数是否严格递增page=1 → page=2 → page=3...无跳跃、无重复页码生成器逻辑错误,可能漏页

下面是一个可直接运行的校验脚本框架:

public void runQualityCheck() { List<Integer> itemCounts = new ArrayList<>(); List<Integer> pageNumbers = new ArrayList<>(); Set<String> allUrls = new HashSet<>(); // 抽样爬取前5页 for (int page = 1; page <= 5; page++) { try { Document doc = fetchPage("https://example.com/list?page=" + page); // 1. 统计条目数 int count = doc.select("div.item").size(); itemCounts.add(count); // 2. 解析页码(从URL或DOM中) int parsedPage = extractPageNumber(doc); pageNumbers.add(parsedPage); // 3. 收集URL去重 doc.select("div.item a").forEach(a -> allUrls.add(a.absUrl("href"))); } catch (Exception e) { System.err.println("第" + page + "页校验失败:" + e.getMessage()); } } // 计算方差 double mean = itemCounts.stream().mapToInt(Integer::intValue).average().orElse(0); double variance = itemCounts.stream() .mapToDouble(x -> Math.pow(x - mean, 2)) .average().orElse(0); System.out.println("条目数方差:" + variance); System.out.println("页码序列:" + pageNumbers); System.out.println("去重URL数:" + allUrls.size()); if (variance > 2) { throw new RuntimeException("结构不稳定:条目数波动过大"); } if (!isStrictlyIncreasing(pageNumbers)) { throw new RuntimeException("页码不连贯:存在跳跃或重复"); } }

这段代码不是摆设,而是你交付给导师或上线前的“质量签证”。它把模糊的“感觉差不多”变成可量化的数字结论。

6.2 生产环境必加的日志埋点:让每一次失败都可追溯

日志不是写给机器看的,是写给你自己(或接锅同事)看的。我在每个关键节点都加了结构化日志:

// 爬取前 log.info("START_PAGE", "page", currentPage, "url", currentPageUrl, "cookies_size", cookies.size(), "user_agent_snippet", userAgent.substring(0, Math.min(20, userAgent.length()))); // 解析后 int itemCount = doc.select("div.item").size(); log.info("PARSE_RESULT", "page", currentPage, "item_count", itemCount, "title_sample", doc.select("div.item h2").first() != null ? doc.select("div.item h2").first().text() : "N/A"); // 失败时 log.error("FETCH_FAILED", "page", currentPage, "url", currentPageUrl, "status_code", response.statusCode(), "error_msg", e.getMessage(), "response_body_length", response.body().length());

用log.info("EVENT_NAME", key1, value1, key2, value2)这种结构,方便后续用 ELK 或 grep 提取特定事件。比如查所有失败页:grep "FETCH_FAILED" app.log | awk '{print $5}';查某页详情:grep "page=42" app.log。没有这种日志,排查问题就是大海捞针。

6.3 从那以后我每次写分页爬虫,都强制走一遍“三分钟验证流程”

现在我的标准动作是:写完核心逻辑后,不急着跑全量,而是打开终端,三分钟内完成这三件事:

  1. 跑通单页:java Crawler --page 1,确认能取到 HTML、解析出数据、打印日志;
  2. 跑通两页跳转:java Crawler --from 1 --to 2,验证page=1的“下一页”链接是否正确指向page=2,且page=2能正常加载;
  3. 跑通断点续爬:手动删掉crawl_progress.json,跑一次--from 1 --to 3,再杀进程,重启后检查是否从page=4开始。

这三步花不了三分钟,但它能提前暴露 90% 的低级错误:URL 拼错、选择器写反、Cookie 没传递、页码解析逻辑崩坏……曾经有个项目,我跳过这步直接跑100页,结果爬了8小时发现第1页和第100页数据一模一样——因为服务端把page=100当成非法参数,全部重定向回第1页,而我没关followRedirects。从那以后我每次写分页爬虫,都强制走一遍这个三分钟验证流程,就像飞行员起飞前的 checklist。

希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 13:55:56

PyTorch深度学习实战:环境配置与LSTM模型优化

1. PyTorch深度学习实战笔记&#xff1a;从环境搭建到LSTM模型实现 在深度学习领域&#xff0c;PyTorch因其动态计算图和直观的API设计&#xff0c;已经成为学术界和工业界最受欢迎的框架之一。作为一名长期使用PyTorch的研究者&#xff0c;我记录下这套实战笔记&#xff0c;重…

作者头像 李华
网站建设 2026/10/26 13:55:55

Stable Diffusion四大核心模块原理与调试实战

1. 这不是“魔法”&#xff0c;是可拆解、可复现、可调试的工程系统Stable Diffusion 不是黑箱&#xff0c;更不是靠调参玄学堆出来的AI绘画玩具。它是一套由 CLIP、潜在扩散模型&#xff08;Latent Diffusion Model&#xff09;、UNet 主干网络、VAE 编解码器共同构成的精密协…

作者头像 李华
网站建设 2026/10/26 13:53:44

9家AI独角兽背后的技术栈与工程化估值逻辑

1. 开年数据速览&#xff1a;9家新贵和224亿美元说明什么 2025年开年没到三个月&#xff0c;全球AI投资圈就排队交出了成绩单。我这两天翻融资档案&#xff0c;最抢眼的是一行统计&#xff1a;今年前两个月&#xff0c;全球新出现9家AI独角兽&#xff0c;合计估值224亿美元。平…

作者头像 李华
网站建设 2026/10/26 13:53:11

四川企业用工风险咨询:核心价值与服务解析

1. 四川企业用工风险咨询的核心价值解析 在四川这个民营经济活跃的省份&#xff0c;企业用工风险咨询已成为刚需服务。去年成都某科技公司因未规范签订劳动合同&#xff0c;被前员工集体仲裁索赔87万元的真实案例&#xff0c;让不少企业主意识到专业用工咨询的重要性。用工风险…

作者头像 李华
网站建设 2026/10/26 13:52:59

C盘优化全攻略:10种方法解决系统变慢问题

1. 为什么C盘会变慢&#xff1f;先搞懂原理再动手 机械硬盘时代&#xff0c;C盘空间不足直接导致系统卡顿是常识。但很多人不知道的是&#xff0c;即使使用SSD固态硬盘&#xff0c;C盘剩余空间低于15%时&#xff0c;Windows的预读机制和虚拟内存性能也会断崖式下跌。我经手过数…

作者头像 李华
网站建设 2026/10/26 13:52:46

Windows下C++ OpenSSL RSA加密实战:从密钥生成到分块与避坑

简介&#xff1a;这份资源面向需要在 Windows 平台使用 C 完成 RSA 加解密开发的初中级程序员&#xff0c;针对网上多数示例为 Linux 版、代码老旧且内容残缺导致难以调试的问题&#xff0c;提供一套可直接编译运行的完整工程。压缩包共 12 个文件&#xff0c;约 450KB&#xf…

作者头像 李华