使用Selenium提取page_source时无法获取页面显示数据的解决求助
看起来你遇到了AngularJS动态渲染页面的常见问题——这类页面的实际数据并不直接写在HTML的静态结构里,而是存在JavaScript的模型(Model)中,所以直接拿page_source只能拿到页面的模板框架,看不到渲染后的实际值,比如CNPJ的04.031.960/00001-70。
问题根源
这个CVM页面是用AngularJS构建的,你看到的CNPJ输入框是绑定到$responsavel.ofertante.cnpj这个Angular模型变量的。页面显示的值是Angular从模型中动态渲染出来的,不会直接出现在input标签的value属性里,所以静态HTML(也就是page_source)里自然看不到。
解决方法:通过执行JavaScript访问Angular模型
Selenium允许我们直接在浏览器中执行JavaScript代码,这样就能直接访问Angular的模型数据,拿到页面显示的实际值。
1. 获取单个字段(比如CNPJ)
针对你提到的CNPJ输入框,可以用下面的代码获取它的实际值:
# 执行JS代码获取Angular模型中的CNPJ值 cnpj_value = driver.execute_script(""" // 找到绑定了目标模型的input元素 const inputElement = document.querySelector('input[data-ng-model="$responsavel.ofertante.cnpj"]'); // 获取该元素对应的Angular作用域(scope) const scope = angular.element(inputElement).scope(); // 返回模型中的CNPJ值 return scope.$responsavel.ofertante.cnpj; """) print(cnpj_value) # 输出:04.031.960/00001-70
2. 等待页面完全渲染
另外,你的代码里没有添加等待逻辑,可能点击操作后页面还没完成Angular的渲染就去拿数据了,导致获取失败。建议添加显式等待,确保Angular已经完成渲染:
from selenium.webdriver.support.ui import WebDriverWait # 等待Angular的消化循环完成(确保页面渲染完毕) WebDriverWait(driver, 15).until( lambda driver: driver.execute_script("return angular.element(document.body).scope().$$phase === null") )
3. 批量获取其他字段
如果需要获取多个绑定了Angular模型的字段,只需要找到对应的data-ng-model属性,替换上面代码中的模型路径即可。比如获取其他字段时,只需要修改return scope.xxx.xxx部分。
为什么不能直接选中页面值?
页面中的值无法选中也是同样的原因——这些值是Angular动态渲染的,并没有直接写入DOM的value或文本节点中,所以普通的选中操作(比如鼠标拖动)或者用Selenium的get_attribute('value')都拿不到,必须通过访问Angular模型的方式获取。
内容的提问来源于stack exchange,提问作者fmarques

