Python+Selenium序列化对象为JSON时报错mappingproxy无__dict__属性
问题根因
open_tagged_tickets函数内存在错误的变量覆盖逻辑:你调用json.dumps(driver.toJson(), indent=4)得到的是JSON字符串,直接赋值给了原来存储CMCHomePage实例的driver变量,后续调用driver.switch_to_iframe本身就会因为字符串没有对应方法报错,这是优先级最高的逻辑错误。同时toJson方法本身已经返回了json.dumps的结果,对JSON字符串重复序列化也是完全多余的操作。- 序列化逻辑错误触发
mappingproxy属性报错:CMCHomePage的toJson是实例方法,但没有声明self参数,调用时默认传入的实例对象会被赋值给obj参数- 你尝试序列化整个页面对象,对象内部包含Selenium原生驱动实例,Selenium大量内部类使用
mappingproxy类型存储类属性,该类型没有__dict__属性,因此触发属性错误。
- iframe切换参数类型错误:
switch_to.frame方法只接受Selenium原生WebElement、iframe的id/name属性值、索引,你传入的是自己封装的BaseElement实例,就算前面的错误修好也无法完成切换。
可行解决方案
最简修复方案(满足核心iframe切换需求)
直接删掉open_tagged_tickets里无用的序列化代码,调整iframe切换的参数即可,修改后代码:
from selenium.webdriver.support.select import Select def open_tagged_tickets(cmc_page): # 改名避免和原生driver混淆 iframe = cmc_page.iframe() # 直接调用切换方法,传入BaseElement封装的原生web_element cmc_page.switch_to_iframe(iframe.web_element)
如果不需要序列化页面对象的功能,直接删掉CMCHomePage类里的toJson方法即可,问题完全解决。
如果你确实需要保留序列化功能
修改toJson方法为标准实例方法,只序列化自定义的可序列化属性,排除Selenium原生对象:
def toJson(self): # 按需添加你需要序列化的自定义属性即可,不要包含self.driver等Selenium原生对象 serialize_dict = { "page_url": self.url } return json.dumps(serialize_dict, indent=4)
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

