如何将Cypress JS脚本转为Python,从JSON数组获取目标id
将Cypress JSON数组处理脚本转换为Python代码
问题背景
已实现Cypress中从JSON数组获取目标元素ID的功能,现在需要转换成适配Selenium的Python代码,但自行编写的Python脚本运行后返回None,无法得到预期结果。
目标JSON数组
[ { "id": 3328367679, "inbox_id": 35584, "subject": "Open this message" }, { "id": 3328364404, "inbox_id": 35584, "subject": "Another message" }, { "id": 3328363502, "inbox_id": 35584, "subject": "Open this message" }, { "id": 3328357254, "inbox_id": 35584, "subject": "Open this message" }, { "id": 3328349654, "inbox_id": 35584, "subject": "Open this message" } ]
可正常运行的Cypress JavaScript脚本
该脚本遍历JSON数组,找到第一个subject为"Open this message"的元素,返回其id值(即3328367679):
function getMessageID() { cy.request({ url: Cypress.env('url'), method: 'GET', headers: { 'Api-Token': Cypress.env('token'), 'Content-Type': 'application/json;charset=utf-8' }, }) .then((response) => { expect(response.status).to.eq(200) var messages = response.body var messageTitle = 'Open this message' for (var i = 0; i < messages.length; i++){ if (messages[i].subject == messageTitle){ return messages[i].id break; } } }) } getMessageID()
自行编写的Python脚本(存在问题)
运行后打印结果为None,在feature文件中调用:
def get_messages(): url = "https://uri.io/api/accounts/fdsdfs/inboxes/dfsfds/messages/" headers = { "Content-Type": "application/json;charset=utf-8", "Api-Token": "123345dsfgsdrgf3456dfg5634dfv5" } response = requests.get(url=url, headers=headers) return response.json() @staticmethod def get_id(): messages = ClassName.get_messages() message_title = "Open this message" for item in messages: if item["subject"] == message_title: print("Message id is " + item["id"]) return item["id"] break
也尝试过嵌套循环,同样无法得到正确结果:
def get_id(): messages = ClassName.get_messages() message_title = "Open this message" for json_item in messages: for message_item in json_item: if message_item["subject"] == message_title: print("Message id is " + str(message_item["id"])) return message_item["id"] break
已知print(messages[0]["subject"])可以正常打印subject值,但不清楚如何正确遍历获取目标ID。
解决方案
问题分析
你编写的两个Python脚本都存在核心问题:
- 第一个脚本中,
break语句放在if的else分支,导致循环只执行一次就终止,根本没遍历后续元素; - 第二个嵌套循环逻辑错误:
json_item是字典,遍历它得到的是键名(如"id"、"subject"),不是字典本身,后续message_item["subject"]会直接报错。
正确的Python代码
import requests def get_messages(): url = "https://uri.io/api/accounts/fdsdfs/inboxes/dfsfds/messages/" headers = { "Content-Type": "application/json;charset=utf-8", "Api-Token": "123345dsfgsdrgf3456dfg5634dfv5" } response = requests.get(url=url, headers=headers) # 对应Cypress的状态码验证,请求失败直接抛出异常 response.raise_for_status() return response.json() @staticmethod def get_id(): messages = ClassName.get_messages() message_title = "Open this message" # 遍历所有消息元素,直到找到第一个匹配项 for item in messages: if item["subject"] == message_title: # 用f-string处理数字转字符串拼接,避免报错 print(f"Message id is {item['id']}") return item["id"] # 遍历完无匹配项时返回None,也可根据需求抛出异常 return None
代码说明
- 请求验证:添加
response.raise_for_status(),对应Cypress里的expect(response.status).to.eq(200),确保请求成功才继续处理; - 循环逻辑:移除多余的
break,让循环正常遍历数组元素,找到第一个匹配项后立即返回其id; - 字符串处理:使用f-string简化拼接,同时处理
id为数字类型的问题,避免直接拼接字符串报错; - 边界处理:遍历完无匹配项时返回
None,也可改为抛出异常,比如raise ValueError("未找到指定主题的消息")。
Pythonic简化写法
可以用生成器表达式结合next()直接获取第一个匹配项,代码更简洁:
@staticmethod def get_id(): messages = ClassName.get_messages() message_title = "Open this message" # next()的第二个参数为无匹配时的默认返回值 target_item = next((item for item in messages if item["subject"] == message_title), None) if target_item: print(f"Message id is {target_item['id']}") return target_item["id"] return None
内容的提问来源于stack exchange,提问作者Faith Berroya
相关产品推荐
相关产品推荐

