Python

※This article is based on Python 3.7.3

环境 [edit]

webdriver [edit]

Microsoft Edge浏览器 [edit]

推荐使用Edge浏览器,因为Chrome的版本问题,webdrive总是没有最新的

浏览器下载地址:

https://www.microsoft.com/zh-cn/edge

驱动器下载地址:

https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

Firefox(火狐)浏览器 [edit]

浏览器下载地址:

http://www.firefox.com.cn

驱动器下载地址:

https://github.com/mozilla/geckodriver/releases

Chrome(google)浏览器 [edit]

浏览器下载地址:

https://www.google.cn/chrome

驱动器下载地址:

http://chromedriver.storage.googleapis.com/index.html

下载路径

http://npm.taobao.org/mirrors/chromedriver/

要和本地的Chrome的版本一致,否则报错

selenium.common.exceptions.WebDriverException: Message: unknown error: cannot connect to chrome at 127.0.0.1:9527
from session not created: This version of ChromeDriver only supports Chrome version 99
Current browser version is 116.0.5845.142
Stacktrace:
Backtrace:
        Ordinal0 [0x007B9943+2595139]
        Ordinal0 [0x0074C9F1+2148849]
        Ordinal0 [0x00644528+1066280]
        Ordinal0 [0x006642C3+1196739]
        Ordinal0 [0x0065D83B+1169467]
        Ordinal0 [0x0065D606+1168902]
        Ordinal0 [0x00690530+1377584]

等待 [edit]

显示等待 [edit]

WebDriverWait(driver,timeout=10).until(ec.presence_of_element_located(locator))

超时时间内定位到locator后执行下一步,否则超时异常

隐式等待 [edit]

driver.implicitly_wait(timeout=10)

等待页面完全加载好才能执行下一步,只需要获取某个元素时,有点浪费时间,配一个限制一下避免部分页面加载慢

强制等待 [edit]

time.sleep(10)

不要用这种,不稳定

页面等待 [edit]

driver.set_page_load_timeout(timeout=20)

执行get(url)方法,页面等待超时时间

元素定位 [edit]

Html Code

<input type="text" class="s_ipt" name="wd" id="kw" />
定位方式By
idBy.ID
nameBy.NAME
class_nameBy.CLASS_NAME
tag_nameBy.TAG_NAME
link_textBy.LINK_TEXT
partial_link_textBy.PARTIAL_LINK_TEXT
css_selectorBy.CSS_SELECTOR
xpathBy.XPATH

ID定位 [edit]

find_element_by_id(id) #id参数表示的是id的属性值;(定位的元素必须有ID属性)

driver.find_element_by_id("kw")

NAME定位 [edit]

find_element_by_name(name) #name参数表示的是name的属性值;(定位元素必须有NAME属性)

driver.find_element_by_name("wd")

CLASS_NAME定位 [edit]

find_element_by_class_name(class_name) #class_name参数表示的是class的属性值;(定位元素必须有class属性)

driver.find_element_by_class_name("s_ipt")
#新的用法
driver.find_element(by=By.CLASS_NAME, value="s_ipt")
#列举多个
driver.find_elements(by=By.CLASS_NAME, value="s_ipt")

注意:class属性值有多个时(用空格隔开),仅需要其中一个属性值:(但若是使用Xpath属性定位时,需要用到全部属性值)

TAG_NAME定位 [edit]

find_element_by_tag_name(tag_name) #tag_name参数表示的是元素的标签名;(定位元素必须有标签名)如果有重复的元素定位到的元素默认都是第一个;

driver.find_element_by_tag_name("input")

XPATH定位 [edit]

使用class定位 [edit]

driver.find_element_by_xpath('//input[@class="s_ipt"]')

路径定位 [edit]

定位方法:find_element_by_xpath(xpath) #xpath表达式

绝对路径:表达式以/html开头,元素的层级之间是以/分隔,相同层级的元素可以使用下标,下标从1开始;需要列出元素所经过的所有层级元素,在工作中,一般不使用绝对路径。

/html/body/div/div/div/div/div

路径定位 定位方法:find_element_by_xpath(xpath) #xpath表达式

相对路径:匹配任意层级的元素,是以//tag_name或者//*开头,也可以使用下标,下标从1 开始。

//div[10]//button

属性定位 [edit]

<input type="text" class="s_ipt" name="wd" id="kw" />
driver.find_element_by_xpath(//input[@id='kw'])

通过父元素查找子元素 [edit]

在Selenium中,我们可以使用find_element_by_xpath()方法来查找子元素。例如,假设我们要查找一个div元素下面的第二个a元素,可以使用以下代码:

div_element = driver.find_element_by_xpath("//div[@class='example']")
a_element = div_element.find_element_by_xpath(".//a[2]")

上面的代码首先使用driver.find_element_by_xpath()方法查找到class属性为'example'的div元素,然后使用div_element.find_element_by_xpath()方法查找div元素下面的第二个a元素。在这里,'.//'表示相对路径,表示在当前元素下查找子元素。

通过子元素找到父元素 [edit]

在Selenium中,我们也可以使用parent属性来查找父元素。例如,假设我们要查找一个a元素的父元素,可以使用以下代码:

a_element = driver.find_element_by_xpath("//a[@id='example']")
div_element = a_element.find_element_by_xpath("..")

上面的代码首先使用driver.find_element_by_xpath()方法查找id属性为'example'的a元素,然后使用a_element.find_element_by_xpath("..")方法查找a元素的父元素。在这里,'..'表示父节点。

兄弟节点定位 [edit]

兄弟节点定位是指在HTML中,同一级别的元素之间存在兄弟关系。例如,一个ul元素下面有多个li元素,这些li元素就是ul元素的兄弟节点。在Selenium中,我们可以使用兄弟节点定位来查找特定的元素。

查找前一个兄弟节点 [edit]

在Selenium中,我们可以使用preceding-sibling轴来查找前一个兄弟节点。例如,假设我们要查找一个ul元素下面的第一个li元素的前一个兄弟节点,可以使用以下代码:

ul_element = driver.find_element_by_xpath("//ul[@class='example']")
li_element = ul_element.find_element_by_xpath("./li[1]")
previous_li_element = li_element.find_element_by_xpath("preceding-sibling::li[1]")

上面的代码首先使用driver.find_element_by_xpath()方法查找class属性为'example'的ul元素,然后使用ul_element.find_element_by_xpath()方法查找ul元素下面的第一个li元素,最后使用li_element.find_element_by_xpath("preceding-sibling::li[1]")方法查找li元素的前一个兄弟节点。

查找后一个兄弟节点 [edit]

在Selenium中,我们可以使用following-sibling轴来查找后一个兄弟节点。例如,假设我们要查找一个ul元素下面的第一个li元素的后一个兄弟节点,可以使用以下代码:

ul_element = driver.find_element_by_xpath("//ul[@class='example']")
li_element = ul_element.find_element_by_xpath("./li[1]")
next_li_element = li_element.find_element_by_xpath("following-sibling::li[1]")

上面的代码首先使用driver.find_element_by_xpath()方法查找class属性为'example'的ul元素,然后使用ul_element.find_element_by_xpath()方法查找ul元素下面的第一个li元素,最后使用li_element.find_element_by_xpath("following-sibling::li[1]")方法查找li元素的后一个兄弟节点。

基本操作 [edit]

浏览器相关操作 [edit]

创建浏览器对象

driver = http://webdriver.xxx()

窗口最大化

maximize_window()

获取浏览器尺寸

get_window_size()

设置浏览器尺寸

set_window_size()

获取浏览器位置

get_window_position()

设置浏览器位置

set_window_position(x,y)

关闭当前标签/窗口

close()

关闭所有标签/窗口

quit()

页面相关操作 [edit]

请求某个url

driver.get(url)

刷新页面操作

refresh()

回退到之前的页面

back()

前进到之后的页面

forward()

获取当前访问页面url

current_url

获取当前浏览器标题

title

保存图片

get_screenshot_as_png()/get_screenshot_as_file(file)

网页源码

page_source

元素的操作 [edit]

点击操作

element.click()

清空输入框

element.clear()

输入框输入数据 element.send_keys(data)

获取文本内容(既开闭标签之间的内容)

element.text

获取属性值

element = driver.find_element_by_id('user')
print(element.get_attribute('class'))
element = driver.find_element_by_class_name('input')
print(element.get_attribute('value'))

获取 HTML 内容(整个元素 HTML 或 元素内部的 HTML):

element = driver.find_element_by_id('id')
print(element.get_attribute('outerHTML'))	// 获取整个元素对应的 HTML
print(element.get_attribute('innerHTML'))	// 获取元素内部分HTML

鼠标和键盘操作 [edit]

鼠标操作需要导入类,见第一部分,然后创建对象ActionChains(driver),键盘操作导入类

鼠标右击 el = driver.find_element_by_xxx(value) context_click(el)

鼠标双击 el = driver.find_element_by_xxx(value) ActionChains(driver).double_click(el).perform()

鼠标悬停 el = driver.find_element_by_xxx(value) ActionChains(driver).move_to_element(el).perform()

常用键盘操作 [edit]

send_keys(Keys.BACK_SPACE)

删除键(BackSpace)

send_keys(Keys.SPACE)

空格键(Space)

send_keys(Keys.TAB)

制表键(Tab)

send_keys(Keys.ESCAPE)

回退键(Esc)

send_keys(Keys.ENTER)

回车键(Enter)

send_keys(Keys.CONTROL,‘a’)

全选(Ctrl+A)

send_keys(Keys.CONTROL,‘c’)

复制(Ctrl+C)

send_keys(Keys.CONTROL,‘x’)

剪切(Ctrl+X)

send_keys(Keys.CONTROL,‘v’)

粘贴(Ctrl+V)

弹出框操作 [edit]

进入到弹出框中

driver.switch_to.alert()

接收警告

accept()

关闭警告

dismiss()

发送文本到警告框 send_keys(data)

下拉框操作 [edit]

将定位到的下拉框元素传入Select类中

selobj = Select(element)

通过索引选择,index 索引从 0 开始

select_by_index()

通过值选择(option标签的一个属性值)

select_by_value()

通过文本选择(下拉框的值)

select_by_visible_text()

查看所有已选

all_selected_options

查看第一个已选

first_selected_option

查看是否是多选

is_multiple

查看选项元素列表

options

取消选择

deselect_by_index() /deselect_by_value()/ deselect_by_visible_text()

滚动条操作 [edit]

x为水平拖动距离,y为垂直拖动举例

js = "window.scrollTo(x,y) "
driver.execute_script(js)
js= “var q=document.documentElement.scrollTop=n” n为从顶部往下移动滚动举例
driver.execute_script(js)

cookies操作 [edit]

获取所有cookies

get_cookies()

获取key对应的值

get_cookie(key)

设置cookies

add_cookie(cookie_dict)

删除指定名称的cookie

delete_cookie(name)

删除所有cookie

delete_all_cookies()

多标签/多窗口、多表单/多框架切换 [edit]

多表单/多框架切换

直接使用id值切换进表单

driver.switch_to.frame(value)

定位到表单元素,再切换进入

el = driver.find_element_by_xxx(value)
driver.switch_to.frame(el)

跳回最外层的页面

driver.switch_to.default_content()

跳回上层的页面

driver.switch_to.parent_frame()

多标签/多窗口之间的切换

获取所有窗口的句柄

handles = driver.window_handlers

通过窗口的句柄进入的窗口

driver.switch_to.window(handles[n])

例程 [edit]

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.keys import Keys
import time
 
class SeleniumHelper:
    def __init__(self, driver):
        self.driver = driver
 
    def find_element(self, locator, timeout=10):
        """
        查找单个元素
        :param locator: 元素定位信息,如(By.ID, 'element_id')
        :param timeout: 超时时间,默认为10秒
        :return: WebElement对象或None
        """
        try:
            element = WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located(locator)
            )
            return element
        except (TimeoutException, NoSuchElementException):
            return None
 
    def find_elements(self, locator, timeout=10):
        """
        查找多个元素
        :param locator: 元素定位信息,如(By.CLASS_NAME, 'element_class')
        :param timeout: 超时时间,默认为10秒
        :return: WebElement对象列表或空列表
        """
        try:
            elements = WebDriverWait(self.driver, timeout).until(
                EC.presence_of_all_elements_located(locator)
            )
            return elements
        except (TimeoutException, NoSuchElementException):
            return []
 
# Edge浏览器 https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
s=Service('F:\Temp\edgedriver_win64\msedgedriver.exe')
options = webdriver.EdgeOptions()
options.use_chromium = True
# 屏蔽inforbar
options.add_experimental_option('useAutomationExtension', False)
options.add_experimental_option('excludeSwitches', ['enable-automation', 'enable-logging'])
options.add_argument("start-maximized")
# options.add_argument('--headless')
options.binary_location=r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
driver = webdriver.Edge(service=s, options=options)
driver.get('https://www.baidu.com')
# 创建SeleniumHelper对象
helper = SeleniumHelper(driver)
search_box = helper.find_element((By.ID, 'kw'))
if search_box:
    search_box.send_keys("aaaaaa")
    search_box.send_keys(Keys.RETURN)
time.sleep(6)
#driver.quit()

Troubleshooting [edit]

pip install win32api [edit]

ERROR: Could not find a version that satisfies the requirement win32api (from versions: none)
ERROR: No matching distribution found for win32api

使用pip install pypiwin32 安装成功

E:\python>pip install pypiwin32

button is not clickable at point [edit]

错误现象

selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <button type="button" class="lvc2-grey-btn" elementtiming="element-timing">...</button> is not clickable at point (569, 903). Other element would receive the click: <div class="index-module__goodsFooterContainer___3poOW " elementtiming="element-timing" style="left: 526.156px; width: 621.328px;">...</div>
  (Session info: MicrosoftEdge=115.0.1901.183)

原因有四种可能性

  1. 没加载出来就等待元素加载出来,再往下执行。最好还是使用selenium自带WebDriverWait
  2. 如果元素在iframe里,在窗口里找是找不到元素的,更是无法点击。所以,要切换到iframe里去找元素。
  3. 不在视窗里,需要拉滚动条
  4. 要点击的元素被覆盖
  5. 要点击的元素被遮挡

find_element_by_id 找不到要素的处理 [edit]

import unittest
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException    #导入NoSuchElementException

class ExceptionTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.get("https://www.baidu.com")

    def test_exception(self):
        driver = self.driver
        try:
            search_text = driver.find_element_by_id("ss")
            self.assertEqual('百度一下', search_text.get_attribute("value"))
        except NoSuchElementException:

コメント:



(画像の文字列を入力して下さい)

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS