通过selenium的方式可以实现与web进行交互操作,本文列举了一些基础的写法,澄清了网络上一些错误写法,并给出了一些模拟动作函数。
欢迎大家收藏,未来会继续更新本文。文中的错误请大家在评论指出。
目录
版本说明:selenium=4.4.3
代码测试平台:win10(chrome=104.0.5112.102)、Mac M1(chrome=105.0.5195.125)
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 通过Option写入启动浏览器的参数
chrome_options = Options()
chrome_options.add_argument("--no-sandbox") # 传入该能解决部分root相关问题
# chrome_options.add_argument("--headless") # 传入该参数后,浏览器不会打开,一切操作后台执行
chrome_options.add_argument("--disable-dev-shum-usage")
# 基于上述参数启动浏览器
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(url) # 指定打开的网页
print("Chrome Task title: " + driver.title)
# 前进
driver.forward()
# 后退
driver.back()
# 刷新
driver.refrash()
版本说明:
新版selenium与旧版存在更新,统一使用find_element函数,通过By传参。
安装最新版selenium使用旧版会存在"AttributeError: ‘WebDriver’ object has no attribute xxxx"报错。
旧版:
(1)driver.find_element_by_id(“value”)
(2)driver.find_element_by_class_name(“value”)
(3)…
新版:
(1)driver.find_element(By.ID, “value”)
(2)driver.find_element(By.CSS_SELECTOR, “value”)
(3)…
个人推荐css selector,写法更加通用,传参中指定条件(id/class/type)。
需要注意的是,这里使用find_element方法只会返回一个元素,默认为第一个符合条件的元素。如果使用find_elements方法会返回list。
from selenium.webdriver.common.by import By
# 基于CSS
driver.find_element(By.CSS_SELECTOR, values) # 通式
# 基于xpath
driver.find_element(By.XPATH, values) # 通式
| 条件 | html | values 写法1 | values 写法2 |
|---|---|---|---|
| 标签 | ‘div’ | - | |
| id | < button id=“button”> | ‘#button’ | ‘[id=“button”]’ |
| class | < button class=“el-button”> | ‘.el-button’ | ‘[class=“el-button”]’ |
| multi-class | < button class=“el-button el-button–primary”> | ‘.el-button.el-button–primary’ | ‘[class=“el-button el-button–primary”]’ |
| type name … | - | - | 同上 |
头尾匹配写法:其中,头尾匹配可以是部分字符,部分匹配需要是按空格分隔的完整字符。
| 条件 | html | values 写法1 (头部匹配) | values 写法2 (尾部匹配) | values 写法3 (部分匹配) |
|---|---|---|---|---|
| class | < button class=“el-button el-button–primary”> | ‘[class^=“el-button”]’ | ‘[class$=“–primary”]’ | ‘[class~=“el-button”]’ |
(1)同时包含两个条件
# 这里使用CSS举例
# 包含input标签与type='text'属性
driver.find_element(By.CSS_SELECTOR, 'input[type="text"]')
# 包含type='text'与maxlength='50'两个条件的元素,语法上不需要and进行连接
driver.find_element(By.CSS_SELECTOR, '[type="text"][maxlength="50"]')
(2)包含一个条件且不包含另一条件
# 包含type='text'且不包含maxlength='50'的元素,语法上使用:not()进行连接
driver.find_element(By.CSS_SELECTOR, '[type="text"]:not([maxlength="50"])')
新版css 使用’:contains(“xxx”)'会报错illegal。查阅了一些资料,没有发现在css selector中使用:contain的方法,欢迎大家补充。
同时,网上某些方法的语法存在问题,这里做一下澄清。
# 这里使用xpath进行text定位
driver.find_element(By.XPATH, values)
| html | values写法1 | values写法2 | |
|---|---|---|---|
| 模糊匹配 | < div type=‘button’>登陆< /div> | “//div[contains(text(),‘登陆’)]” | “//*[contains(text(),‘登陆’)]” |
| 准确匹配 | < div type=‘button’>登陆< /div> | “//div[text()=‘登陆’]” | “//*[text()=‘登陆’]” |
注:本人遇到过模糊匹配可以定位,但是准确匹配无法定位的情况。大家可以优先使用模糊匹配。
这里给大家一些动作的示例,更多的组合动作大家自己探索。
from selenium.webdriver.common.action_chains import ActionChains
# 鼠标点击
def dom_click(values, by='css'):
if by == 'css':
driver.find_element(By.CSS_SELECTOR, values).click()
elif by == 'xpath':
driver.find_element(By.XPATH, values).click()
# 鼠标悬停
def dom_focus(values, by='css'):
if by == 'css':
location = driver.find_element(By.CSS_SELECTOR, values)
elif by == 'xpath':
location = driver.find_element(By.XPATH, values)
chain = ActionChains(self._driver)
chain.move_to_element(location)
chain.perform()
# 键盘输入
def type(text):
chain = ActionChains(driver)
chain.send_keys(text)
chain.perform()
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用
如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的