Python爬虫入门教程:requests+BeautifulSoup实现合规数据采集

发布时间:2026/8/30 3:51:30

Python爬虫入门教程:requests+BeautifulSoup实现合规数据采集
Python 爬虫是很多开发者入门自动化数据采集时最先接触的技术。市面上的教程经常把“抓取 VIP 付费视频”“绕过会员限制”当作卖点这类内容既违反目标网站的使用条款也可能触及版权和数据安全红线。真正值得学习的爬虫能力是在规则允许的范围内用 Python 获取公开数据并把它变成结构化、可复用、可维护的数据流水线。本文会从零搭建一个最小但完整的 Python 爬虫项目使用requests获取网页 HTML使用BeautifulSoup解析标题、价格和评分字段再通过分页循环批量抓取多个页面最后把数据保存为 CSV 和 JSON 文件。示例目标使用专门为爬虫练习设计的公开网站books.toscrape.com这是一个允许爬虫测试的学习站点不涉及版权内容。学完之后你可以把同样的思路迁移到天气数据、公开新闻、开源资料等合规场景。1. 写爬虫之前先弄清请求、解析和合规边界1.1 HTTP 请求与响应爬虫实际上是在模拟浏览器爬虫的本质是“用代码发送 HTTP 请求拿到服务器返回的 HTML 或 JSON再从中提取需要的数据”。浏览器打开一个页面时会发送一个 GET 请求服务器返回 HTML 文本爬虫做的事情与浏览器基本相同只不过我们不需要 JavaScript 渲染而是直接分析服务器返回的文本。用requests发送一个最简单请求只需要几行代码import requests url https://books.toscrape.com/ resp requests.get(url, timeout10) print(resp.status_code) print(resp.text[:500])这段代码会返回 HTTP 状态码和网页源码前 500 个字符。状态码是判断请求是否成功的重要依据常见的状态码需要提前掌握状态码含义爬虫中常见场景200请求成功正常返回页面内容301永久重定向页面换了地址请求会自动跳转403服务器拒绝访问缺少 User-Agent 或触发反爬规则404页面不存在URL 拼接错误或资源已删除418被识别为爬虫部分服务器会返回这个状态码拒绝服务429请求频率过高触发限流需要降速500服务器内部错误目标站点自身异常可稍后重试实际开发中不要只判断状态码是否为 200还应该用resp.raise_for_status()主动抛出 HTTP 错误避免把 403、404 页面当成正常数据继续解析。1.2 robots.txt 与合规边界不是所有能访问的数据都能爬robots.txt是网站用来声明“哪些路径允许搜索引擎和爬虫访问”的协议文件。访问方式是在域名后加上/robots.txt例如https://books.toscrape.com/robots.txtbooks.toscrape.com的 robots 内容大致允许爬虫抓取。但很多真实网站会明确禁止抓取某些路径例如用户中心、支付页面、视频播放地址、个人隐私数据等。合规判断可以按这个顺序进行查看目标网站的robots.txt不允许抓取的路径不碰。阅读网站服务条款或用户协议明确数据使用范围。只抓取公开数据不抓取需要登录、付费或加密后才能访问的内容。不要通过隐藏 User-Agent、伪造身份等手段刻意绕过反爬限制。对抓取的数据做二次处理时注意版权、隐私和商业使用限制。这里要特别说明付费视频、VIP 影视内容、会员制信息都属于受版权保护的内容爬取这类资源不仅违反网站条款还可能涉嫌侵权。本文所有示例都只围绕公开免费页面展开不涉及任何“破解付费”相关内容。1.3 静态页面与动态页面为什么有些数据明明在页面上却抓不到在浏览器里能看到的数据不一定都在 HTML 源码里。网页分为两种渲染方式服务端渲染服务器把 HTML 拼接好直接返回爬虫拿到 HTML 就能解析出数据。客户端渲染服务器只返回一个空壳 HTML真实数据由 JavaScript 在浏览器中异步请求 API 后动态渲染到页面上。books.toscrape.com属于服务端渲染页面直接在 HTML 中可以看到书籍信息适合入门。判断一个页面到底是静态还是动态最简单的方法是在浏览器中打开页面右键查看网页源代码搜索你看到的数据。如果源代码里有就是静态页面如果源代码里没有说明数据来自后面的 API 请求此时需要在浏览器开发者工具的 Network 面板中查找 XHR 或 Fetch 请求。这个判断很关键。很多爬虫新手在动态页面上反复修改 HTML 选择器却拿不到数据就是因为解析对象从一开始就选错了。2. 环境准备Python 版本、虚拟环境和依赖2.1 安装 Python 与创建虚拟环境本文示例使用 Python 3.9 以上版本建议使用 3.11 或 3.12。安装完成后在命令行输入以下命令确认版本python --version不同操作系统下创建虚拟环境的命令略有差异# Windows python -m venv venv venv\Scripts\activate # macOS / Linux python3 -m venv venv source venv/bin/activate虚拟环境可以把项目依赖与系统全局环境隔离避免多个项目之间出现包版本冲突。进入虚拟环境后命令行提示符前面会出现(venv)标记这是环境激活成功的标志。2.2 安装核心依赖在激活的虚拟环境中执行pip install requests beautifulsoup4 lxml三个库的用途如下依赖用途requests发送 HTTP 请求获取网页 HTML 或 API JSONbeautifulsoup4解析 HTML 文档提供查找节点和提取数据的方法lxmlBeautifulSoup 的解析引擎比默认的 Python 解析器更快安装完成后可以使用以下代码验证导入是否正常import requests import bs4 import lxml print(requests.__version__) print(bs4.__version__)2.3 准备示例目标网站示例网站books.toscrape.com是一个虚构的图书商店专门为爬虫学习者设计。页面结构稳定分类和分页清晰不涉及真实商业数据和版权风险。在开始写代码前建议先在浏览器中打开首页按 F12 打开开发者工具查看一个书籍卡片对应的 HTML 结构。这样等会儿写选择器时你会清楚每个字段对应哪个节点。如果示例网站无法访问也可以把首页 HTML 保存到本地文件然后用open(books.html, encodingutf-8)读取本地文件来解析。本地文件不涉及网络请求适合调试解析逻辑。3. 从单页抓取开始requests 加 BeautifulSoup 的最小闭环3.1 抓取首页并检查响应第一步是写一个函数负责请求页面并返回可解析的 BeautifulSoup 对象。这里的关键不是“能请求通”而是“用合理的方式请求”包括设置 User-Agent、超时时间和编码。import requests from bs4 import BeautifulSoup BASE_URL https://books.toscrape.com/ HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 } def fetch_soup(url): resp requests.get(url, headersHEADERS, timeout10) resp.raise_for_status() resp.encoding resp.apparent_encoding return BeautifulSoup(resp.text, lxml) soup fetch_soup(BASE_URL) print(soup.title.text)这里有几处容易被忽略的细节headers中的 User-Agent 用于声明客户端身份。部分网站会拒绝没有 User-Agent 的请求设置成正常浏览器标识可以避免一些不必要的拦截。timeout10限制请求最多等待 10 秒避免某个请求卡死导致程序一直挂起。resp.encoding resp.apparent_encoding用页面的实际编码覆盖 requests 猜测的编码防止中文乱码。raise_for_status()会在状态码为 4xx/5xx 时抛出异常避免把错误页面当作数据源。3.2 用 BeautifulSoup 解析书名、价格和评分在浏览器中查看首页 HTML可以观察到每本书都位于article.product_pod节点中。书名在h3 a的title属性里价格在p.price_color文本中评分在p.star-rating的 class 属性中。def parse_books(soup): books [] for article in soup.select(article.product_pod): title article.h3.a.get(title) price article.select_one(p.price_color).text rating article.select_one(p.star-rating).get(class) books.append({ title: title, price: price, rating: rating, }) return books books parse_books(soup) print(len(books)) print(books[0])select和select_one接收的是 CSS 选择器这是 BeautifulSoup 中比较方便的定位方式。article.product_pod表示查找所有 class 为product_pod的 article 节点。随后的p.price_color和p.star-rating同理。rating在 HTML 中的形态类似p classstar-rating Three.../p所以get(class)返回的是列表[star-rating, Three]实际评分等级在第二个元素中。可以进一步处理成统一格式rating_class article.select_one(p.star-rating).get(class) rating rating_class[1] if len(rating_class) 2 else Unknown3.3 输出结构化数据把解析结果打印出来单页数据应当是一个包含 20 本书的列表每本书包含标题、价格和评分字段for book in books[:3]: print(book)预期输出类似{title: A Light in the Attic, price: £51.77, rating: Three} {title: Tipping the Velvet, price: £53.74, rating: One} {title: Soumission, price: £50.10, rating: One}到这里最小的“请求 - 解析 - 输出”闭环已经跑通。接下来要解决的是批量问题一个页面只有 20 本书如果网站有几百个页面不可能手动逐个请求。4. 批量抓取分页、限速与数据保存4.1 理解分页 URL 规律批量抓取的前提是先找出分页 URL 的规律。books.toscrape.com的分页结构为第 1 页https://books.toscrape.com/第 2 页https://books.toscrape.com/catalogue/page-2.html第 3 页https://books.toscrape.com/catalogue/page-3.html也就是说从第 2 页开始URL 遵循catalogue/page-{n}.html的规律。代码里可以把首页和后续页面统一处理def get_page_url(page): if page 1: return https://books.toscrape.com/ return fhttps://books.toscrape.com/catalogue/page-{page}.html实际项目中分页形式五花八门有的使用查询参数?page2有的使用page/2/有的需要从页面底部的下一页按钮解析真实链接。遇到不规律的网站应该先观察“下一页”按钮的 URL 规律或者直接用soup.select_one(li.next a).get(href)动态获取下一页地址而不是硬编码页码。4.2 分页循环与限速设计批量抓取时要重点考虑抓取频率。爬虫的本质是持续向服务器发送请求如果频率过高轻则触发限流重则影响目标网站正常运行。合理做法是每次请求后停顿一段时间。import time def crawl_pages(start_page1, max_pages3): all_books [] for page in range(start_page, max_pages 1): url get_page_url(page) print(f正在抓取第 {page} 页: {url}) soup fetch_soup(url) books parse_books(soup) all_books.extend(books) print(f第 {page} 页解析到 {len(books)} 条数据) time.sleep(1) return all_books all_books crawl_pages(max_pages3) print(f共抓取 {len(all_books)} 条数据)这里的关键是time.sleep(1)它让每次请求之间至少间隔 1 秒。对于小型练习项目每秒 1 个请求已经足够对于正式项目建议把请求频率控制在目标网站可接受的范围内并且观察服务器的响应情况遇到 429 或 403 时立即降速。4.3 把数据保存为 CSV 和 JSON抓取到的数据如果只存在内存中程序一停就丢失了。把结果落盘成文件后续才能继续使用。CSV 适合用 Excel 打开JSON 适合程序之间交换数据。两者都写一份import csv import json def save_to_csv(books, filenamebooks.csv): with open(filename, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnames[title, price, rating]) writer.writeheader() writer.writerows(books) def save_to_json(books, filenamebooks.json): with open(filename, w, encodingutf-8) as f: json.dump(books, f, ensure_asciiFalse, indent2) save_to_csv(all_books) save_to_json(all_books)encodingutf-8-sig会在 CSV 文件开头写入 BOMExcel 打开时中文不会乱码ensure_asciiFalse让 JSON 保存中文时保持可读。如果抓取数量大还需要考虑断点续爬的思想。最简单的方式是把“已抓取的页码”记录到一个单独的文本文件或数据库表中下次启动时从上次停止的页码继续而不是从头开始。5. 让爬虫更健壮异常处理、日志和项目结构5.1 网络请求的异常处理真实网络环境远比本地测试复杂。服务器可能超时、连接可能被重置、目标网站可能临时故障。如果不处理异常一个请求失败就会导致整个爬虫崩溃。比较稳妥的做法是封装一个带重试机制的请求函数import time import requests def fetch_with_retry(url, headersHEADERS, timeout10, retries3): for attempt in range(1, retries 1): try: resp requests.get(url, headersheaders, timeouttimeout) resp.raise_for_status() resp.encoding resp.apparent_encoding return resp except requests.exceptions.Timeout: print(f第 {attempt} 次请求超时: {url}) except requests.exceptions.RequestException as e: print(f第 {attempt} 次请求异常: {e}) time.sleep(2 ** attempt) return None这里使用了指数退避的重试策略第一次失败等待 2 秒第二次失败等待 4 秒第三次失败等待 8 秒。这样既能给服务器留出恢复时间也避免在故障发生时继续高频重试加重负担。调用时先判断返回值是否为Noneresp fetch_with_retry(url) if resp is None: print(f无法获取页面跳过: {url}) return [] soup BeautifulSoup(resp.text, lxml)5.2 解析阶段防错网页结构和示例不总是一致。某个书名可能没有title属性某个价格节点可能不存在某个字段可能是空字符串。解析代码要养成“先判空、再取值”的习惯。def parse_books(soup): books [] for article in soup.select(article.product_pod): title_node article.h3.a if article.h3 and article.h3.a else None title title_node.get(title) if title_node else price_node article.select_one(p.price_color) price price_node.text if price_node else rating_node article.select_one(p.star-rating) rating if rating_node: classes rating_node.get(class, []) rating classes[1] if len(classes) 2 else books.append({ title: title.strip(), price: price.strip(), rating: rating, }) return books这种写法的好处是某个字段解析失败时不会因为调用None.text而抛出AttributeError。爬虫代码里一个看似不起眼的None判断往往能省去大量排查时间。5.3 工程化项目结构当爬虫从脚本升级为项目时建议拆分成多个模块每个模块只负责一件事。一个适合练习的目录结构如下scraper/ ├── requirements.txt ├── config.py ├── fetcher.py ├── parser.py ├── storage.py ├── spider.py └── main.py各模块职责文件职责config.py存放 URL、请求头、超时时间、重试次数等配置fetcher.py负责发送 HTTP 请求和重试逻辑parser.py负责从 HTML 中提取结构化数据storage.py负责把数据保存为 CSV、JSON 或数据库记录spider.py负责分页调度和流程编排main.py程序入口负责参数解析和启动生产级爬虫还要加入日志模块。直接用print打印信息在调试阶段够用但正式运行时print 的信息不会自动写入文件也无法按级别过滤。推荐使用 Python 自带的loggingimport logging logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(crawler.log, encodingutf-8), logging.StreamHandler(), ] ) logger logging.getLogger(__name__)这样日志同时输出到文件和控制台程序运行后还能留下完整的记录。6. 运行验证与常见问题排查6.1 如何验证爬虫结果正确爬虫跑完不代表数据正确。运行完成后至少要做四项校验数量校验books.toscrape.com首页应为 20 条数据多页数据总量应当等于每页数量之和。字段完整性校验每条数据的title、price、rating三个字段都不能为空。格式校验价格是否包含货币符号评分是否为 One 到 Five 的字符串。重复校验不同页面之间是否出现重复数据说明分页逻辑或选择器可能出了问题。from collections import Counter titles [book[title] for book in all_books] duplicates [t for t, cnt in Counter(titles).items() if cnt 1] print(f数据总量: {len(all_books)}) print(f重复数量: {len(duplicates)})一份合格的数据不只要有“能跑通的代码”还要有“能解释清楚的数据质量结论”。6.2 高频异常与排查路径以下表格汇总了爬虫开发中最常见的几类问题问题现象常见原因检查方式处理建议请求返回 403请求头缺少 User-Agent或频率过高被拦截检查请求头、登录状态、请求频率补充浏览器 User-Agent降低频率返回 418被服务器识别为自动化脚本检查 User-Agent、Cookie、访问模式不要对抗反爬检查是否合规或停止抓取HTML 乱码编码判断错误打印resp.encoding和页面 meta 标签设置resp.encoding resp.apparent_encoding解析结果为空CSS 选择器写错或数据由 JS 动态渲染查看网页源代码确认数据在 HTML 中存在修正选择器或改为请求底层 API 接口请求卡死不退出未设置 timeout查看程序停留位置所有请求都加timeout参数抓取到中途被封请求频率过高查看之前是否有 403/429降低请求频率增加随机等待时间保存的 CSV 出现空行打开文件时未设置newline检查写入代码使用open(filename, w, newline)排查有个固定顺序先确认请求是否成功再确认 HTML 是否包含目标数据再确认选择器是否写对最后确认存储方式是否正确。不要一上来就怀疑程序哪里写错了先看请求返回的原始内容是什么。6.3 用浏览器开发者工具辅助调试当页面结构或接口不清楚时用手写代码猜测远不如直接观察浏览器开发者工具。打开目标页面按 F12在 Network 面板中刷新页面就能看到所有网络请求。排查动态页面时重点关注类型为XHR或Fetch的请求它们通常返回 JSON 数据。请求的 URL 中的参数比如分页页码、查询关键词、排序方式。响应的数据格式如果 JSON 里已经有完整数据就不需要解析 HTML。浏览器中也可以把某个请求复制成 cURL 命令然后在命令行里执行这样能快速确认请求是否成功也能看到服务器返回的原始信息。7. 爬虫的合规边界与生产环境注意事项7.1 学习环境与生产环境的差异同一个爬虫在练习环境和生产环境中的要求完全不同。不能因为本地跑通了就认为可以直接部署对比项学习环境生产环境数据量几十条到几百条百万级甚至更高存储CSV/JSON 文件MySQL、PostgreSQL、对象存储等调度手动运行脚本定时任务、消息队列监控无日志、告警、失败重试、数据质量校验反爬应对直接请求合理限速、代理池、登录授权异常处理基本 try/except重试、死信队列、人工介入机制生产环境的爬虫是把数据采集当作一条可持续运行的业务链路来对待而不是一锤子买卖。7.2 爬虫也会伤害服务端频率、限速和公平性很多爬虫问题不是“技术做不到”而是“频率控制得太激进”。即使目标网站允许爬虫过高的并发和请求频率也会导致服务器负载上升甚至影响正常用户访问。合理的限速策略包括每两次请求之间至少间隔 1 秒。对同一域名的请求做好整体频率控制而不是只控制单个页面。优先使用目标网站提供的官方 APIAPI 通常有明确的频率限制文档。开启压缩传输减少从服务器下载的数据量。对于大文件资源使用流式下载避免一次性占用大量内存。爬虫质量高不高不取决于请求速度而取决于能否在尽量不打扰目标站点的前提下稳定获取完整、准确的数据。7.3 数据使用与版权抓取公开数据之后如何使用仍然受法律和平台条款约束。具体表现在个人学习、研究用途与商业用途的合规边界不同。涉及个人隐私的数据即使技术上能抓到也不能随意采集和存储。版权内容、付费内容、会员专属内容是明令禁止爬取的对象。对方网站明确禁止爬虫抓取的路径无论技术上是否可行都应当停止。本文用于示例的books.toscrape.com是公开练习网站数据本身是虚构的适合学习解析逻辑。真实项目中如果有数据需求优先寻找官方 API、开放数据集或授权接口爬虫永远是最后的选择。8. 可复用的爬虫开发清单与扩展方向8.1 从零到上线的检查清单这里是一份可以直接使用的清单写任何爬虫前先逐项确认目标网站是否允许爬虫访问robots.txt是否放行。目标数据是否公开可用是否涉及个人隐私、版权或付费内容。是否理解了页面数据是服务端渲染还是客户端渲染。请求是否设置了 User-Agent、超时和合理编码。是否处理了请求超时、连接错误、HTTP 错误和重试逻辑。解析逻辑是否对空节点做了判空保护。分页规则是否正确是否可能出现死循环。是否设置了请求间隔避免对服务器造成压力。数据保存前是否做了去重和格式校验。日志是否完整能否定位某次抓取失败的时间、URL 和原因。数据库或文件中是否记录了上次抓取进度支持断点续爬。是否考虑过数据版权和使用限制不在未授权场景中商用。8.2 接下来可以学什么跑通这个最小项目后可以从以下几个方向继续深入Scrapy 框架学习如何用框架管理请求、解析、去重和导出适合大型爬虫项目。动态页面抓取了解 Playwright 或 Selenium 如何驱动浏览器加载 JavaScript但优先尝试寻找底层 API。数据清洗与入库把抓取结果从 CSV 升级到 MySQL 或 SQLite学习去重、增量更新。定时调度使用 APScheduler、Cron 或 Airflow 让爬虫按计划运行。监控与告警当抓取失败、数据量异常、目标页面结构变化时如何快速感知。对初学者来说最有价值的练习不是找各种“破解”教程而是把本文的最小项目反复重写几遍改目标网站、改解析字段、改存储方式。每次都去处理真实请求中遇到的超时、编码、空节点、分页问题这些经验才是爬虫能力真正的组成部分。爬虫技术的价值在于高效获取公开信息而不是绕过限制、窃取隐私或破坏他人服务。把这一条边界守住再去学习请求、解析、存储和调度你的 Python 爬虫之路才会越走越稳。

相关新闻

人形机器人本体厂生态卡位:乐聚对外投资的战略逻辑与启示

人形机器人本体厂生态卡位:乐聚对外投资的战略逻辑与启示

2026/8/30 3:41:30

1. 这篇文章真正要解决的问题人形机器人赛道这两年的热度,已经不需要再科普了。从特斯拉 Optimus 到波士顿动力 Atlas,再到国内一批创业公司接连完成大额融资,整个行业的叙事已经从“能不能造出来”快速切换到了“谁能先跑通商业闭环”。但有…

鲁棒MDP的ω-正则目标定量分析:minimax值迭代与Python实践

鲁棒MDP的ω-正则目标定量分析:minimax值迭代与Python实践

2026/8/30 3:41:30

这次我们来看一个偏理论、但对强化学习与形式化验证都很有分量的题目:Robust MDP(鲁棒马尔可夫决策过程)上的 ω-正则目标定量分析。这类工作一般不以“一键启动包”的形式出现,但它解决的问题非常实际:当系统模型的转…

DeepSeek Harness与V4-Pro编程能力对比:从0.3%差距看真实开发效能

DeepSeek Harness与V4-Pro编程能力对比:从0.3%差距看真实开发效能

2026/8/30 3:41:30

这两天的讨论里,DeepSeek Harness 和 V4-Pro 编程能力的对比是个绕不开的话题。最让人印象深刻的不是模型本身,而是几个反差很大的数字:宣传材料里说 V4-Pro 编程能力只比 Claude 旗舰版差 0.3%,但前端相关的服务费又说可能高出 1…

Llama Tests:从能跑模型到敢用模型的工程化测试方案

Llama Tests:从能跑模型到敢用模型的工程化测试方案

2026/8/30 5:01:33

从“能跑模型”到“敢用模型”:为什么每个 Llama 用户都需要一套“Llama Tests”如果你最近在折腾 Llama 系列模型,大概率会陷入同一种困惑:模型下载下来了,推理脚本也能跑通,demo 界面也弹出来了,输出看起…

百度2018校招AI异构计算工程师笔试题复盘:核心考点与备战路线

百度2018校招AI异构计算工程师笔试题复盘:核心考点与备战路线

2026/8/30 5:01:33

直接切入正题吧。这篇东西其实欠了挺久,我一直想找个机会把百度2018校招AI异构计算工程师(提前批)这套笔试题拿出来聊聊。原因很简单:虽然年份有点早,但这份卷子的考察思路放在今天依然很有参考价值,尤其是…

CLAUDE.md 与 AGENTS.md 实战指南:一套模板同时喂饱 Claude Code 与 Codex

CLAUDE.md 与 AGENTS.md 实战指南:一套模板同时喂饱 Claude Code 与 Codex

2026/8/30 5:01:33

CLAUDE.md 与 AGENTS.md 实战指南:一套模板同时喂饱 Claude Code 与 Codex 写给正在把 AI 编程助手引入团队工程流程的开发者。 本文提供一套经过验证的写作框架,以及前端、后端(Java / Python)、Monorepo 四类可直接套用的模板。 一、为什么需要这个文件 每个 AI 编程助手…

GPLv2合规判断指南:从源码提供义务到Android生态实践

GPLv2合规判断指南:从源码提供义务到Android生态实践

2026/8/30 5:01:33

当一句“Google is in clear violation of the GPLv2”出现在技术社区时,先不要急着站队。这个断言牵扯到 GPLv2 的许可证文本、链接边界、分发行为、源代码提供义务,以及 Android、Kernel、Bionic libc 这些具体工程组件之间的关系。作为一名开发者&…

STM32WL LoRaWAN节点在ChirpStack上因LinkADRReq静默的根因与修复

STM32WL LoRaWAN节点在ChirpStack上因LinkADRReq静默的根因与修复

2026/8/30 5:01:33

1. 现象复盘:同一个固件,TTN 上安安稳稳,ChirpStack 上几十秒后“哑掉”1.1 测试平台的完整配置这次问题的主角是一批基于 STM32WL55 的节点设备,用的是一颗将射频收发器和 Cortex-M4 应用核心集成在一起的 SoC,目标场…

软件测试面试高频考点与实战技巧:从八股文到Offer收割

软件测试面试高频考点与实战技巧:从八股文到Offer收割

2026/8/30 4:51:33

“金三银四”的春招号角已经吹响,软件测试岗位的竞争一年比一年激烈。最近很多读者私信我,问得最多的就是“2023年软件测试面试到底在考什么”、“八股文背了这么多,为什么一到面试官面前就卡壳”。作为在测试行业摸爬滚打了十年、参与过上百…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/8/30 0:01:07

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/8/30 0:01:07

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/8/30 0:01:07

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/8/30 0:01:07

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/8/30 0:01:07

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/8/30 0:01:07

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/28 7:35:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/28 7:34:51

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/28 7:34:35

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…