By ID/Name VS. xpath Vs. link text

本文探讨了Web自动化测试中使用ID、名称、XPath和链接文本定位元素的不同效率和适用场景。ID和名称定位提供更好的代码可读性和性能,而XPath则在复杂页面结构中更具灵活性。链接文本定位适用于频繁变更的链接文本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Id

Detail

Using an element ID or name locator

  1. Most efficient in terms of test performance
  2. Makes your test code more readable, assuming the ID or name within the page source is well-named

using XPath

  1. XPath statements take longer to process since the browser must run its XPath processor
  2. If the page source does not have an ID or name attribute you may have no choice but to use an XPath locator.
  3. With XPath (and DOM) you can locate an object with respect to another object on the page. For example, if there is a link that must occur within the second paragraph within a <div> section, you can use XPath to specify this. With ID and name locators, you can only specify that they occur on the page that is, somewhere on the page. If you must test that an image displaying the company logo appears at the top of the page within a header section, XPath may be the better locator.

Using link text

  1. Locating via a link’s text is often convenient and performs well.
  2. If the link’s text is likely to change frequently, locating by the <a> element would be the better choice.
In [4]: print(response.text[:2000]) # 查看前2000个字符 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>-东北石油大学</title><meta name="pageType" content="3"> <meta name="pageTitle" content="大会隆重开幕"> <META Name="keywords" Content="东北石油大学主站,东油要闻,代会,石油大学" /> <META Name="description" Content="为创建国内著名国际知名的一流能源大学而不懈奋斗!" /> <meta name="description" content=""> <link rel="stylesheet" type="text/css" href="../../css/base.css" /> <link rel="stylesheet" type="text/css" href="../../css/style.css" /> <link rel="Shortcut Icon" href="../../js/favicon.ico" type="image/x-icon" /> <script src="../../js/jquery.min.js"></script> <!--[if lt IE 9]> <script src="../../js/html5shiv.min.js"></script> <script src="../../js/respond.min.js"></script> <![endif]--> <!--Announced by Visual SiteBuilder 9--> <script language="javascript" src="../../_sitegray/_sitegray.js"></script> <!-- CustomerNO:77656262657232306578475050525742000400014e50 --> <link rel="stylesheet" type="text/css" href="../../content3.vsb.css" /> <script type="text/javascript" src="/system/resource/js/vsbscreen.min.js" id="_vsbscreen" devices="pc|pad"></script> <script type="text/javascript" src="/system/resource/js/counter.js"></script> <script type="text/javascript">_jsq_(1049,'/content3.jsp',19607,1598682733)</script> </head> <body> <!-- Start header --> <header> <div class="t_top f13"> <section> <div class="fl t_link"><script language="javascript" src="/system/resource/js/dynclicks.js"></script><script language="javascript" src="/system/resource/js/openlink.js"></script><a href="http://www.nepuqhd.net/" target="_blank" onclick="_addDynClicks("wburl", 1598682733, 64249)">秦皇岛校区</a><b>|</b> <a href="../../kstd/xs.htm" target="_blank" onclick="_addDynClicks("wburl", 15986
07-04
对于页面 <div class="container navigation"> <div class="row"> <div class="col nav"> <ul class="pc-nav" id="runoob-detail-nav"> <li><a href="//www.runoob.com/">首页</a></li> <li><a href="/html/html-tutorial.html">HTML</a></li> <li><a href="/css/css-tutorial.html">CSS</a></li> <li><a href="/js/js-tutorial.html">JavaScript</a></li> <li><a href="javascript:void(0);" data-id="vue">Vue</a></li> <li><a href="/react/react-tutorial.html">React</a></li> <!-- <li><a href="/nodejs/nodejs-tutorial.html">NodeJS</a></li>--> <li><a href="/python3/python3-tutorial.html">Python3</a></li> <!-- <li><a href="/python/python-tutorial.html">Python2</a></li> --> <li><a href="/java/java-tutorial.html">Java</a></li> <li><a href="/cprogramming/c-tutorial.html">C</a></li> <li><a href="/cplusplus/cpp-tutorial.html">C++</a></li> <li><a href="/csharp/csharp-tutorial.html">C#</a></li> <li><a href="javascript:void(0);" data-id="aiNav">AI</a></li> <li><a href="/go/go-tutorial.html">Go</a></li> <li><a href="/sql/sql-tutorial.html">SQL</a></li> <li><a href="/linux/linux-tutorial.html">Linux</a></li> <li><a href="/vscode/vscode-tutorial.html">VS Code</a></li> <!--<li><a href="/jquery/jquery-tutorial.html">jQuery</a></li>--> <li><a href="javascript:void(0);" data-id="bootstrap">Bootstrap</a></li> <li><a href="/git/git-tutorial.html">Git</a></li> <li><a href="/browser-history">本地书签</a></li><!-- <li><a href="https://www.jyshare.com/front-end/9235/" target="_blank">AI 编程助理</a></li> --> <!-- <li><a href="/w3cnote/knowledge-start.html" style="font-weight: bold;" onclick="_hmt.push(['_trackEvent', '星球', 'click', 'start'])" title="我的圈子">我的圈子</a></li> <li><a href="javascript:;" class="runoob-pop">登录</a></li> --> </ul> <ul class="mobile-nav"> <li><a href="//www.runoob.com/">首页</a></li> <li><a href="/html/html-tutorial.html">HTML</a></li> <li><a href="/css/css-tutorial.html">CSS</a></li> <li><a href="/js/js-tutorial.html">JS</a></li> <li><a href="/browser-history">本地书签</a></li> <li><a href="javascript:void(0)" class="search-reveal">Search</a> </li> </ul> </div> </div> </div> 识别到的结果 C:\own\app\python_code\.venv\Scripts\python.exe C:\own\app\python_code\work\入职培训\打印点击\导航栏识别测试.py 共识别出 8 个导航栏 导航栏 #1: <div class='container navigation'> 导航栏 #2: <div class='col nav'> 导航栏 #3: <ul class='pc-nav'> 导航栏 #4: <ul class='mobile-nav'> 导航栏 #5: <div class='container navigation'> 导航栏 #6: <div class='container navigation'> 导航栏 #7: <div class='row'> 导航栏 #8: <div class='col nav'> Process finished with exit code 0 识别不全啊 from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("file:///C:/own/app/python_code/work/入职培训/打印点击/111.html") def is_navigation_bar(element, max_depth=5, current_depth=0): try: if current_depth > max_depth: return False if element.tag_name.lower() == 'nav': return True role = element.get_attribute('role') if role and role.lower() == 'navigation': return True class_name = element.get_attribute('class') if class_name: class_name = class_name.lower() if any(keyword in class_name for keyword in ['nav', 'navbar', 'navigation', 'menu', 'bar']): return True if contains_navigation_structure(element): return True try: parent = element.find_element(By.XPATH, '..') return is_navigation_bar(parent, max_depth, current_depth + 1) except: return False except Exception as e: print(f"[导航栏识别] 出错: {e}") return False def contains_navigation_structure(element): """增强结构识别:查找是否有多个 <a>、<p> 或 <li>,支持深层嵌套结构""" links = element.find_elements(By.XPATH, './/a | .//p | .//li') link_count = 0 for el in links: if el.tag_name == 'a': href = el.get_attribute('href') if href and href != 'javascript:void(0);': link_count += 1 elif el.tag_name in ['p', 'li']: text = el.text.strip() if text: link_count += 1 if link_count >= 2: return True lists = element.find_elements(By.XPATH, './/ul | .//ol') if len(lists) >= 1: return True return False # ✅ 使用 CSS 选择器查找所有可能的候选元素 def find_all_navigation_bars(driver): candidates = [] # 1. 查找 <nav> 标签 nav_elements = driver.find_elements(By.TAG_NAME, 'nav') candidates.extend(nav_elements) # 2. 查找 role="navigation" role_navs = driver.find_elements(By.XPATH, '//*[@role="navigation"]') candidates.extend(role_navs) # 3. 查找常见 class 名称的元素 class_keywords = ['nav', 'navbar', 'navigation', 'menu', 'bar'] for keyword in class_keywords: elements = driver.find_elements(By.CSS_SELECTOR, f'[class*="{keyword}"]') candidates.extend(elements) # 4. 查找包含 ul/li 结构的容器 list_containers = driver.find_elements(By.XPATH, '//div[.//ul] | //div[.//ol] | //nav[.//ul] | //nav[.//ol]') candidates.extend(list_containers) # 去重 + 筛选 unique_candidates = [] seen = set() for el in candidates: id_ = id(el) if id_ not in seen: seen.add(id_) if is_navigation_bar(el): unique_candidates.append(el) return unique_candidates # ✅ 主程序入口 nav_bars = find_all_navigation_bars(driver) print(f"共识别出 {len(nav_bars)} 个导航栏") for i, nav in enumerate(nav_bars): try: tag = nav.tag_name class_name = nav.get_attribute('class') print(f"导航栏 #{i+1}: <{tag} class='{class_name}'>") except Exception as e: print(f"导航栏 #{i+1}: 无法获取信息", e) driver.quit()
最新发布
08-23
优化这段代码 import parsel import requests from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Firefox() driver.get('https://www.amazon.de/') word = input('请输入你需要的关键词:') driver.find_element(by=By.NAME, value="field-keywords").send_keys(word) sleep(5) driver.find_element(By.XPATH, "//input[@type='submit']").click() # 利用相对路径+属性值 driver.find_element(By.ID, "nav-search-submit-button").click() url = 'https://www.amazon.de/s?k={}'.format(word) headers = { 'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0', 'Referer': 'https://www.amazon.de/' } res = requests.get(url=url, headers=headers) html_data = res.text for links in driver.find_elements(By.XPATH, '//*[@class="a-link-normal s-underline-text s-underline-link-text s-link-style ' 'a-text-normal"]'): time.sleep(1) print(links.get_attribute('href')) a = [] for links in driver.find_elements(By.XPATH, '//*[@class="a-link-normal s-underline-text s-underline-link-text s-link-style ' 'a-text-normal"]'): time.sleep(1) print(links.get_attribute('href')) a.append(links.get_attribute('href')) driver.find_element(By.XPATH, '//*[@class="a-link-normal s-underline-text s-underline-link-text s-link-style ' 'a-text-normal"]').click() driver.find_element(By.ID, "sellerProfileTriggerId").click() box = driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/div/div/div/div/div[9]/div/div/div").text print(box) driver.back() driver.back() driver.refresh() for i in adriver.find_element(By.XPATH, '//*[@class="a-link-normal s-underline-text s-underline-link-text s-link-style ' 'a-text-normal"]').click(): print(i)
04-21
from selenium import webdriver from selenium.webdriver.common.by import By import time #WebDriver对象常用的属性和方法 #close() 关闭选项卡 #quit() 退出浏览器 #edge.set_window_size(width,height) 设置浏览器的大小 #maximize_window() 最大化窗口 #minimize_window() 最小化窗口 #back() 后退 #forward() 前进 #refresh() 刷新页面 #get_screenshot_as_file(filename) 把当前窗口截图并保存到filename #page_source 得到渲染后的页面代码(与开发者工具中元素选项卡下的内容一样 #find_element(by,value) 得到一个WebElement对象 # by选择元素的方法 by=By. # By.CLASS_NAME class类名 # By.ID id属性 # By.LINK_TEXT 链接文本 # By.TAG_NAME 标签名 # By.XPATH xpath路径 # By.CSS_SELECTOR css选择器 # By.PARTIAL_LINK_TEXT 部分链接文本 # By.NAME 名称 # value值 #find_elements(by,value) 参数含义find_element,得到的结果是list对象,其元素是WebElement对象 #window_handles 当前浏览器的选项卡句柄 #switch_to.window() 切换到哪个句柄窗口 #WebElement对象的常用属性和方法 #find_element,find_elements 同上 #clear() 清空输入框、文本域中的内容 #tag_name 标签的名称 #click() 模拟鼠标单击操作 #text 元素的文本内容 #get_attribute(name) 获取元素name属性的值 #size 元素的大小 #screenshot(filename) 对元素进行截图并保存 #js = "window.open('about:blank')" #el = edge.find_element(by=By.ID,value='newBook') # els #=edge.find_elements(by=By.XPATH,value='//*[@id="newBook"]/div/div[3]//a') # el= els[0] # el.screenshot('./spider/el.png') #edge.refresh() #获取人民邮电出版社新书推荐下电子栏目中书的 书名、作者、价格 edge = webdriver.Edge() url = 'https://www.ptpress.com.cn/' edge.get(url) edge.maximize_window() el = edge.find_element(by=By.XPATH,value='//div[@id="newBook"]/div/div[2]/span') print(el.text) el.click() time.sleep(2) books = [] #用来保存结果的 booka = edge.find_elements(by=By.XPATH,value='//*[@id="newBook"]/div/div[3]//a') for a in booka: book = {} a.click() whs = edge.window_handles #获取当前浏览器选项卡 edge.switch_to.window(whs[-1]) #切换到新的选项卡 time.sleep(8) #等待数据加载 book['name'] = edge.find_element(by=By.CLASS_NAME,value="book-name").text book['price'] = edge.find_element(by=By.CLASS_NAME,value='price').text book['author'] = edge.find_element(by=By.CLASS_NAME,value='book-author').text books.append(book) edge.close() edge.switch_to.window(whs[0]) print(books) #作业:获取两个类别的新书推荐书籍信息:书名、作者、价格,ISBN input()
05-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值