关键在于区分“源码”与“当前页面显示的html”:view page source显示服务器返回的原始html(js未执行,无动态内容),elements面板显示js运行后的实时dom树(含所有动态渲染结果)。

直接看懂网页 HTML 代码,关键不是“背标签”,而是建立「源码 → 渲染结果 → DOM 实时状态」三者的对应关系。只看 View Page Source(右键→查看网页源代码)或只盯 Elements 面板,都会漏掉一半真相。
怎么区分“源码”和“当前页面显示的HTML”?
这是新手最常卡住的第一步。两者根本不是一回事:
-
View Page Source(Ctrl+U)看到的是服务器返回的原始 HTML 字符串——JS 还没执行,动态内容全为空,class名可能是loading,真实数据一个都没有 -
Elements面板(F12 → Elements)看到的是 JS 运行后、浏览器最终渲染出的实时 DOM 树——按钮已可点击、列表已加载、class可能变成了loaded item__3xKm - 如果在
View Page Source里搜不到你要找的文本,但页面上明明显示着,那它 100% 是 JS 渲染出来的,requests+BeautifulSoup直接抓这个 URL 就会失败
Elements 面板点不动、选不中目标元素?
不是工具坏了,是页面结构“活”了:
- React/Vue/Angular 类框架通常把整个页面挂在一个空容器(如
<div id="root"></div>)下,初始Elements里只有这个空壳,内容靠 JS 异步插入 - 滚动加载、点击展开、Tab 切换等交互,往往触发 XHR/Fetch 请求拉取 JSON 或 HTML 片段,再用 JS 插入 DOM —— 这些新节点不会出现在初始源码里
- 实操建议:打开
Network面板 → 切到XHR或Fetch标签 → 刷新页面或触发操作(比如点“加载更多”),找返回数据的请求;它的响应体(Response)才是你真正该解析的内容
右键“Copy selector”为什么总失效?
因为自动生成的 CSS 选择器太依赖页面瞬时状态:
-
#app > div:nth-child(2) > ul > li:first-child这类路径极易断裂:加个广告位、改个组件顺序、服务端 AB 测试切个分支,就全匹配不上 - 动态 class 名(如
item__2Kx9、btn_active_abc123)是 Webpack/CSS-in-JS 的产物,每次构建都变,不能硬写死 - 更靠谱的做法:右键目标元素 →
Copy → Copy XPath,再人工简化,比如把含哈希的 class 去掉,保留语义性部分://ul[@class="product-list"]//li[contains(@class, "item")] - 如果必须用 CSS 选择器,优先选稳定属性:
[data-testid="product-item"]、[aria-label="价格"]、button[type="submit"]
Selenium 等不到元素?别只调长时间
WebDriverWait(driver, 10).until(EC.presence_of_element_located(...)) 失败,大概率不是超时,是等待条件错了:
-
presence_of_element_located只确认元素进了 DOM,但可能还在 loading 中、被遮挡、不可见、没绑定事件 - 要等按钮可点:用
element_to_be_clickable - 要等文字填进去了(比如异步填充的
<span></span>):用text_to_be_present_in_element,传元组(By.XPATH, '//span')和预期文本 - 要等某个 class 被 JS 移除(如
loading消失):用invisibility_of_element_located - 所有等待都基于当前 driver 的 DOM 快照——如果页面跳转或进了
iframe,必须先switch_to.frame()或等新页面加载完成
真正难的不是找到那个 <div>,而是判断它什么时候“算真正存在”。源码里没有、Elements 里还没出现、Network 里还没返回、Selenium 等不到……这些状态切换的间隙,才是分析网页结构最需要盯住的地方。</div>
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











