软件测试/测试开发丨用户端Web自动化测试学习笔记

点此获取更多相关资料

本文为霍格沃兹测试开发学社学员学习笔记分享
原文链接:https://ceshiren.com/t/topic/24826

一、SeleniumIDE用例录制

1、SeleniumIDE的下载以及安装

  1. 官网:https://www.selenium.dev/
  2. Chrome插件:https://chrome.google.com/webstore/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd
  3. Firefox插件:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/
  4. github release:https://github.com/SeleniumHQ/selenium-ide/releases
  5. 其它版本:https://addons.mozilla.org/en-GB/firefox/addon/selenium-ide/versions/
  • 注意:Chrome插件在国内无法下载,Firefox可以直接下载。

2、启动

  1. 安装完成后,通过在浏览器的菜单栏中点击它的图标来启动它:
  2. 如果没看到图标,首先确保是否安装了Selenium IDE扩展插件
  3. 通过以下链接访问所有插件
  • Chrome: chrome://extensions
  • Firefox: about:addons

3、SeleniumIDE常用功能

  1. 新建、保存、打开
  2. 开始和停止录制
  3. 运行8中的所有的实例
  4. 运行单个实例
  5. 调试模式
  6. 调整案例的运行速度
  7. 要录制的网址
  8. 实例列表
  9. 动作、目标、值
  10. 对单条命令的解释
  11. 运行日志

软件测试/测试开发丨用户端Web自动化测试学习笔记_第1张图片

4、SeleniumIDE脚本导出:Java和Python

软件测试/测试开发丨用户端Web自动化测试学习笔记_第2张图片

软件测试/测试开发丨用户端Web自动化测试学习笔记_第3张图片

二、自动化测试用例结构分析

1、标准的用例结构(功能)

  1. 用例标题
  2. 前提条件
  3. 用例步骤
  4. 预期结果
  5. 实际结果

2、自动化用例结构及作用

【结构:自动化测试用例:作用】

  1. 用例标题:测试包、文件、类、方法名称:【用例的唯一标识】
  2. 前提条件:setup、setup_class(Pytest;BeforeEach、BeforeAll(JUnit):【测试用例前的准备动作,比如读取数据或者driver的初始化】
  3. 用例步骤:测试方法内的代码逻辑:【测试用例具体的步骤行为】
  4. 预期结果:assert 实际结果 = 预期结果:【断言,印证用例是否执行成功】
  5. 实际结果:assert 实际结果 = 预期结果:【断言,印证用例是否执行成功】
  6. 后置动作:teardown、teardown_class(Pytest);@AfterEach、@AfterAll(JUnit):【脏数据清理、关闭driver进程】

3、IDE录制脚本

  1. 脚本步骤:
  • 访问百度网站
  • 搜索框输入“霍格沃兹测试开发”
  • 点击搜索按钮
# Generated by Selenium IDE
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class Test():
  def setup_method(self, method):
    self.driver = webdriver.Chrome()
    self.vars = {}
  
  def teardown_method(self, method):
    self.driver.quit()
  
  def test_sougou(self):
    # 打开网页,设置窗口
    self.driver.get("https://www.sogou.com/")
    self.driver.set_window_size(1235, 693)
    # 输入搜索信息
    self.driver.find_element(By.ID, "query").click()
    self.driver.find_element(By.ID, "query").send_keys("霍格沃兹测试开发")
    # 点击搜索
    self.driver.find_element(By.ID, "stb").click()
    element = self.driver.find_element(By.ID, "stb")
    actions = ActionChains(self.driver)
    actions.move_to_element(element).perform()
#优化后的代码,添加断言判断用例是否成功
# Generated by Selenium IDE
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities


class Test(object):
    # 前提条件,webdriver的初始化
    def setup_method(self, method):
        self.driver = webdriver.Chrome()
        self.vars = {}

    # 后置操作,关闭网站
    def teardown_method(self, method):
        self.driver.quit()

    # 测试用例步骤
    def test_sougou(self):
        # 打开网页,设置窗口
        self.driver.get("https://www.sogou.com/")
        self.driver.set_window_size(1235, 693)
        # 输入搜索信息
        self.driver.find_element(By.ID, "query").click()
        self.driver.find_element(By.ID, "query").send_keys("霍格沃兹测试开发")
        # 点击搜索
        self.driver.find_element(By.ID, "stb").click()
        element = self.driver.find_element(By.ID, "stb")
        actions = ActionChains(self.driver)
        actions.move_to_element(element).perform()
        # 问题:无法确定用例执行成功或失败
        # 解决方案:添加断言信息,判断搜索列表中,是否会有"霍格沃兹测试开发"
        res_element = self.driver.find_element(By.CSS_SELECTOR, "#sogou_vr_30000000_0 > em")
        # 获取到定位的文本信息
        # 判断实际获取到的搜索展示的列表和预期是否一致
        assert res_element.text == "霍格沃兹测试开发"

三、web 浏览器控制

  • 模拟功能测试中对浏览器的操作
操作 使用场景
get 打开浏览器 web自动化测试第一步
refresh 浏览器刷新 模拟浏览器刷新
back 浏览器退回 模拟退回步骤
maximize_window 最大化浏览器 模拟浏览器最大化
minimize_window 最小化浏览器 模拟浏览器最小化
import time
from selenium import webdriver
# 打开网页
def open_browser():
    # 实例化chromedriver
    driver = webdriver.Chrome()
    # 调用get方法时需要传递浏览器的URL
    driver.get("https://ceshiren.com/")
    # 添加等待1秒
    time.sleep(2)
    # # 刷新浏览器
    # driver.refresh()
    # # 通过get跳转到百度
    # driver.get("https://www.baidu.com/")
    # # 回退操作,退回到测试人网页
    # driver.back()
    # 最大化浏览器
    driver.maximize_window()
    time.sleep(2)
    # 最小化浏览器
    driver.minimize_window()
    time.sleep(2)

if __name__ == '__main__':
    open_browser()

四、常见控件定位方法

1、HTML铺垫

  1. 标签:尖括号,如括起来的</code>等</li> <li>属性:a=b,如href</li> <li>类属性: class</li> </ol> <pre><code class="prism language-html"><span class="token doctype"><span class="token punctuation"><!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>utf-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>title</span><span class="token punctuation">></span></span>测试人论坛<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://ceshiren.com/<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>link<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>链接<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>html</span><span class="token punctuation">></span></span> </code></pre> <h4>2、Selenium八大定位方式</h4> <ol> <li>selenium 常用定位方式</li> </ol> <ul> <li>格式:</li> </ul> <p><code>driver.find_element_by_定位方式(定位元素)</code></p> <p><code>driver.find_element(By.定位方式, 定位元素)</code></p> <ul> <li>示例,两种方式作用一模一样</li> <li>官方建议使用下面的方式</li> </ul> <p><code>driver.find_element_by_id("su")</code></p> <p><code>driver.find_element(By.ID, "su")</code></p> <table> <thead> <tr> <th>方式</th> <th>描述</th> </tr> </thead> <tbody> <tr> <td>class name</td> <td>class 属性对应的值</td> </tr> <tr> <td>css selector(重点)</td> <td>css 表达式</td> </tr> <tr> <td>id(重点)</td> <td>id 属性对应的值</td> </tr> <tr> <td>name(重点)</td> <td>name 属性对应的值</td> </tr> <tr> <td>link text</td> <td>查找其可见文本与搜索值匹配的锚元素</td> </tr> <tr> <td>partial link text</td> <td>查找其可见文本包含搜索值的锚元素。如果多个元素匹配,则只会选择第一个元素。</td> </tr> <tr> <td>tag name</td> <td>标签名称</td> </tr> <tr> <td>xpath(重点)</td> <td>xpath表达式</td> </tr> </tbody> </table> <ol start="2"> <li>【方式:描述】</li> </ol> <ul> <li>class name:class 属性对应的值</li> <li>css selector(重点):css 表达式 <ul> <li>格式: <code>driver.find_element(By.CSS_SELECTOR, "css表达式")</code></li> <li>复制绝对定位</li> <li>编写 css selector 表达式</li> </ul> </li> <li>id(重点):id 属性对应的值 <ul> <li>格式: <code>driver.find_element(By.ID, "ID属性对应的值")</code></li> </ul> </li> <li>name(重点):name 属性对应的值 <ul> <li>格式: <code>driver.find_element(By.NAME, "Name属性对应的值")</code></li> </ul> </li> <li>link text:查找其可见文本与搜索值匹配的锚元素 <ul> <li>格式:<code>driver.find_element(By.LINK_TEXT,"文本信息")</code></li> </ul> </li> <li>partial link text:查找其可见文本包含搜索值的锚元素。如果多个元素匹配,则只会选择第一个元素。</li> <li>tag name:标签名称</li> <li>xpath(重点):xpath表达式 <ul> <li>格式: <code>driver.find_element(By.XPATH, "xpath表达式")</code></li> <li>复制绝对定位</li> <li>编写 xpath 表达式</li> </ul> </li> </ul> <p><a href="http://img.e-com-net.com/image/info8/76a3f4f1d36246789955a190c7f9a9ca.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/76a3f4f1d36246789955a190c7f9a9ca.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第4张图片" width="650" height="407" style="border:1px solid black;"></a></p> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">def</span> <span class="token function">web_locate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 首先需要实例化driver对象,Chrome一定要加括号</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 打开一个网页</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/frame"</span><span class="token punctuation">)</span> <span class="token comment"># 1.ID定位,第一个参数传递定位方式,第二个参数传递定位元素,调用这个方法的返回值为WebElement</span> web_element <span class="token operator">=</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"locate_id"</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span>web_element<span class="token punctuation">)</span> <span class="token comment"># 2.NAME定位,如果没有报错,证明元素找到了</span> <span class="token comment"># 如果报错no such element,代表元素定位可能出现错误</span> <span class="token comment"># driver.find_element(By.NAME, "locate123") # 错误示例</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>NAME<span class="token punctuation">,</span> <span class="token string">"locate"</span><span class="token punctuation">)</span> <span class="token comment"># 3.CSS选择器定位</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"#locate_id > a > span"</span><span class="token punctuation">)</span> <span class="token comment"># 4.xpath表达式定位</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">'//*[@id="locate_id"]/a/span'</span><span class="token punctuation">)</span> <span class="token comment"># 表达式里有双引号,建议用单引号</span> <span class="token comment"># 5.Link text,通过链接文本的方式,(1)元素一定是a标签;(2)输入的元素为标签内的文本</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>LINK_TEXT<span class="token punctuation">,</span> <span class="token string">"元素定位"</span><span class="token punctuation">)</span> <span class="token comment"># 通常会带一个点击的操作,在最后面添加.click(),可加可不加</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> web_locate<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h2>五、强制等待与隐式等待</h2> <h4>1、为什么要添加等待</h4> <p>避免页面未渲染完成后操作,导致的报错</p> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">def</span> <span class="token function">wait_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 如果直接执行,不添加任何等待,可能会报错 """</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 不加等待,可能会因为网速等原因产生报错</span> <span class="token comment"># 报错:no such element: Unable to locate element</span> <span class="token comment"># 原因:页面未加载完成,就去查找元素,此时这个元素还未加载出来</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='个人中心']"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> wait_sleep<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>2、强制(直接)等待</h4> <ol> <li>解决方案:在报错的元素操作之前添加等待</li> <li>原理:强制等待,线程休眠一定时间。time.sleep(3)</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support <span class="token keyword">import</span> expected_conditions <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token keyword">def</span> <span class="token function">wait_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 如果直接执行,不添加任何等待,可能会报错 """</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 不加等待,可能会因为网速等原因产生报错</span> <span class="token comment"># 报错:no such element: Unable to locate element</span> <span class="token comment"># 原因:页面未加载完成,就去查找元素,此时这个元素还未加载出来</span> <span class="token comment"># 1.强制等待,让页面渲染完成,在报错的元素操作之前添加等待,没有报错,就证明是页面渲染速度导致,有报错则是其他问题,如定位错误等</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='个人中心']"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> wait_sleep<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>3、隐式等待</h4> <ol> <li>问题:难以确定元素加载的具体等待时间。</li> <li>解决方案:针对于寻找元素的这个动作,使用隐式等待添加配置。</li> <li>原理:设置一个等待时间,轮询查找(默认0.5秒)元素是否出现,如果没出现就抛出异常</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support <span class="token keyword">import</span> expected_conditions <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token keyword">def</span> <span class="token function">wait_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 如果直接执行,不添加任何等待,可能会报错 """</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 不加等待,可能会因为网速等原因产生报错</span> <span class="token comment"># 报错:no such element: Unable to locate element</span> <span class="token comment"># 原因:页面未加载完成,就去查找元素,此时这个元素还未加载出来</span> <span class="token comment"># 1.强制等待,让页面渲染完成,在报错的元素操作之前添加等待,没有报错,就证明是页面渲染速度导致,有报错则是其他问题,如定位错误等</span> <span class="token comment"># time.sleep(3)</span> <span class="token comment"># 强制等待的问题:(1)不确定页面加载时间,可能会因为等待时间过长,而影响用例的执行效率;(2)不确定页面加载时间,可能会因为等待时间过短,而导致代码依然报错</span> <span class="token comment"># 2.隐式等待</span> <span class="token comment"># 设置一个最长的等待时间,轮询查找(默认0.5秒)元素是否出现,如果没出现就抛出异常</span> <span class="token comment"># 注意:(1)在代码一开始运行时就添加隐式等待的配置,隐式等待是全局生效,即在所有find_element动作之前添加该配置即可;(2)隐式等待只能解决元素查找问题,不能解决元素交互问题</span> driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='个人中心']"</span><span class="token punctuation">)</span> <span class="token comment"># driver.implicitly_wait(5) # 修改隐式等待的配置</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='题库']"</span><span class="token punctuation">)</span> </code></pre> <h4>4、隐式等待无法解决的问题</h4> <ol> <li>问题:元素可以找到,使用点击等操作,出现报错</li> <li>原因:</li> </ol> <ul> <li>页面元素加载是异步加载过程,通常html会先加载完成,js、css其后</li> <li>元素存在与否是由HTML决定,元素的交互是由css或者js决定</li> <li>隐式等待只关注元素能不能找到,不关注元素能否点击或者进行其他的交互</li> </ul> <ol start="3"> <li>解决方案:使用显式等待</li> </ol> <h4>5、显式等待基本使用(初级)</h4> <ol> <li>示例: <code>WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)</code></li> <li>原理:在最长等待时间内,轮询,是否满足结束条件</li> </ol> <ul> <li>在初级时期,先关注使用</li> </ul> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support <span class="token keyword">import</span> expected_conditions <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token triple-quoted-string string">"""显示等待"""</span> <span class="token keyword">def</span> <span class="token function">wait_show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/frame"</span><span class="token punctuation">)</span> <span class="token comment"># driver.implicitly_wait(3) # 问题:元素可以找到,但是点击效果没有触发</span> <span class="token comment"># 显示等待,第一个参数是driver,第二个参数是最长等待时间,轮询时间可加可不加,util方法内需要结合expected_conditions或者自己封装的方法进行使用</span> <span class="token comment"># expected_conditions的参数传入都是一个元组,即多一层小括号</span> WebDriverWait<span class="token punctuation">(</span>driver<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">.</span>until<span class="token punctuation">(</span>expected_conditions<span class="token punctuation">.</span>element_to_be_clickable<span class="token punctuation">(</span><span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"success_btn"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"success_btn"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 添加点击操作.click(),点击"消息提示"</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> wait_show<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>6、总结</h4> <ol> <li>直接等待:</li> </ol> <ul> <li>使用方式:<code>time.sleep(等待时间))</code></li> <li>原理:强制线程等待</li> <li>适用场景:调试代码,临时性添加</li> </ul> <ol start="2"> <li>隐式等待:</li> </ol> <ul> <li>使用方式:<code>driver.implicitly_wait(等待时间)</code></li> <li>原理:在时间范围内,轮询查找元素</li> <li>适用场景:解决找不到元素问题,无法解决交互问题</li> </ul> <ol start="3"> <li>显式等待:</li> </ol> <ul> <li>使用方式:<code>WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)</code></li> <li>原理:设定特定的等待条件,轮询操作</li> <li>适用场景:解决特定条件下的等待问题,比如点击等交互性行为</li> </ul> <h2>六、常见控件交互方法</h2> <h4>1、元素操作</h4> <p>点击,输入,清空</p> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">def</span> <span class="token function">element_interaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 元素操作:点击、输入、清空 :return: """</span> <span class="token comment"># 1.实例化driver对象</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 2.打开一个网页</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 3.定位到输入框进行输入操作,.send_keys()</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"霍格沃滋测试开发"</span><span class="token punctuation">)</span> <span class="token comment"># 强制等待2秒</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 4.对输入框进行清空操作.clear()</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>clear<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 5.再次输入</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"霍格沃滋测试开发学社"</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 6.点击搜索.click()</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"stb"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> element_interaction<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>2、获取元素属性信息</h4> <ol> <li>原因:定位到元素后,获取元素的文本信息,属性信息等</li> <li>目的:根据这些信息进行断言或者调试</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token comment"># 获取元素属性</span> <span class="token keyword">def</span> <span class="token function">element_get_attr</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 1.实例化driver对象</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 2.打开网页</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/iframe"</span><span class="token punctuation">)</span> <span class="token comment"># 3.定位一个元素</span> web_element <span class="token operator">=</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"locate_id"</span><span class="token punctuation">)</span> <span class="token comment"># 4.打印这个元素信息</span> <span class="token comment"># 使用debug方式查看,断点打在想看的对象的下一行</span> <span class="token comment"># print(web_element)</span> <span class="token comment"># 5.获取元素的文本信息,不是每个元素都有文本信息的</span> <span class="token keyword">print</span><span class="token punctuation">(</span>web_element<span class="token punctuation">.</span>text<span class="token punctuation">)</span> <span class="token comment"># 6.获取元素的属性信息,如 id="locate_id", title="xxx"</span> res <span class="token operator">=</span> web_element<span class="token punctuation">.</span>get_attribute<span class="token punctuation">(</span><span class="token string">"class"</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> <span class="token comment"># 获取元素属性</span> element_get_attr<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/a5c7161ddd1246b1be5af067eff2d7ed.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a5c7161ddd1246b1be5af067eff2d7ed.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第5张图片" width="650" height="348" style="border:1px solid black;"></a></p> <h4>3、获取元素属性信息的方法</h4> <ol> <li>获取元素文本</li> <li>获取元素的属性(html的属性值)</li> </ol> <pre><code class="prism language-python"><span class="token comment"># 获取元素文本</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>text <span class="token comment"># 获取这个元素的name属性的值</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>get_attribute<span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span> </code></pre> <h2>七、自动化测试定位策略</h2> <h4>1、定位方式</h4> <p><a href="http://img.e-com-net.com/image/info8/53835cc63570455e9ee6b7afd1299ddf.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/53835cc63570455e9ee6b7afd1299ddf.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第6张图片" width="650" height="567" style="border:1px solid black;"></a></p> <h4>2、通用 Web 定位方式</h4> <table> <thead> <tr> <th>定位策略</th> <th>描述</th> </tr> </thead> <tbody> <tr> <td>class name</td> <td>通过 class 属性定位元素</td> </tr> <tr> <td>css selector</td> <td>通过匹配 css selector 定位元素</td> </tr> <tr> <td>id</td> <td>通过 id 属性匹配元素</td> </tr> <tr> <td>name</td> <td>通过 name 属性定位元素</td> </tr> <tr> <td>link text</td> <td>通过 text 标签中间的 text 文本定位元素</td> </tr> <tr> <td>partial link text</td> <td>通过 text 标签中间的 text 文本的部分内容定位元素</td> </tr> <tr> <td>tag name</td> <td>通过 tag 名称定位元素</td> </tr> <tr> <td>xpath</td> <td>通过 xpath 表达式匹配元素</td> </tr> </tbody> </table> <h4>3、选择定位器通用原则</h4> <ol> <li>与研发约定的属性优先(class属性: <code>[name='locate']</code>)</li> <li>身份属性 id,name(web 定位)</li> <li>复杂场景使用组合定位:</li> </ol> <ul> <li>xpath,css</li> <li>属性动态变化(id,text)</li> <li>重复元素属性(id,text,class)</li> <li>父子定位(子定位父)</li> </ul> <ol start="4"> <li>js定位</li> </ol> <h4>4、Web 弹框定位</h4> <ol> <li>场景:web 页面 alert 弹框</li> <li>解决:web 需要使用 <code>driver.switchTo().alert()</code> 处理</li> </ol> <h4>5、下拉框/日期控件定位</h4> <ol> <li>场景:</li> </ol> <ul> <li><code><input></code>标签组合的下拉框无法定位</li> <li><code><input></code>标签组合的日期控件无法定位</li> </ul> <ol start="2"> <li>解决:面对这些元素,我们可以引入JS注入技术来解决问题。</li> </ol> <h4>6、文件上传定位</h4> <ol> <li>场景:input 标签文件上传</li> <li>解决:input 标签直接使用 send_keys()方法</li> </ol> <p><a href="http://img.e-com-net.com/image/info8/9473d35055224ded8195b5e6a2ba0abf.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/9473d35055224ded8195b5e6a2ba0abf.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第7张图片" width="650" height="420" style="border:1px solid black;"></a></p> <h4>L1实战–测试人论坛搜索功能自动化测试</h4> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestCeshiren01</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 前提条件:进入测试人论坛的搜索页面 :return: """</span> <span class="token comment"># 实例化driver对象</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待</span> <span class="token comment"># 打开被测地址</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/search?expanded=true"</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">teardown</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 每一次用例结束之后都会关闭chromedriver进程,也会关闭浏览器</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_search01</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 测试步骤:1.输入搜索关键词;2.点击搜索按钮 :return: """</span> <span class="token comment"># 定位搜索框,并输入搜索内容,如果是动态id,使用css</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"[placeholder=搜索]"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"appium"</span><span class="token punctuation">)</span> <span class="token comment"># 定位到搜索按钮,并点击搜索</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">".search-cta"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 断言=预期结果与实际结果对比的结果</span> <span class="token comment"># 定位实际结果,即为获取搜索结果列表的标题内容</span> web_element <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">".topic-title"</span><span class="token punctuation">)</span> <span class="token comment"># 获取文本类的实际结果断言,appium关键字是否在获取的实际结果文本之中</span> <span class="token keyword">assert</span> <span class="token string">"appium"</span> <span class="token keyword">in</span> web_element<span class="token punctuation">.</span>text </code></pre> <h2>八、高级定位-css</h2> <h4>1、css 选择器概念</h4> <ol> <li>css 选择器有自己的语法规则和表达式</li> <li>css 定位通常分为绝对定位和相对定位</li> <li>和Xpath一起常用于UI自动化测试中的元素定位</li> </ol> <h4>2、css 相对定位使用场景</h4> <ol> <li>支持web产品</li> <li>支持app端的webview</li> </ol> <h4>3、css 相对定位的优点</h4> <ol> <li>可维护性更强</li> <li>语法更加简洁</li> <li>解决各种复杂的定位场景</li> </ol> <h4>4、css 定位的调试方法</h4> <ol> <li>进入浏览器的console</li> <li>输入:<code>$("css表达式")</code>或者<code>$$("css表达式")</code>,如果表达式里有双引号,外面要单引号,如果表达式用的是单引号,外面就要用双引号,外双内单,外单内双</li> </ol> <h4>5、css基础语法</h4> <table> <thead> <tr> <th>类型</th> <th>表达式</th> </tr> </thead> <tbody> <tr> <td>标签</td> <td>标签名</td> </tr> <tr> <td>类</td> <td>. (表示class属性值)</td> </tr> <tr> <td>ID</td> <td># (表示id属性值)</td> </tr> <tr> <td>属性</td> <td>[属性名=‘属性值’]</td> </tr> </tbody> </table> <p>【类型:表达式】</p> <ol> <li>标签:标签名</li> </ol> <ul> <li><code>$("div")</code> 获取所有的div标签</li> </ul> <ol start="2"> <li>类:.表示为class属性值,如果类里面有多个值(单词),就不能直接复制,将空格改为.即可</li> </ol> <ul> <li><code>$(".logo-big")</code>等同于<code>$("[class='logo-big']")</code></li> </ul> <ol start="3"> <li>ID:#表示为id属性值</li> </ol> <ul> <li><code>$("#site-logo")</code>等同于<code>$("[id='site-logo']")</code></li> </ul> <ol start="4"> <li>属性:[属性名=‘属性值’]</li> </ol> <ul> <li><code>$("[alt='测试人社区']")</code></li> </ul> <p><a href="http://img.e-com-net.com/image/info8/c857e00e372346778a91eb63e303fa8d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c857e00e372346778a91eb63e303fa8d.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第8张图片" width="650" height="290" style="border:1px solid black;"></a></p> <h4>6、css关系定位</h4> <table> <thead> <tr> <th>类型</th> <th>格式</th> </tr> </thead> <tbody> <tr> <td>并集</td> <td>元素,元素</td> </tr> <tr> <td>邻近兄弟(了解即可)</td> <td>元素+元素</td> </tr> <tr> <td>兄弟(了解即可)</td> <td>元素1~元素2</td> </tr> <tr> <td>父子</td> <td>元素>元素</td> </tr> <tr> <td>后代</td> <td>元素 元素</td> </tr> </tbody> </table> <p>【类型:格式】</p> <ol> <li>并集:元素,元素<code>$("#main,#ember4")</code></li> </ol> <p><a href="http://img.e-com-net.com/image/info8/0b6d058a542445d9974292314902d63d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/0b6d058a542445d9974292314902d63d.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第9张图片" width="650" height="226" style="border:1px solid black;"></a></p> <p><a href="http://img.e-com-net.com/image/info8/1536a996e77f4e8fb4976dfe71bd4f40.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/1536a996e77f4e8fb4976dfe71bd4f40.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第10张图片" width="650" height="306" style="border:1px solid black;"></a></p> <ol start="2"> <li>邻近兄弟(了解即可):元素+元素<br> <code>$("#ember39+#ember40")</code></li> <li>兄弟(了解即可):元素1~元素2<br> <code>$("#ember39~#ember41")</code></li> <li>父子:元素>元素<br> <code>$("#main>#ember4")</code></li> <li>后代:元素 元素<br> <code>$("#main #skip-link")</code></li> </ol> <p><a href="http://img.e-com-net.com/image/info8/fb70e4ef460f42d29ceaec8338ed99b0.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/fb70e4ef460f42d29ceaec8338ed99b0.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第11张图片" width="650" height="230" style="border:1px solid black;"></a></p> <h4>7、css 顺序关系</h4> <table> <thead> <tr> <th>类型</th> <th>格式</th> </tr> </thead> <tbody> <tr> <td>父子关系+顺序</td> <td>元素 元素</td> </tr> <tr> <td>父子关系+标签类型+顺序</td> <td>元素 元素</td> </tr> </tbody> </table> <p>【类型:格式】</p> <ol> <li>父子关系+顺序:元素 元素(父亲有多个孩子,找到第一个孩子)<br> 表达式:<code>//:nth-child(n)</code><br> <code>$("#ember15>:nth-child(3)")</code> ( #ember15为父亲,:nth-child(3)为第三个孩子)</li> <li>父子关系+标签类型+顺序:元素 元素(父亲的孩子有多个类型,想找其中一个类型里面的第一个孩子)<br> 表达式:<code>//:nth-of-type(n)</code><br> <code>$("#ember15>div:nth-of-type(1)")</code>( #ember15为父亲,:nth-of-type(1)为第三个类型div的第一个孩子)</li> </ol> <p><a href="http://img.e-com-net.com/image/info8/9302b11ec31944f9a74fe2defb3535a6.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/9302b11ec31944f9a74fe2defb3535a6.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第12张图片" width="650" height="329" style="border:1px solid black;"></a></p> <p>css表达式定位</p> <p><a href="http://img.e-com-net.com/image/info8/95660b0556f04a4fb0c42ac3ab8c0ebd.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/95660b0556f04a4fb0c42ac3ab8c0ebd.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第13张图片" width="650" height="601" style="border:1px solid black;"></a></p> <h2>九、高级定位-xpath</h2> <h4>1、xpath 基本概念</h4> <ol> <li>XPath 是一门在 XML 文档中查找信息的语言</li> <li>XPath 使用路径表达式在 XML 文档中进行导航</li> <li>XPath 的应用非常广泛</li> <li>XPath 可以应用在UI自动化测试</li> </ol> <h4>2、xpath 使用场景</h4> <ol> <li>web自动化测试</li> <li>app自动化测试</li> </ol> <h4>3、xpath 相对定位的优点</h4> <ol> <li>可维护性更强</li> <li>语法更加简洁</li> <li>相比于css可以支持更多的方式</li> </ol> <h4>4、xpath 定位的调试方法</h4> <ol> <li>浏览器-console</li> </ol> <ul> <li>$x(“xpath表达式”)</li> </ul> <ol start="2"> <li>浏览器-elements</li> </ol> <ul> <li>ctrl+f 输入xpath或者css</li> </ul> <h4>5、xpath 基础语法(包含关系)</h4> <table> <thead> <tr> <th>表达式</th> <th>结果</th> </tr> </thead> <tbody> <tr> <td>/</td> <td>从该节点的子元素选取</td> </tr> <tr> <td>//</td> <td>从该节点的子孙元素选取</td> </tr> <tr> <td>*</td> <td>通配符</td> </tr> <tr> <td>nodename</td> <td>选取此节点的所有子节点</td> </tr> <tr> <td>…</td> <td>选取当前节点的父节点</td> </tr> <tr> <td>@</td> <td>选取属性</td> </tr> </tbody> </table> <p>【表达式:结果】</p> <ol> <li>/ :从该节点的子元素选取</li> <li>// :从该节点的子孙元素选取</li> <li> <ul> <li>:通配符<br> <code>$x("//*[@id='ember61']")</code>,匹配所有的[@id=‘ember61’]<br> <code>$x("//tr[@id='ember61']")</code>,匹配tr标签下面的[@id=‘ember61’]</li> </ul> </li> <li><code>nodename</code> :选取此节点的所有子节点,相当于标签名</li> <li><code>.. </code>:选取当前节点的父节点,<br> 如<code>$x("//*[@id='ember61']/..")</code>,寻找ember61的父节点</li> </ol> <p>写法二:<code>$x("//tr[@id='ember61']")</code>,在某个标签下寻找</p> <ol start="6"> <li> <p><code>@ </code>:选取属性</p> </li> <li> <p>整个页面<br> <code>$x("/")</code></p> </li> </ol> <p><a href="http://img.e-com-net.com/image/info8/9f44ce15d26e4d76a3c4bf37f14f19aa.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/9f44ce15d26e4d76a3c4bf37f14f19aa.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第14张图片" width="650" height="707" style="border:1px solid black;"></a></p> <p>页面中的所有的子元素,匹配/下面的所有节点,相当于是html<br> <code>$x("/*")</code></p> <p><a href="http://img.e-com-net.com/image/info8/3909a9577c7f4dc0abd3852e1eff71da.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/3909a9577c7f4dc0abd3852e1eff71da.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第15张图片" width="650" height="503" style="border:1px solid black;"></a></p> <p>整个页面中的所有元素<br> <code>$x("//*")</code></p> <p><a href="http://img.e-com-net.com/image/info8/23867e8cd1f5436c8d24ec2f4edfd8b0.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/23867e8cd1f5436c8d24ec2f4edfd8b0.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第16张图片" width="650" height="624" style="border:1px solid black;"></a></p> <p>查找页面上面所有的div标签节点,标签不等于属性<br> <code>$x("//div")</code></p> <p><a href="http://img.e-com-net.com/image/info8/ec58527e0f8542828c74f2bfb3a9bfb8.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/ec58527e0f8542828c74f2bfb3a9bfb8.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第17张图片" width="650" height="681" style="border:1px solid black;"></a></p> <p>查找id属性为ember61的节点,*先匹配所有节点,再匹配某个属性<br> <code>$x('//*[@id="ember61"]')</code></p> <p><a href="http://img.e-com-net.com/image/info8/62e2ba52d531455eae4fb31f44043208.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/62e2ba52d531455eae4fb31f44043208.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第18张图片" width="650" height="219" style="border:1px solid black;"></a></p> <p>查找ember61节点的父节点</p> <p><code>$x('//*[@id="ember61"]/..')</code></p> <p><code>$x("//*[@id='ember61']/../..")</code> 再往上寻找父节点</p> <h4>6、xpath 顺序关系(索引)</h4> <pre><code class="prism language-python">xpath通过索引直接获取对应元素 <span class="token comment"># 查找tbody下的所有tr</span> $x<span class="token punctuation">(</span><span class="token string">"//tbody//tr"</span><span class="token punctuation">)</span> <span class="token comment"># 查找tbody下的第一个tr,下标从1开始</span> $x<span class="token punctuation">(</span><span class="token string">"//tbody//tr[1]"</span><span class="token punctuation">)</span> <span class="token comment"># 获取所有的tr,注意这里的tr并不是都是同一个父节点</span> $x<span class="token punctuation">(</span><span class="token string">"//tr"</span><span class="token punctuation">)</span> <span class="token comment"># 获取每个不同父节点下面的第一个tr</span> $x<span class="token punctuation">(</span><span class="token string">"//tr[1]"</span><span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/0cd27b7ce4644239a0ad12af5b83c34c.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/0cd27b7ce4644239a0ad12af5b83c34c.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第19张图片" width="650" height="258" style="border:1px solid black;"></a></p> <h4>7、xpath 高级用法</h4> <pre><code>①[last()]: 选取最后一个 $x("//tr[last()]") # 获取每一个父节点下的最后一个tr $x("//tbody//tr[last()]") # 获取tbody下面的最后一个tr ②[@属性名='属性值' and @属性名='属性值']: 与关系 $x("//*[@class='topic-list-item category-bu-161-category unseen-topic ember-view' and @id='ember44']") ③[@属性名='属性值' or @属性名='属性值']: 或关系 $x("//*[@class='topic-list-item category-bu-161-category unseen-topic ember-view' or @id='ember44']") ④[text()='文本信息']: 根据文本信息定位 $x("//*[text()='赏金任务']") # text不是属性,不需要加@,是一个方法,加括号 ⑤[contains(text(),'文本信息')]: 根据文本信息包含定位;也可以contains(@id或@name等) $x("//*[contains(text(),'赏金')]") $x("//*[contains(@id,'site')]") ⑥注意:所有的表达式需要和[]结合 </code></pre> <h2>十、显式等待高级使用</h2> <h4>1、显式等待原理</h4> <ol> <li>在代码中定义等待一定条件发生后再进一步执行代码</li> <li>在最长等待时间内循环执行结束条件的函数,结合③一起查看</li> <li>源码:<code>WebDriverWait(driver 实例, 最长等待时间, 轮询时间).until(结束条件函数)</code></li> </ol> <h4>2、常见 expected_conditions</h4> <table> <thead> <tr> <th>类型</th> <th>示例方法</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>element</td> <td>element_to_be_clickable();visibility_of_element_located()</td> <td>针对于元素,比如判断元素是否可以点击,或者元素是否可见</td> </tr> <tr> <td>url</td> <td>url_contains()</td> <td>针对于 url</td> </tr> <tr> <td>title</td> <td>title_is()</td> <td>针对于标题</td> </tr> <tr> <td>frame</td> <td>frame_to_be_available_and_switch_to_it(locator)</td> <td>针对于 frame</td> </tr> <tr> <td>alert</td> <td>alert_is_present()</td> <td>针对于弹窗</td> </tr> </tbody> </table> <h4>3、封装等待条件</h4> <ol> <li>官方的 excepted_conditions 不可能覆盖所有场景,如有些按钮需要点击两次或多次才会有反应</li> <li>定制封装条件会更加灵活、可控</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>remote<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> WebDriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token keyword">class</span> <span class="token class-name">TestWebdriverWait</span><span class="token punctuation">:</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>maximize_window<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/iframe"</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">teardown</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_webdriver_wait</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 解决的问题:有的按钮点击一次没有反应,可能要点击多次,比如企业微信的添加成员</span> <span class="token comment"># 解决的方案:一直点击按钮,直到下个页面出现,封装成显式等待的一个条件</span> <span class="token keyword">def</span> <span class="token function">muliti_click</span><span class="token punctuation">(</span>button_element<span class="token punctuation">,</span>until_ele<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 函数封装</span> <span class="token keyword">def</span> <span class="token function">inner</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 封装点击方法</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span>button_element<span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">return</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span>until_ele<span class="token punctuation">)</span> <span class="token keyword">return</span> inner time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># 在限制时间内会一直点击按钮,直到展示弹框</span> WebDriverWait<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">.</span>until<span class="token punctuation">(</span>muliti_click<span class="token punctuation">(</span><span class="token string">"//*[text()='点击两次响应']"</span><span class="token punctuation">,</span><span class="token string">"//*[text()='该弹框点击两次后才会弹出']"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> </code></pre> <h2>十一、高级控件交互方法</h2> <h4>1、使用场景</h4> <table> <thead> <tr> <th>使用场景</th> <th>对应事件</th> </tr> </thead> <tbody> <tr> <td>复制粘贴</td> <td>键盘事件</td> </tr> <tr> <td>拖动元素到某个位置</td> <td>鼠标事件</td> </tr> <tr> <td>鼠标悬停</td> <td>鼠标事件</td> </tr> <tr> <td>滚动到某个元素</td> <td>滚动事件</td> </tr> <tr> <td>使用触控笔点击</td> <td>触控笔事件(了解即可)</td> </tr> </tbody> </table> <h4>2、ActionChains解析</h4> <ol> <li>实例化类ActionChains,参数为driver实例。</li> <li>中间可以有多个操作。</li> <li>.perform()代表确定执行。</li> </ol> <h4>3、键盘事件</h4> <ol> <li>按下、释放键盘键位</li> <li>结合send_keys回车</li> <li>键盘事件-使用shift实现大写</li> </ol> <ul> <li><code>ActionChains(self.driver)</code>: 实例化ActionChains类</li> <li><code>key_down(Keys.SHIFT, ele)</code>: 按下shift键实现大写</li> <li><code>send_keys("selenium")</code>: 输入大写的selenium</li> <li><code>perform()</code>: 确认执行</li> </ul> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_shift</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 键盘事件-使用shift实现大写 1.访问https://ceshiren.com/官方网站 2.点击搜索按钮 3.输入搜索的内容,输入的同时按着shift键 :return: """</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索按钮</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-button"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 目标元素,即为输入框</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-term"</span><span class="token punctuation">)</span> <span class="token comment"># key_down代表按下某个键位,.send_keys输入内容,.perform()确认执行以上操作</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>SHIFT<span class="token punctuation">,</span> ele<span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"selenium"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <ol start="4"> <li>键盘事件-输入后回车</li> </ol> <ul> <li>直接输入回车: <code>元素.send_keys(Keys.ENTER)</code></li> <li>使用ActionChains: <code>key_down(Keys.ENTER)</code></li> </ul> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_enter</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""键盘事件-输入后回车"""</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"python语言"</span><span class="token punctuation">)</span> <span class="token comment"># 第一种回车方式,直接输入回车</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>ENTER<span class="token punctuation">)</span> <span class="token comment"># 第二种使用ActionChains,要记得加.perform()</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>ENTER<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <ol start="5"> <li>键盘事件-复制粘贴</li> </ol> <ul> <li>多系统兼容 <ul> <li>mac 的复制按钮为 COMMAND</li> <li>windows 的复制按钮为 CONTROL</li> </ul> </li> <li>左箭头:<code>Keys.ARROW_LEFT</code></li> <li>按下COMMAND或者CONTROL: <code>key_down(cmd_ctrl)</code></li> <li>按下剪切与粘贴按钮: <code>send_keys("xvvvvv")</code></li> </ul> <pre><code class="prism language-python"><span class="token keyword">import</span> sys <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_copy_and_paste</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""键盘事件-复制粘贴"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索按钮</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-button"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 目标元素,即为输入框</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-term"</span><span class="token punctuation">)</span> <span class="token comment"># 判断操作系统是否为Mac(darwin),是mac返回command键位,windows返回control键位</span> command_control <span class="token operator">=</span> Keys<span class="token punctuation">.</span>COMMAND <span class="token keyword">if</span> sys<span class="token punctuation">.</span>platform <span class="token operator">==</span> <span class="token string">"darwin"</span> <span class="token keyword">else</span> Keys<span class="token punctuation">.</span>CONTROL <span class="token comment"># .key_down(Keys.SHIFT, ele)按下shift键,.send_keys("selenium")输入大写selenium,</span> <span class="token comment"># .key_down(Keys.ARROW_LEFT)按下左箭头,.key_down(command_control)按下command或control键位,</span> <span class="token comment"># .send_keys("xvv"),x表示为剪切,多少个v表示复制多少次,.key_up(command_control)表示松开command或control键位,.perform()执行</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>SHIFT<span class="token punctuation">,</span> ele<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"selenium@"</span><span class="token punctuation">)</span>\ <span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>ARROW_LEFT<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>command_control<span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"xvvvvvv"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>key_up<span class="token punctuation">(</span>command_control<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>4、鼠标事件</h4> <ol> <li>双击<br> <code>double_click(元素对象)</code>: 双击元素</li> <li>拖动元素<br> <code>drag_and_drop(起始元素对象, 结束元素对象)</code>: 拖动并放开元素</li> <li>指定位置(悬浮)<br> <code>move_to_element(元素对象)</code>: 移动到某个元素</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_double_click</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""鼠标事件-双击"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/iframe"</span><span class="token punctuation">)</span> <span class="token comment"># 获取点击按钮</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"primary_btn"</span><span class="token punctuation">)</span> <span class="token comment"># .double_click(ele)调用双击方法,传入双击元素,.perform()执行</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>double_click<span class="token punctuation">(</span>ele<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_drag_and_drop</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""鼠标事件-拖动元素"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/action_chains"</span><span class="token punctuation">)</span> <span class="token comment"># 获取需要拖动的元素,即起始元素的位置</span> item_left <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#item1'</span><span class="token punctuation">)</span> <span class="token comment"># #表示id标签</span> <span class="token comment"># 获取目标元素的位置</span> item_right <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#item3'</span><span class="token punctuation">)</span> <span class="token comment"># #表示id标签</span> <span class="token comment"># 实现拖拽操作,.drag_and_drop(item_left, item_right)</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>drag_and_drop<span class="token punctuation">(</span>item_left<span class="token punctuation">,</span> item_right<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_hover</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""鼠标事件-悬浮"""</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/action_chains2"</span><span class="token punctuation">)</span> <span class="token comment"># 获取下拉框位置</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">".menu"</span><span class="token punctuation">)</span> <span class="token comment"># 鼠标悬浮在下拉框</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>move_to_element<span class="token punctuation">(</span>ele<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 选择下拉选项</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[contains(text(),'测开班')]"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> </code></pre> <h4>5、滚轮/滚动操作</h4> <ol> <li>滚动到元素<br> <code>scroll_to_element(WebElement对象)</code>:滚动到某个元素</li> <li>根据坐标滚动<br> <code>scroll_by_amount(横坐标, 纵坐标)</code></li> <li>注意: selenium 版本需要在 4.2 之后</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestScroll</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_scoll_to_element</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""滚轮/滚动操作-滚动到元素"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 获取页面底部某个标题</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='接口测试上线标准']"</span><span class="token punctuation">)</span> <span class="token comment"># 页面滚动操作,找到"接口测试上线标准",selenium版本需要在 4.2 之后</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>scroll_to_element<span class="token punctuation">(</span>ele<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_scroll_to_xy</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""滚轮/滚动操作-根据坐标滚动"""</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 坐标滚动方式,.scroll_by_amount(0, 10000)纵向滚动</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>scroll_by_amount<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> </code></pre> <h2>十二、网页 frame 与多窗口处理</h2> <h4>1、selenium⾥⾯如何处理多窗⼜场景</h4> <ol> <li>多个窗口识别</li> <li>多个窗口之间切换</li> </ol> <h4>2、selenium⾥⾯如何处理frame</h4> <ol> <li>多个frame识别</li> <li>多个frame之间切换</li> </ol> <h4>3、多窗口处理</h4> <ol> <li>点击某些链接,会重新打开⼀个窗口,对于这种情况,想在新页⾯上操作,就得先切换窗口了。</li> <li>获取窗口的唯⼀标识⽤句柄表⽰,所以只需要切换句柄,就可以在多个页⾯灵活操作了。</li> </ol> <h4>4、多窗口处理流程</h4> <ol> <li>先获取到当前的窗口句柄(driver.current_window_handle)</li> <li>再获取到所有的窗口句柄(driver.window_handles)</li> <li>判断是否是想要操作的窗口,如果是,就可以对窗口进⾏操作,如果不是,跳转到另外⼀个窗口,对另⼀个窗口进⾏操作 (driver.switch_to_window)</li> </ol> <pre><code class="prism language-python"><span class="token triple-quoted-string string">"""base.py文件,Base类有前置和后置操作"""</span> <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token comment"># 前置和后置操作,提供测试用例调用</span> <span class="token keyword">class</span> <span class="token class-name">Base</span><span class="token punctuation">(</span><span class="token builtin">object</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 前置操作</span> <span class="token keyword">def</span> <span class="token function">setup</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待</span> <span class="token comment"># 后置操作</span> <span class="token keyword">def</span> <span class="token function">teardown</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token triple-quoted-string string">"""测试用例文件test_window.py"""</span> <span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestWindows</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_window</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.baidu.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 找到登录按钮,并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[@id='s-top-loginbtn']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>current_window_handle<span class="token punctuation">)</span> <span class="token comment"># 点击登录之后,打印当前窗口</span> <span class="token comment"># 点击弹窗里的立即注册按钮</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='立即注册']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># # 点击立即注册之后,打印当前窗口</span> <span class="token comment"># print(self.driver.current_window_handle)</span> <span class="token comment"># # 打印所有窗口的名字,列表形式,会有注册页面的窗口,</span> <span class="token comment"># print(self.driver.window_handles)</span> <span class="token comment"># 获取所有窗口列表,赋给window</span> window <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>window_handles <span class="token comment"># window[-1]获取注册页面的窗口,并切换到注册页面的窗口</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>window<span class="token punctuation">(</span>window<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment"># 注册页面,输入用户名username</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_4__userName"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 切换回最初登录页面的窗口</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>window<span class="token punctuation">(</span>window<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment"># # 登录页面,点击短信登录</span> <span class="token comment"># self.driver.find_element(By.XPATH, "//*[text()='短信登录']").click()</span> <span class="token comment"># 获取用户名输入框,并输入用户名</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_11__userName"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"login_username"</span><span class="token punctuation">)</span> <span class="token comment"># 获取密码输入框,并输入密码</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_11__password"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"login_password"</span><span class="token punctuation">)</span> <span class="token comment"># 点击登录</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_11__submit"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span> </code></pre> <h4>5、frame处理</h4> <pre><code class="prism language-python"><span class="token number">1</span>)frame介绍 ①在web⾃动化中,如果⼀个元素定位不到,那么很⼤可能是在iframe中。 ②什么是frame? a<span class="token punctuation">.</span> frame是html中的框架,在html中,所谓的框架就是可以在同⼀个浏览器中显⽰不⽌⼀个页⾯。 b<span class="token punctuation">.</span> 基于html的框架,又分为垂直框架和⽔平框架(cols,rows) ③Frame 分类 a<span class="token punctuation">.</span> frame标签包含frameset、frame、iframe三种, b<span class="token punctuation">.</span> frameset和普通的标签⼀样,不会影响正常的定位,可以使⽤index、<span class="token builtin">id</span>、name 、webelement任意种⽅式定位frame。 c<span class="token punctuation">.</span> ⽽frame与iframe对selenium定位⽽⾔是⼀样的。selenium有⼀组⽅法对frame进⾏操作 <span class="token number">2</span>)多frame切换 ①frame存在两种:⼀种是嵌套的,⼀种是未嵌套的 ②切换frame ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 根据元素id或者index切换切换frame</span> ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>default_content<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 切换到默认frame</span> ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>parent_frame<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 切换到⽗级frame</span> <span class="token number">3</span>)frame未嵌套 ①处理未嵌套的iframe ❖ driver<span class="token punctuation">.</span>switch_to_frame<span class="token punctuation">(</span>“frame 的 <span class="token builtin">id</span>”<span class="token punctuation">)</span> ❖ driver<span class="token punctuation">.</span>switch_to_frame<span class="token punctuation">(</span>“frame <span class="token operator">-</span> index”<span class="token punctuation">)</span> frame⽆ID的时候依据索引来处理,索引从<span class="token number">0</span>开始 driver<span class="token punctuation">.</span>switch_to_frame<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token number">4</span>)frame嵌套 ②处理嵌套的iframe ❖ 对于嵌套的先进⼊到iframe的⽗节点,再进到⼦节点,然后可以对⼦节点⾥⾯的对象进⾏处理和操作 ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span>“⽗节点”<span class="token punctuation">)</span> ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span>“⼦节点”<span class="token punctuation">)</span> </code></pre> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestFrame</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_frame</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"</span><span class="token punctuation">)</span> <span class="token comment"># 切换到frame中,根据frame的元素id</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span><span class="token string">"iframeResult"</span><span class="token punctuation">)</span> <span class="token comment"># 写法一,常用</span> <span class="token comment"># self.driver.switch_to_frame("iframeResult") # 写法二</span> <span class="token comment"># 获取"请拖拽我!"的属性,获取文本内容</span> <span class="token keyword">print</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"draggable"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>text<span class="token punctuation">)</span> <span class="token comment"># 写法一:切回网页,即不在frame页面,即切回frame父节点</span> <span class="token comment"># self.driver.switch_to.parent_frame()</span> <span class="token comment"># 写法二:切换到默认frame节点,即刚打开的地址节点</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>default_content<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取"点击运行"按钮,并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"submitBTN"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/6056596c1b9b45e080f903c981ccd705.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/6056596c1b9b45e080f903c981ccd705.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第20张图片" width="650" height="426" style="border:1px solid black;"></a></p> <h2>十三、文件上传弹框处理</h2> <h4>1、⽂件上传</h4> <ol> <li>input标签可以直接使⽤send_keys(⽂件地址)上传⽂件</li> <li>⽤法: <ul> <li>el = driver.find_element_by_id(‘上传按钮id’)</li> <li>el.send_keys(”⽂件路径+⽂件名")</li> </ul> </li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestFile</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_file_upload</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.baidu.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 找到百度的相机图标并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[@class='soutu-btn']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 定位到选择文件,并选择文件</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//input[@class='upload-pic']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"/Users/jiyu/PycharmProjects/pythonProject/webui/img/12.png"</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> </code></pre> <h4>2、chrome 开启 debug 模式</h4> <ol> <li>有时候登录⽅式⽐较繁琐,需要动态⼿机密码,⼆维码登录之类的。⾃动话实现⽐较⿇烦。⼿⼯登录后,不想让selenium启动⼀个新浏览器。可以使⽤chrome的debug⽅式来执⾏测试。</li> <li>启动chrome的时候需要先退出所有chrome进程。使⽤ps aux|grep chrome|grep -v 'grep’查看是否有chrome进程存在。确保没有chrome进程被启动过。</li> <li>正常启动chrome的debug模式 <ul> <li> <h2>默认macOS系统</h2> </li> </ul> <code>/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debuggingport=9222</code> <ul> <li> <h2>Windows下找到chrome.exe位置执⾏下⾯的命令</h2> </li> </ul> <code>chrome.exe --remote-debugging-port=9222</code></li> <li>启动后的提⽰信息,代表chrome运⾏正常,不要关闭⾃动打开的chrome窗口。</li> </ol> <h4>3、弹框处理机制</h4> <ol> <li>在页⾯操作中有时会遇到JavaScript所⽣成的alert、confirm以及prompt弹框,可以使⽤<code>switch_to.alert()</code>⽅法定位到。然后使⽤text/accept/dismiss/send_keys等⽅法进⾏操作。</li> <li>操作alert常⽤的⽅法: <ul> <li><code>switch_to.alert()</code>:获取当前页⾯上的警告框。</li> <li><code>text</code>:返回alert/confirm/prompt 中的⽂字信息。</li> <li><code>accept()</code>:接受现有警告框。</li> <li><code>dismiss()</code>:解散现有警告框。</li> <li><code>send_keys(keysToSend)</code>:发送⽂本⾄警告框。keysToSend:将⽂本发送⾄警告框。</li> </ul> </li> </ol> <p><a href="http://img.e-com-net.com/image/info8/a364611445b44f03b71c021cb71e2fa9.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a364611445b44f03b71c021cb71e2fa9.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第21张图片" width="650" height="484" style="border:1px solid black;"></a></p> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token keyword">class</span> <span class="token class-name">TestAlert</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_alert</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" ❖ 打开⽹页 https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable ❖ 操作窗⼜右侧页⾯, 将元素1拖拽到元素2 ❖ 这时候会有⼀个alert弹框,点击弹框中的’确定’ ❖ 然后再按’点击运⾏’ ❖ 关闭⽹页 :return: """</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"</span><span class="token punctuation">)</span> <span class="token comment"># 切换到frame中,根据frame的元素id</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span><span class="token string">"iframeResult"</span><span class="token punctuation">)</span> <span class="token comment"># 获取需要拖动的元素,即起始元素的位置</span> a1 <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#draggable'</span><span class="token punctuation">)</span> <span class="token comment"># 获取目标元素的位置</span> a2 <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#droppable'</span><span class="token punctuation">)</span> <span class="token comment"># 实现拖拽操作,.drag_and_drop(a1, a2):将a1拖拽到a2上,.perform()执行</span> action <span class="token operator">=</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span> action<span class="token punctuation">.</span>drag_and_drop<span class="token punctuation">(</span>a1<span class="token punctuation">,</span> a2<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 强制等待2秒,查看效果</span> <span class="token comment"># 切换到alert页面,点击alert的确认按钮.accept()</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>alert<span class="token punctuation">.</span>accept<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 退出alert页面,返回到默认frame节点</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>default_content<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取"点击运行"按钮,并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">'submitBTN'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> </code></pre> <h2>十四、自动化关键数据记录</h2> <h4>1、什么是关键数据</h4> <ol> <li>代码的执行日志</li> <li>代码执行的截图</li> <li>page source(页面源代码)</li> </ol> <h4>2、记录关键数据的作用</h4> <table> <thead> <tr> <th>内容</th> <th>作用</th> </tr> </thead> <tbody> <tr> <td>日志</td> <td>1. 记录代码的执行记录,方便复现场景;2. 可以作为bug依据</td> </tr> <tr> <td>截图</td> <td>1. 断言失败或成功截图;2.异常截图达到丰富报告的作用;3. 可以作为bug依据</td> </tr> <tr> <td>page source</td> <td>1. 协助排查报错时元素当时是否存在页面上</td> </tr> </tbody> </table> <h4>3、行为日志记录</h4> <ol> <li>日志配置</li> <li>脚本日志级别 <ul> <li>debug记录步骤信息</li> <li>info记录关键信息,比如断言等</li> </ul> </li> </ol> <pre><code class="prism language-python"><span class="token comment">#日志配置文件log_utils.py</span> <span class="token comment"># 日志配置</span> <span class="token keyword">import</span> logging <span class="token comment"># 创建logger实例</span> logger <span class="token operator">=</span> logging<span class="token punctuation">.</span>getLogger<span class="token punctuation">(</span><span class="token string">'simple_example'</span><span class="token punctuation">)</span> <span class="token comment"># 设置日志级别</span> logger<span class="token punctuation">.</span>setLevel<span class="token punctuation">(</span>logging<span class="token punctuation">.</span>DEBUG<span class="token punctuation">)</span> <span class="token comment"># 流处理器</span> ch <span class="token operator">=</span> logging<span class="token punctuation">.</span>StreamHandler<span class="token punctuation">(</span><span class="token punctuation">)</span> ch<span class="token punctuation">.</span>setLevel<span class="token punctuation">(</span>logging<span class="token punctuation">.</span>DEBUG<span class="token punctuation">)</span> <span class="token comment"># 日志打印格式</span> formatter <span class="token operator">=</span> logging<span class="token punctuation">.</span>Formatter<span class="token punctuation">(</span><span class="token string">'%(asctime)s - %(name)s - %(levelname)s - %(message)s'</span><span class="token punctuation">)</span> <span class="token comment"># 添加格式配置</span> ch<span class="token punctuation">.</span>setFormatter<span class="token punctuation">(</span>formatter<span class="token punctuation">)</span> <span class="token comment"># 添加日志配置</span> logger<span class="token punctuation">.</span>addHandler<span class="token punctuation">(</span>ch<span class="token punctuation">)</span> </code></pre> <pre><code class="prism language-python"><span class="token comment"># 测试用例脚本文件test_data_record.py</span> <span class="token comment"># 日志与脚本结合</span> <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>data_record<span class="token punctuation">.</span>log_utils <span class="token keyword">import</span> logger <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestDataRecord</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""""""</span> <span class="token keyword">def</span> <span class="token function">test_data_record</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> search_content <span class="token operator">=</span> <span class="token string">"python语言"</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 定位输入框,输入内容</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>search_content<span class="token punctuation">)</span> <span class="token comment"># 加入日志,步骤信息较多且琐碎,使用debug</span> logger<span class="token punctuation">.</span>debug<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"搜索的信息为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"stb"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取搜索结果列表的标题,对应测试结果的实际结果</span> search_result <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"em"</span><span class="token punctuation">)</span> <span class="token comment"># 多个em的情况下,默认拿第一个</span> <span class="token comment"># 添加日志,断言使用info,级别高于debug,断言实际结果与预期结果是否一致</span> logger<span class="token punctuation">.</span>info<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"实际结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_result<span class="token punctuation">.</span>text<span class="token punctuation">}</span></span><span class="token string">,预期结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 断言,search_result.text 获取搜索结果的文本信息,预期结果search_content</span> <span class="token keyword">assert</span> search_result<span class="token punctuation">.</span>text <span class="token operator">==</span> search_content </code></pre> <h4>4、步骤截图记录</h4> <ol> <li>save_screenshot(截图路径+名称)</li> <li>记录关键页面 <ul> <li>断言页面</li> <li>重要的业务场景页面</li> <li>容易出错的页面</li> </ul> </li> </ol> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>data_record<span class="token punctuation">.</span>log_utils <span class="token keyword">import</span> logger <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestDataRecord</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_screen_shot_data_record</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> search_content01 <span class="token operator">=</span> <span class="token string">"python语言"</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 定位输入框,输入内容</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>search_content01<span class="token punctuation">)</span> <span class="token comment"># 加入日志,步骤信息较多且琐碎,使用debug</span> logger<span class="token punctuation">.</span>debug<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"搜索的信息为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content01<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"stb"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取搜索结果列表的标题,对应测试结果的实际结果</span> search_result01 <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"em"</span><span class="token punctuation">)</span> <span class="token comment"># 多个em的情况下,默认拿第一个</span> <span class="token comment"># 添加日志,断言使用info,级别高于debug,断言实际结果与预期结果是否一致</span> logger<span class="token punctuation">.</span>info<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"实际结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_result01<span class="token punctuation">.</span>text<span class="token punctuation">}</span></span><span class="token string">,预期结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content01<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 截图记录,双重保障</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>save_screenshot<span class="token punctuation">(</span><span class="token string">"search_result01.png"</span><span class="token punctuation">)</span> <span class="token comment"># 断言,search_result01.text 获取搜索结果的文本信息,预期结果search_content01</span> <span class="token keyword">assert</span> search_result01<span class="token punctuation">.</span>text <span class="token operator">==</span> search_content01 </code></pre> <h4>5、page source记录</h4> <ol> <li>使用page_source属性获取页面源码</li> <li>在调试过程中,如果有找不到元素的错误可以保存当时的page_source调试代码</li> </ol> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestDataRecord</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_page_source_data_record</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""获取page_source主要用于调试,可以不需要断言等其余信息"""</span> <span class="token comment"># 现象:产生了no such element的错误</span> <span class="token comment"># 方案:在报错的代码行之前打印page_source,确认定位的元素没有问题</span> content <span class="token operator">=</span> <span class="token string">"python语言"</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># # 定位输入框,输入内容</span> <span class="token comment"># self.driver.find_element(By.ID, "query").send_keys(content)</span> <span class="token comment"># 获取page_source,即获取的是这个网页的源代码</span> <span class="token comment"># logger.debug(self.driver.page_source) # 可以使用debug查看输出的内容</span> <span class="token comment"># 将获取的page_source写入到record.html</span> <span class="token keyword">with</span> <span class="token builtin">open</span><span class="token punctuation">(</span><span class="token string">"record.html"</span><span class="token punctuation">,</span> <span class="token string">"w"</span><span class="token punctuation">,</span> encoding<span class="token operator">=</span><span class="token string">"utf-8"</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span> f<span class="token punctuation">.</span>write<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>page_source<span class="token punctuation">)</span> <span class="token comment"># 错误定位输入框</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query1"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>content<span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/a2b2c0fd5d3a4c8bb38caac950f6af8b.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a2b2c0fd5d3a4c8bb38caac950f6af8b.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第22张图片" width="650" height="410" style="border:1px solid black;"></a></p> <p><a href="http://img.e-com-net.com/image/info8/e9657571012b4fbf9bda1a345dd1bab6.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/e9657571012b4fbf9bda1a345dd1bab6.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第23张图片" width="650" height="445" style="border:1px solid black;"></a></p> <h2>点此获取更多相关资料</h2> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1722195640198443008"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(学习,笔记,软件测试,自动化测试,python)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1835514464028422144.htm" title="情绪觉察日记第37天" target="_blank">情绪觉察日记第37天</a> <span class="text-muted">露露_e800</span> <div>今天是家庭关系规划师的第二阶最后一天,慧萍老师帮我做了个案,帮我处理了埋在心底好多年的一份恐惧,并给了我深深的力量!这几天出来学习,爸妈过来婆家帮我带小孩,妈妈出于爱帮我收拾东西,并跟我先生和婆婆产生矛盾,妈妈觉得他们没有照顾好我…。今晚回家见到妈妈,我很欣赏她并赞扬她,妈妈说今晚要跟我睡我说好,当我们俩躺在床上准备睡觉的时候,我握着妈妈的手对她说:妈妈这几天辛苦你了,你看你多利害把我们的家收拾得</div> </li> <li><a href="/article/1835513803861749760.htm" title="机器学习与深度学习间关系与区别" target="_blank">机器学习与深度学习间关系与区别</a> <span class="text-muted">ℒℴѵℯ心·动ꦿ໊ོ꫞</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>一、机器学习概述定义机器学习(MachineLearning,ML)是一种通过数据驱动的方法,利用统计学和计算算法来训练模型,使计算机能够从数据中学习并自动进行预测或决策。机器学习通过分析大量数据样本,识别其中的模式和规律,从而对新的数据进行判断。其核心在于通过训练过程,让模型不断优化和提升其预测准确性。主要类型1.监督学习(SupervisedLearning)监督学习是指在训练数据集中包含输入</div> </li> <li><a href="/article/1835513701143244800.htm" title="铭刻于星(四十二)" target="_blank">铭刻于星(四十二)</a> <span class="text-muted">随风至</span> <div>69夜晚,绍敏同学做完功课后,看了眼房外,没听到动静才敢从书包的夹层里拿出那个心形纸团。折痕压得很深,都有些旧了,想来是已经写好很久了。绍敏同学慢慢地、轻轻地捏开折叠处,待到全部拆开后,又反复抚平纸张,然后仔细地一字字默看。只是开头的三个字是第一次看到,让她心漏跳了几拍。“亲爱的绍敏:从四年级的时候,我就喜欢你了,但是我一直不敢说,怕影响你学习。六年级的时候听说有人跟你表白,你接受了,我很难过,但</div> </li> <li><a href="/article/1835513424734416896.htm" title="UI学习——cell的复用和自定义cell" target="_blank">UI学习——cell的复用和自定义cell</a> <span class="text-muted">Magnetic_h</span> <a class="tag" taget="_blank" href="/search/ui/1.htm">ui</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a> <div>目录cell的复用手动(非注册)自动(注册)自定义cellcell的复用在iOS开发中,单元格复用是一种提高表格(UITableView)和集合视图(UICollectionView)滚动性能的技术。当一个UITableViewCell或UICollectionViewCell首次需要显示时,如果没有可复用的单元格,则视图会创建一个新的单元格。一旦这个单元格滚动出屏幕,它就不会被销毁。相反,它被添</div> </li> <li><a href="/article/1835512809883004928.htm" title="10月|愿你的青春不负梦想-读书笔记-01" target="_blank">10月|愿你的青春不负梦想-读书笔记-01</a> <span class="text-muted">Tracy的小书斋</span> <div>本书的作者是俞敏洪,大家都很熟悉他了吧。俞敏洪老师是我行业的领头羊吧,也是我事业上的偶像。本日摘录他书中第一章中的金句:『一个人如果什么目标都没有,就会浑浑噩噩,感觉生命中缺少能量。能给我们能量的,是对未来的期待。第一件事,我始终为了进步而努力。与其追寻全世界的骏马,不如种植丰美的草原,到时骏马自然会来。第二件事,我始终有阶段性的目标。什么东西能给我能量?答案是对未来的期待。』读到这里的时候,我便</div> </li> <li><a href="/article/1835511912843014144.htm" title="理解Gunicorn:Python WSGI服务器的基石" target="_blank">理解Gunicorn:Python WSGI服务器的基石</a> <span class="text-muted">范范0825</span> <a class="tag" taget="_blank" href="/search/ipython/1.htm">ipython</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>理解Gunicorn:PythonWSGI服务器的基石介绍Gunicorn,全称GreenUnicorn,是一个为PythonWSGI(WebServerGatewayInterface)应用设计的高效、轻量级HTTP服务器。作为PythonWeb应用部署的常用工具,Gunicorn以其高性能和易用性著称。本文将介绍Gunicorn的基本概念、安装和配置,帮助初学者快速上手。1.什么是Gunico</div> </li> <li><a href="/article/1835511542284644352.htm" title="学点心理知识,呵护孩子健康" target="_blank">学点心理知识,呵护孩子健康</a> <span class="text-muted">静候花开_7090</span> <div>昨天听了华中师范大学教育管理学系副教授张玲老师的《哪里才是学生心理健康的最后庇护所,超越教育与技术的思考》的讲座。今天又重新学习了一遍,收获匪浅。张玲博士也注意到了当今社会上的孩子由于心理问题导致的自残、自杀及伤害他人等恶性事件。她向我们普及了一个重要的命题,她说心理健康的一些基本命题,我们与我们通常的一些教育命题是不同的,她还举了几个例子,让我们明白我们原来以为的健康并非心理学上的健康。比如如果</div> </li> <li><a href="/article/1835510025561403392.htm" title="《投行人生》读书笔记" target="_blank">《投行人生》读书笔记</a> <span class="text-muted">小蘑菇的树洞</span> <div>《投行人生》----作者詹姆斯-A-朗德摩根斯坦利副主席40年的职业洞见-很短小精悍的篇幅,比较适合初入职场的新人。第一部分成功的职业生涯需要规划1.情商归为适应能力分享与协作同理心适应能力,更多的是自我意识,你有能力识别自己的情并分辨这些情绪如何影响你的思想和行为。2.对于初入职场的人的建议,细节,截止日期和数据很重要截止日期,一种有效的方法是请老板为你所有的任务进行优先级排序。和老板喝咖啡的好</div> </li> <li><a href="/article/1835508131032035328.htm" title="ArcGIS栅格计算器常见公式(赋值、0和空值的转换、补充栅格空值)" target="_blank">ArcGIS栅格计算器常见公式(赋值、0和空值的转换、补充栅格空值)</a> <span class="text-muted">研学随笔</span> <a class="tag" taget="_blank" href="/search/arcgis/1.htm">arcgis</a><a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a> <div>我们在使用ArcGIS时通常经常用到栅格计算器,今天主要给大家介绍我日常中经常用到的几个公式,供大家参考学习。将特定值(-9999)赋值为0,例如-9999.Con("raster"==-9999,0,"raster")2.给空值赋予特定的值(如0)Con(IsNull("raster"),0,"raster")3.将特定的栅格值(如1)赋值为空值,其他保留原值SetNull("raster"==</div> </li> <li><a href="/article/1835507248395284480.htm" title="【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数" target="_blank">【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数</a> <span class="text-muted">广龙宇</span> <a class="tag" taget="_blank" href="/search/%E4%B8%80%E8%B5%B7%E5%AD%A6Rust/1.htm">一起学Rust</a><a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Rust%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">Rust设计模式</a><a class="tag" taget="_blank" href="/search/rust/1.htm">rust</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、使用借用类型作为参数二、格式化拼接字符串三、使用构造函数总结前言Rust不是传统的面向对象编程语言,它的所有特性,使其独一无二。因此,学习特定于Rust的设计模式是必要的。本系列文章为作者学习《Rust设计模式》的学习笔记以及自己的见解。因此,本系列文章的结构也与此书的结构相同(后续可能会调成结构),基本上分为三个部分</div> </li> <li><a href="/article/1835506996258893824.htm" title="回溯 Leetcode 332 重新安排行程" target="_blank">回溯 Leetcode 332 重新安排行程</a> <span class="text-muted">mmaerd</span> <a class="tag" taget="_blank" href="/search/Leetcode%E5%88%B7%E9%A2%98%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/1.htm">Leetcode刷题学习记录</a><a class="tag" taget="_blank" href="/search/leetcode/1.htm">leetcode</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E8%81%8C%E5%9C%BA%E5%92%8C%E5%8F%91%E5%B1%95/1.htm">职场和发展</a> <div>重新安排行程Leetcode332学习记录自代码随想录给你一份航线列表tickets,其中tickets[i]=[fromi,toi]表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。所有这些机票都属于一个从JFK(肯尼迪国际机场)出发的先生,所以该行程必须从JFK开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。例如,行程[“JFK”,“LGA”]与[“JFK”,“LGB</div> </li> <li><a href="/article/1835506869838376960.htm" title="Python数据分析与可视化实战指南" target="_blank">Python数据分析与可视化实战指南</a> <span class="text-muted">William数据分析</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE/1.htm">数据</a> <div>在数据驱动的时代,Python因其简洁的语法、强大的库生态系统以及活跃的社区,成为了数据分析与可视化的首选语言。本文将通过一个详细的案例,带领大家学习如何使用Python进行数据分析,并通过可视化来直观呈现分析结果。一、环境准备1.1安装必要库在开始数据分析和可视化之前,我们需要安装一些常用的库。主要包括pandas、numpy、matplotlib和seaborn等。这些库分别用于数据处理、数学</div> </li> <li><a href="/article/1835505858444881920.htm" title="git常用命令笔记" target="_blank">git常用命令笔记</a> <span class="text-muted">咩酱-小羊</span> <a class="tag" taget="_blank" href="/search/git/1.htm">git</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>###用习惯了idea总是不记得git的一些常见命令,需要用到的时候总是担心旁边站了人~~~记个笔记@_@,告诉自己看笔记不丢人初始化初始化一个新的Git仓库gitinit配置配置用户信息gitconfig--globaluser.name"YourName"gitconfig--globaluser.email"youremail@example.com"基本操作克隆远程仓库gitclone查看</div> </li> <li><a href="/article/1835505858939809792.htm" title="python os.environ" target="_blank">python os.environ</a> <span class="text-muted">江湖偌大</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a> <div>os.environ['TF_CPP_MIN_LOG_LEVEL']='0'#默认值,输出所有信息os.environ['TF_CPP_MIN_LOG_LEVEL']='1'#屏蔽通知信息(INFO)os.environ['TF_CPP_MIN_LOG_LEVEL']='2'#屏蔽通知信息和警告信息(INFO\WARNING)os.environ['TF_CPP_MIN_LOG_LEVEL']='</div> </li> <li><a href="/article/1835505606245576704.htm" title="Python中os.environ基本介绍及使用方法" target="_blank">Python中os.environ基本介绍及使用方法</a> <span class="text-muted">鹤冲天Pro</span> <a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>文章目录python中os.environos.environ简介os.environ进行环境变量的增删改查python中os.environ的使用详解1.简介2.key字段详解2.1常见key字段3.os.environ.get()用法4.环境变量的增删改查和判断是否存在4.1新增环境变量4.2更新环境变量4.3获取环境变量4.4删除环境变量4.5判断环境变量是否存在python中os.envi</div> </li> <li><a href="/article/1835505226933694464.htm" title="Pyecharts数据可视化大屏:打造沉浸式数据分析体验" target="_blank">Pyecharts数据可视化大屏:打造沉浸式数据分析体验</a> <span class="text-muted">我的运维人生</span> <a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">信息可视化</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4%E5%BC%80%E5%8F%91/1.htm">运维开发</a><a class="tag" taget="_blank" href="/search/%E6%8A%80%E6%9C%AF%E5%85%B1%E4%BA%AB/1.htm">技术共享</a> <div>Pyecharts数据可视化大屏:打造沉浸式数据分析体验在当今这个数据驱动的时代,如何将海量数据以直观、生动的方式展现出来,成为了数据分析师和企业决策者关注的焦点。Pyecharts,作为一款基于Python的开源数据可视化库,凭借其丰富的图表类型、灵活的配置选项以及高度的定制化能力,成为了构建数据可视化大屏的理想选择。本文将深入探讨如何利用Pyecharts打造数据可视化大屏,并通过实际代码案例</div> </li> <li><a href="/article/1835504817905168384.htm" title="2019-12-22-22:30" target="_blank">2019-12-22-22:30</a> <span class="text-muted">涓涓1016</span> <div>今天是冬至,写下我的日更,是因为这两天的学习真的是能量的满满,让我看到了自己,未来另外一种可能性,也让我看到了这两年这几年的过程中我所接受那些痛苦的来源。一切的根源和痛苦都来自于人生,家庭,而你的原生家庭,你的爸爸和妈妈,是因为你这个灵魂在那一刻选择他们作为你的爸爸和妈妈来的,所以你得接受他,你得接纳他,他就是因为他的存在而给你的学习和成长带来这些痛苦,那其实是你必然要经历的这个过程,当你去接纳的</div> </li> <li><a href="/article/1835504217729626112.htm" title="Python教程:一文了解使用Python处理XPath" target="_blank">Python教程:一文了解使用Python处理XPath</a> <span class="text-muted">旦莫</span> <a class="tag" taget="_blank" href="/search/Python%E8%BF%9B%E9%98%B6/1.htm">Python进阶</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>目录1.环境准备1.1安装lxml1.2验证安装2.XPath基础2.1什么是XPath?2.2XPath语法2.3示例XML文档3.使用lxml解析XML3.1解析XML文档3.2查看解析结果4.XPath查询4.1基本路径查询4.2使用属性查询4.3查询多个节点5.XPath的高级用法5.1使用逻辑运算符5.2使用函数6.实战案例6.1从网页抓取数据6.1.1安装Requests库6.1.2代</div> </li> <li><a href="/article/1835503965563875328.htm" title="python os.environ_python os.environ 读取和设置环境变量" target="_blank">python os.environ_python os.environ 读取和设置环境变量</a> <span class="text-muted">weixin_39605414</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/os.environ/1.htm">os.environ</a> <div>>>>importos>>>os.environ.keys()['LC_NUMERIC','GOPATH','GOROOT','GOBIN','LESSOPEN','SSH_CLIENT','LOGNAME','USER','HOME','LC_PAPER','PATH','DISPLAY','LANG','TERM','SHELL','J2REDIR','LC_MONETARY','QT_QPA</div> </li> <li><a href="/article/1835502704827396096.htm" title="将cmd中命令输出保存为txt文本文件" target="_blank">将cmd中命令输出保存为txt文本文件</a> <span class="text-muted">落难Coder</span> <a class="tag" taget="_blank" href="/search/Windows/1.htm">Windows</a><a class="tag" taget="_blank" href="/search/cmd/1.htm">cmd</a><a class="tag" taget="_blank" href="/search/window/1.htm">window</a> <div>最近深度学习本地的训练中我们常常要在命令行中运行自己的代码,无可厚非,我们有必要保存我们的炼丹结果,但是复制命令行输出到txt是非常麻烦的,其实Windows下的命令行为我们提供了相应的操作。其基本的调用格式就是:运行指令>输出到的文件名称或者具体保存路径测试下,我打开cmd并且ping一下百度:pingwww.baidu.com>./data.txt看下相同目录下data.txt的输出:如果你再</div> </li> <li><a href="/article/1835502282603589632.htm" title="509. 斐波那契数(每日一题)" target="_blank">509. 斐波那契数(每日一题)</a> <span class="text-muted">lzyprime</span> <div>lzyprime博客(github)创建时间:2021.01.04qq及邮箱:2383518170leetcode笔记题目描述斐波那契数,通常用F(n)表示,形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2),其中n>1给你n,请计算F(n)。示例1:输入:2输出:1解释:F(2)=F(1)+</div> </li> <li><a href="/article/1835500750684385280.htm" title="拥有断舍离的心态,过精简生活--《断舍离》读书笔记" target="_blank">拥有断舍离的心态,过精简生活--《断舍离》读书笔记</a> <span class="text-muted">爱吃丸子的小樱桃</span> <div>不知不觉间房间里的东西越来越多,虽然摆放整齐,但也时常会觉得空间逼仄,令人心生烦闷。抱着断舍离的态度,我开始阅读《断舍离》这本书,希望从书中能找到一些有效的方法,帮助我实现空间、物品上的断舍离。《断舍离》是日本作家山下英子通过自己的经历、思考和实践总结而成的,整体内涵也从刚开始的私人生活哲学的“断舍离”升华成了“人生实践哲学”,接着又成为每个人都能实行的“改变人生的断舍离”,从“哲学”逐渐升华成“</div> </li> <li><a href="/article/1835499615491813376.htm" title="四章-32-点要素的聚合" target="_blank">四章-32-点要素的聚合</a> <span class="text-muted">彩云飘过</span> <div>本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters.</div> </li> <li><a href="/article/1835498219489030144.htm" title="高端密码学院笔记285" target="_blank">高端密码学院笔记285</a> <span class="text-muted">柚子_b4b4</span> <div>高端幸福密码学院(高级班)幸福使者:李华第(598)期《幸福》之回归内在深层生命原动力基础篇——揭秘“激励”成长的喜悦心理案例分析主讲:刘莉一,知识扩充:成功=艰苦劳动+正确方法+少说空话。贪图省力的船夫,目标永远下游。智者的梦再美,也不如愚人实干的脚印。幸福早课堂2020.10.16星期五一笔记:1,重视和珍惜的前提是知道它的价值非常重要,当你珍惜了,你就真正定下来,真正的学到身上。2,大家需要</div> </li> <li><a href="/article/1835497664922349568.htm" title="使用Faiss进行高效相似度搜索" target="_blank">使用Faiss进行高效相似度搜索</a> <span class="text-muted">llzwxh888</span> <a class="tag" taget="_blank" href="/search/faiss/1.htm">faiss</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>在现代AI应用中,快速和高效的相似度搜索是至关重要的。Faiss(FacebookAISimilaritySearch)是一个专门用于快速相似度搜索和聚类的库,特别适用于高维向量。本文将介绍如何使用Faiss来进行相似度搜索,并结合Python代码演示其基本用法。什么是Faiss?Faiss是一个由FacebookAIResearch团队开发的开源库,主要用于高维向量的相似性搜索和聚类。Faiss</div> </li> <li><a href="/article/1835497665853485056.htm" title="python是什么意思中文-在python中%是什么意思" target="_blank">python是什么意思中文-在python中%是什么意思</a> <span class="text-muted">编程大乐趣</span> <div>Python中%有两种:1、数值运算:%代表取模,返回除法的余数。如:>>>7%212、%操作符(字符串格式化,stringformatting),说明如下:%[(name)][flags][width].[precision]typecode(name)为命名flags可以有+,-,''或0。+表示右对齐。-表示左对齐。''为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。0表示使用0填</div> </li> <li><a href="/article/1835496402042580992.htm" title="GitHub上克隆项目" target="_blank">GitHub上克隆项目</a> <span class="text-muted">bigbig猩猩</span> <a class="tag" taget="_blank" href="/search/github/1.htm">github</a> <div>从GitHub上克隆项目是一个简单且直接的过程,它允许你将远程仓库中的项目复制到你的本地计算机上,以便进行进一步的开发、测试或学习。以下是一个详细的步骤指南,帮助你从GitHub上克隆项目。一、准备工作1.安装Git在克隆GitHub项目之前,你需要在你的计算机上安装Git工具。Git是一个开源的分布式版本控制系统,用于跟踪和管理代码变更。你可以从Git的官方网站(https://git-scm.</div> </li> <li><a href="/article/1835496148601761792.htm" title="HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动" target="_blank">HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动</a> <span class="text-muted">二挡起步</span> <a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/web%E8%AE%BE%E8%AE%A1%E7%BD%91%E9%A1%B5%E8%A7%84%E5%88%92%E4%B8%8E%E8%AE%BE%E8%AE%A1/1.htm">web设计网页规划与设计</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/dreamweaver/1.htm">dreamweaver</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线</div> </li> <li><a href="/article/1835495770502033408.htm" title="Day17笔记-高阶函数" target="_blank">Day17笔记-高阶函数</a> <span class="text-muted">~在杰难逃~</span> <a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/pycharm/1.htm">pycharm</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a> <div>高阶函数【重点掌握】函数的本质:函数是一个变量,函数名是一个变量名,一个函数可以作为另一个函数的参数或返回值使用如果A函数作为B函数的参数,B函数调用完成之后,会得到一个结果,则B函数被称为高阶函数常用的高阶函数:map(),reduce(),filter(),sorted()1.map()map(func,iterable),返回值是一个iterator【容器,迭代器】func:函数iterab</div> </li> <li><a href="/article/1835495644123459584.htm" title="Day1笔记-Python简介&标识符和关键字&输入输出" target="_blank">Day1笔记-Python简介&标识符和关键字&输入输出</a> <span class="text-muted">~在杰难逃~</span> <a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a> <div>大家好,从今天开始呢,杰哥开展一个新的专栏,当然,数据分析部分也会不定时更新的,这个新的专栏主要是讲解一些Python的基础语法和知识,帮助0基础的小伙伴入门和学习Python,感兴趣的小伙伴可以开始认真学习啦!一、Python简介【了解】1.计算机工作原理编程语言就是用来定义计算机程序的形式语言。我们通过编程语言来编写程序代码,再通过语言处理程序执行向计算机发送指令,让计算机完成对应的工作,编程</div> </li> <li><a href="/article/60.htm" title="Dom" target="_blank">Dom</a> <span class="text-muted">周华华</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a> <div><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&q</div> </li> <li><a href="/article/187.htm" title="【Spark九十六】RDD API之combineByKey" target="_blank">【Spark九十六】RDD API之combineByKey</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/spark/1.htm">spark</a> <div>1. combineByKey函数的运行机制   RDD提供了很多针对元素类型为(K,V)的API,这些API封装在PairRDDFunctions类中,通过Scala隐式转换使用。这些API实现上是借助于combineByKey实现的。combineByKey函数本身也是RDD开放给Spark开发人员使用的API之一   首先看一下combineByKey的方法说明:</div> </li> <li><a href="/article/314.htm" title="msyql设置密码报错:ERROR 1372 (HY000): 解决方法详解" target="_blank">msyql设置密码报错:ERROR 1372 (HY000): 解决方法详解</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E7%BD%AE%E5%AF%86%E7%A0%81/1.htm">设置密码</a> <div>MySql给用户设置权限同时指定访问密码时,会提示如下错误: ERROR 1372 (HY000): Password hash should be a 41-digit hexadecimal number;   问题原因:你输入的密码是明文。不允许这么输入。   解决办法:用select password('你想输入的密码');查询出你的密码对应的字符串, 然后</div> </li> <li><a href="/article/441.htm" title="路漫漫其修远兮 吾将上下而求索" target="_blank">路漫漫其修远兮 吾将上下而求索</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0+%E6%80%9D%E7%B4%A2/1.htm">学习 思索</a> <div>王国维在他的《人间词话》中曾经概括了为学的三种境界古今之成大事业、大学问者,罔不经过三种之境界。“昨夜西风凋碧树。独上高楼,望尽天涯路。”此第一境界也。“衣带渐宽终不悔,为伊消得人憔悴。”此第二境界也。“众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”此第三境界也。学习技术,这也是你必须经历的三种境界。第一层境界是说,学习的路是漫漫的,你必须做好充分的思想准备,如果半途而废还不如不要开始。这里,注</div> </li> <li><a href="/article/568.htm" title="Hadoop(二)对话单的操作" target="_blank">Hadoop(二)对话单的操作</a> <span class="text-muted">朱辉辉33</span> <a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a> <div>Debug: 1、 A = LOAD '/user/hue/task.txt' USING PigStorage(' ') AS (col1,col2,col3); DUMP A; //输出结果前几行示例: (>ggsnPDPRecord(21),,) (-->recordType(0),,) (-->networkInitiation(1),,) </div> </li> <li><a href="/article/695.htm" title="web报表工具FineReport常用函数的用法总结(日期和时间函数)" target="_blank">web报表工具FineReport常用函数的用法总结(日期和时间函数)</a> <span class="text-muted">老A不折腾</span> <a class="tag" taget="_blank" href="/search/finereport/1.htm">finereport</a><a class="tag" taget="_blank" href="/search/%E6%8A%A5%E8%A1%A8%E5%B7%A5%E5%85%B7/1.htm">报表工具</a><a class="tag" taget="_blank" href="/search/web%E5%BC%80%E5%8F%91/1.htm">web开发</a> <div>web报表工具FineReport常用函数的用法总结(日期和时间函数)   说明:凡函数中以日期作为参数因子的,其中日期的形式都必须是yy/mm/dd。而且必须用英文环境下双引号(" ")引用。   DATE DATE(year,month,day):返回一个表示某一特定日期的系列数。 Year:代表年,可为一到四位数。 Month:代表月份。</div> </li> <li><a href="/article/822.htm" title="c++ 宏定义中的##操作符" target="_blank">c++ 宏定义中的##操作符</a> <span class="text-muted">墙头上一根草</span> <a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a> <div>#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {       &nbs</div> </li> <li><a href="/article/949.htm" title="分析Spring源代码之,DI的实现" target="_blank">分析Spring源代码之,DI的实现</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/DI/1.htm">DI</a><a class="tag" taget="_blank" href="/search/%E7%8E%B0/1.htm">现</a><a class="tag" taget="_blank" href="/search/%E6%BA%90%E4%BB%A3%E7%A0%81/1.htm">源代码</a> <div>(转) 分析Spring源代码之,DI的实现 2012/1/3 by tony                 接着上次的讲,以下这个sample [java]  view plain copy print </div> </li> <li><a href="/article/1076.htm" title="for循环的进化" target="_blank">for循环的进化</a> <span class="text-muted">alxw4616</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>// for循环的进化 // 菜鸟 for (var i = 0; i < Things.length ; i++) { // Things[i] } // 老鸟 for (var i = 0, len = Things.length; i < len; i++) { // Things[i] } // 大师 for (var i = Things.le</div> </li> <li><a href="/article/1203.htm" title="网络编程Socket和ServerSocket简单的使用" target="_blank">网络编程Socket和ServerSocket简单的使用</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80/1.htm">网络编程基础</a><a class="tag" taget="_blank" href="/search/IP%E5%9C%B0%E5%9D%80%E7%AB%AF%E5%8F%A3/1.htm">IP地址端口</a> <div>  网络编程;TCP/IP协议   网络:实现计算机之间的信息共享,数据资源的交换   协议:数据交换需要遵守的一种协议,按照约定的数据格式等写出去   端口:用于计算机之间的通信      每运行一个程序,系统会分配一个编号给该程序,作为和外界交换数据的唯一标识 0~65535   查看被使用的</div> </li> <li><a href="/article/1330.htm" title="JDK1.5 生产消费者" target="_blank">JDK1.5 生产消费者</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a><a class="tag" taget="_blank" href="/search/%E7%94%9F%E4%BA%A7%E6%B6%88%E8%B4%B9%E8%80%85/1.htm">生产消费者</a><a class="tag" taget="_blank" href="/search/java%E5%A4%9A%E7%BA%BF%E7%A8%8B/1.htm">java多线程</a> <div>ArrayBlockingQueue:        一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列检索操作则是从队列头部开始获得元素。 ArrayBlockingQueue的常用方法: </div> </li> <li><a href="/article/1457.htm" title="JAVA版身份证获取性别、出生日期及年龄" target="_blank">JAVA版身份证获取性别、出生日期及年龄</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%80%A7%E5%88%AB/1.htm">性别</a><a class="tag" taget="_blank" href="/search/%E5%87%BA%E7%94%9F%E6%97%A5%E6%9C%9F/1.htm">出生日期</a><a class="tag" taget="_blank" href="/search/%E5%B9%B4%E9%BE%84/1.htm">年龄</a> <div>        工作中需要根据身份证获取性别、出生日期及年龄,且要还要支持15位长度的身份证号码,网上搜索了一下,经过测试好像多少存在点问题,干脆自已写一个。 CertificateNo.java package com.bijian.study; import java.util.Calendar; import </div> </li> <li><a href="/article/1584.htm" title="【Java范型六】范型与枚举" target="_blank">【Java范型六】范型与枚举</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>首先,枚举类型的定义不能带有类型参数,所以,不能把枚举类型定义为范型枚举类,例如下面的枚举类定义是有编译错的   public enum EnumGenerics<T> { //编译错,提示枚举不能带有范型参数 OK, ERROR; public <T> T get(T type) { return null; </div> </li> <li><a href="/article/1711.htm" title="【Nginx五】Nginx常用日志格式含义" target="_blank">【Nginx五】Nginx常用日志格式含义</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a> <div>1. log_format 1.1 log_format指令用于指定日志的格式,格式:   log_format name(格式名称) type(格式样式)   1.2 如下是一个常用的Nginx日志格式:   log_format main '[$time_local]|$request_time|$status|$body_bytes</div> </li> <li><a href="/article/1838.htm" title="Lua 语言 15 分钟快速入门" target="_blank">Lua 语言 15 分钟快速入门</a> <span class="text-muted">ronin47</span> <a class="tag" taget="_blank" href="/search/lua+%E5%9F%BA%E7%A1%80/1.htm">lua 基础</a> <div>- - 单行注释 - - [[      [多行注释] - - ]]   - - - - - - - - - - - 1. 变量 & 控制流 - - - - - - - - - - num = 23 - - 数字都是双精度 str = 'aspythonstring' </div> </li> <li><a href="/article/1965.htm" title="java-35.求一个矩阵中最大的二维矩阵 ( 元素和最大 )" target="_blank">java-35.求一个矩阵中最大的二维矩阵 ( 元素和最大 )</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>the idea is from: http://blog.csdn.net/zhanxinhang/article/details/6731134 public class MaxSubMatrix { /**see http://blog.csdn.net/zhanxinhang/article/details/6731134 * Q35 求一个矩阵中最大的二维</div> </li> <li><a href="/article/2092.htm" title="mongoDB文档型数据库特点" target="_blank">mongoDB文档型数据库特点</a> <span class="text-muted">开窍的石头</span> <a class="tag" taget="_blank" href="/search/mongoDB%E6%96%87%E6%A1%A3%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E7%89%B9%E7%82%B9/1.htm">mongoDB文档型数据库特点</a> <div>MongoDD: 文档型数据库存储的是Bson文档-->json的二进制 特点:内部是执行引擎是js解释器,把文档转成Bson结构,在查询时转换成js对象。 mongoDB传统型数据库对比    传统类型数据库:结构化数据,定好了表结构后每一个内容符合表结构的。也就是说每一行每一列的数据都是一样的    文档型数据库:不用定好数据结构,</div> </li> <li><a href="/article/2219.htm" title="[毕业季节]欢迎广大毕业生加入JAVA程序员的行列" target="_blank">[毕业季节]欢迎广大毕业生加入JAVA程序员的行列</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>     一年一度的毕业季来临了。。。。。。。。      正在投简历的学弟学妹们。。。如果觉得学校推荐的单位和公司不适合自己的兴趣和专业,可以考虑来我们软件行业,做一名职业程序员。。。      软件行业的开发工具中,对初学者最友好的就是JAVA语言了,网络上不仅仅有大量的</div> </li> <li><a href="/article/2346.htm" title="PHP操作Excel – PHPExcel 基本用法详解" target="_blank">PHP操作Excel – PHPExcel 基本用法详解</a> <span class="text-muted">cuiyadll</span> <a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/Excel/1.htm">Excel</a> <div>导出excel属性设置//Include classrequire_once('Classes/PHPExcel.php');require_once('Classes/PHPExcel/Writer/Excel2007.php');$objPHPExcel = new PHPExcel();//Set properties 设置文件属性$objPHPExcel->getProperties</div> </li> <li><a href="/article/2473.htm" title="IBM Webshpere MQ Client User Issue (MCAUSER)" target="_blank">IBM Webshpere MQ Client User Issue (MCAUSER)</a> <span class="text-muted">darrenzhu</span> <a class="tag" taget="_blank" href="/search/IBM/1.htm">IBM</a><a class="tag" taget="_blank" href="/search/jms/1.htm">jms</a><a class="tag" taget="_blank" href="/search/user/1.htm">user</a><a class="tag" taget="_blank" href="/search/MQ/1.htm">MQ</a><a class="tag" taget="_blank" href="/search/MCAUSER/1.htm">MCAUSER</a> <div>IBM MQ JMS Client去连接远端MQ Server的时候,需要提供User和Password吗? 答案是根据情况而定,取决于所定义的Channel里面的属性Message channel agent user identifier (MCAUSER)的设置。 http://stackoverflow.com/questions/20209429/how-mca-user-i</div> </li> <li><a href="/article/2600.htm" title="网线的接法" target="_blank">网线的接法</a> <span class="text-muted">dcj3sjt126com</span> <div>一、PC连HUB (直连线)A端:(标准568B):白橙,橙,白绿,蓝,白蓝,绿,白棕,棕。 B端:(标准568B):白橙,橙,白绿,蓝,白蓝,绿,白棕,棕。 二、PC连PC (交叉线)A端:(568A): 白绿,绿,白橙,蓝,白蓝,橙,白棕,棕; B端:(标准568B):白橙,橙,白绿,蓝,白蓝,绿,白棕,棕。 三、HUB连HUB&nb</div> </li> <li><a href="/article/2727.htm" title="Vimium插件让键盘党像操作Vim一样操作Chrome" target="_blank">Vimium插件让键盘党像操作Vim一样操作Chrome</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/chrome/1.htm">chrome</a><a class="tag" taget="_blank" href="/search/vim/1.htm">vim</a> <div>什么是键盘党? 键盘党是指尽可能将所有电脑操作用键盘来完成,而不去动鼠标的人。鼠标应该说是新手们的最爱,很直观,指哪点哪,很听话!不过常常使用电脑的人,如果一直使用鼠标的话,手会发酸,因为操作鼠标的时候,手臂不是在一个自然的状态,臂肌会处于绷紧状态。而使用键盘则双手是放松状态,只有手指在动。而且尽量少的从鼠标移动到键盘来回操作,也省不少事。 在chrome里安装 vimium 插件 </div> </li> <li><a href="/article/2854.htm" title="MongoDB查询(2)——数组查询[六]" target="_blank">MongoDB查询(2)——数组查询[六]</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/MongoDB%E6%9F%A5%E8%AF%A2%E6%95%B0%E7%BB%84/1.htm">MongoDB查询数组</a> <div>MongoDB查询数组 转载请出自出处:http://eksliang.iteye.com/blog/2177292 一、概述  MongoDB查询数组与查询标量值是一样的,例如,有一个水果列表,如下所示: > db.food.find() { "_id" : "001", "fruits" : [ "苹</div> </li> <li><a href="/article/2981.htm" title="cordova读写文件(1)" target="_blank">cordova读写文件(1)</a> <span class="text-muted">gundumw100</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/Cordova/1.htm">Cordova</a> <div>使用cordova可以很方便的在手机sdcard中读写文件。 首先需要安装cordova插件:file 命令为: cordova plugin add org.apache.cordova.file 然后就可以读写文件了,这里我先是写入一个文件,具体的JS代码为: var datas=null;//datas need write var directory=&</div> </li> <li><a href="/article/3108.htm" title="HTML5 FormData 进行文件jquery ajax 上传 到又拍云" target="_blank">HTML5 FormData 进行文件jquery ajax 上传 到又拍云</a> <span class="text-muted">ileson</span> <a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/html5/1.htm">html5</a><a class="tag" taget="_blank" href="/search/FormData/1.htm">FormData</a> <div>html5 新东西:FormData  可以提交二进制数据。 页面test.html <!DOCTYPE> <html> <head> <title> formdata file jquery ajax upload</title> </head> <body> <</div> </li> <li><a href="/article/3235.htm" title="swift appearanceWhenContainedIn:(version1.2 xcode6.4)" target="_blank">swift appearanceWhenContainedIn:(version1.2 xcode6.4)</a> <span class="text-muted">啸笑天</span> <a class="tag" taget="_blank" href="/search/version/1.htm">version</a> <div>  swift1.2中没有oc中对应的方法: + (instancetype)appearanceWhenContainedIn:(Class <UIAppearanceContainer>)ContainerClass, ... NS_REQUIRES_NIL_TERMINATION;  解决方法: 在swift项目中新建oc类如下: #import &</div> </li> <li><a href="/article/3362.htm" title="java实现SMTP邮件服务器" target="_blank">java实现SMTP邮件服务器</a> <span class="text-muted">macroli</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a> <div>电子邮件传递可以由多种协议来实现。目前,在Internet 网上最流行的三种电子邮件协议是SMTP、POP3 和 IMAP,下面分别简单介绍。   ◆ SMTP 协议   简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)是一个运行在TCP/IP之上的协议,用它发送和接收电子邮件。SMTP 服务器在默认端口25上监听。SMTP客户使用一组简单的、基于文本的</div> </li> <li><a href="/article/3489.htm" title="mongodb group by having where 查询sql" target="_blank">mongodb group by having where 查询sql</a> <span class="text-muted">qiaolevip</span> <a class="tag" taget="_blank" href="/search/%E6%AF%8F%E5%A4%A9%E8%BF%9B%E6%AD%A5%E4%B8%80%E7%82%B9%E7%82%B9/1.htm">每天进步一点点</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E6%B0%B8%E6%97%A0%E6%AD%A2%E5%A2%83/1.htm">学习永无止境</a><a class="tag" taget="_blank" href="/search/mongo/1.htm">mongo</a><a class="tag" taget="_blank" href="/search/%E7%BA%B5%E8%A7%82%E5%8D%83%E8%B1%A1/1.htm">纵观千象</a> <div>SELECT cust_id, SUM(price) as total FROM orders WHERE status = 'A' GROUP BY cust_id HAVING total > 250 db.orders.aggregate( [ { $match: { status: 'A' } }, { $group: { </div> </li> <li><a href="/article/3616.htm" title="Struts2 Pojo(六)" target="_blank">Struts2 Pojo(六)</a> <span class="text-muted">Luob.</span> <a class="tag" taget="_blank" href="/search/POJO/1.htm">POJO</a><a class="tag" taget="_blank" href="/search/strust2/1.htm">strust2</a> <div>注意:附件中有完整案例 1.采用POJO对象的方法进行赋值和传值 2.web配置 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee&q</div> </li> <li><a href="/article/3743.htm" title="struts2步骤" target="_blank">struts2步骤</a> <span class="text-muted">wuai</span> <a class="tag" taget="_blank" href="/search/struts/1.htm">struts</a> <div>1、添加jar包 2、在web.xml中配置过滤器 <filter>        <filter-name>struts2</filter-name>        <filter-class>org.apache.st</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>