阅读 25876

Selenium 使用手册

一、安装及环境配置

如果要使用selenium,需要下载chrome及对应系统、对应浏览器版本的chromedriver
pip安装:pip install selenium

二、基本使用

2.1 启动及配置

# 普通启动

from selenium import webdriver

# 1. 实例化一个浏览器
browser = webdriver.Chrome("./chromedriver")  # 参数为驱动路径

browser.get("http://www.baidu.com/")  # 驱动浏览器访问百度

browser.page_source  # 获取当前浏览器的html

browser.quit()  # 退出实例化的浏览器
复制代码
# 包含配置信息启动

from selenium import webdriver

# 配置
options = webdriver.ChromeOptions()
options.add_argument('--headless')  # 增加无界面选项
options.add_argument('--disable-gpu')  # 如果不加这个选项,有时定位会出现问题
options.add_argument('--user-data-dir=/Users/mac/Library/Application Support/Google/Chrome/Default')  # 设置成用户自己的数据目录

# 实例化一个浏览器对象,并加载配置
browser = webdriver.Chrome(executable_path="./chromedriver", options=options)

browser.get("http://www.baidu.com/")  # 驱动浏览器访问百度

browser.page_source  # 获取当前浏览器的html

browser.quit()  # 退出实例化的浏览器
复制代码

2.2 基本浏览器动作

# 定位

browser.find_element_by_id("id")  # 通过id定位
browser.find_element_by_name("name")  # 通过name定位
browser.find_element_by_class_name("class_name")  # 通过classname定位
browser.find_element_by_tag_name("input")  # 通过tag标签定位
browser.find_element_by_xpath("//input[@id='kw']")  # 通过xpath定位
browser.find_element_by_css_selector("#kw")  # 通过CSS方式定位
复制代码
# 等待

# 1.强制等待x秒
time.sleep(10)  # 强制程序休眠10s

# 2.每次都等到浏览器全部加载完成
browser.implicitly_wait(30)  # 隐式等待,参数为最长等待时间(s)。页面全部加载完成才会执行下一步操作。
# 需要注意的是,browser.implicitly_wait(30)是为全局设置最长30s的等待时间。

# 3.等到自己需要的元素出现或者自己不需要的元素消失
from selenium.webdriver.support.wait import WebDriverWait

WebDriverWait(browser, 30).until(EC.title_is("百度一下,你就知道"))  # 等待,直到标题是百度一下,或超时
WebDriverWait(browser, 30).until(EC.title_contains("百度"))  # 等待,直到标题包含百度,或超时
WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.ID, "id")))  # 等待,直到Dom中存在该id
WebDriverWait(browser, 30).until(EC.visibility_of_element_located((By.ID, "id")))  # 等待,直到Dom中存在该id并且可见
WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]")))  # 等待,直到该元素是可点击的
WebDriverWait(browser, 30).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'.main'),'enable'))  # 判断.main中是否包含enable字符串,返回布尔值
WebDriverWait(browser, 30).until(EC.staleness_of(driver.find_element(By.ID,'id')))  # 等待,直到id从dom中移除
复制代码
# 行为

browser.maximize_window()  # 浏览器最大化
browser.minimize_window()  # 浏览器最小化
browser.set_window_size(480, 800)  # 自定义浏览器窗口大小
browser.forword()  # 浏览器前进
browser.back()  # 浏览器后退
browser.close()  # 关闭浏览器当前窗口
browser.quit()  # 退出浏览器驱动并关闭所有窗口
browser.refresh()  # 刷新当前页
browser.page_source  # 获取当前页html
browser.title  # 获取当前页标题
browser.url  # 获取当前页url

browser.find_element_by_name("name").click()  # 点击对象
browser.find_element_by_name("name").send_keys("keyword")  # 模拟键盘输入
browser.find_element_by_name("name").clear()  # 清除对象的内容
browser.find_element_by_name("name").submit()  # 提交对象的内容
browser.find_element_by_name("name").text()  # 获取元素的文本信息
browser.find_element_by_name("name").context_click()  # 右键单击
browser.find_element_by_name("name").double_click()  # 双击
browser.find_element_by_name("name").is_displayed()  # 是否用户可见


# 模拟键盘事件
from selenium.webdriver.common.keys import Keys
browser.find_element_by_id("user_pwd").send_keys(Keys.ENTER)  # 通过定位密码框,enter(回车)来代替登陆按钮
browser.find_element_by_id("login").send_keys(Keys.ENTER)  # 点击回车登陆(替代click),和上面效果一样
browser.find_element_by_name("name").send_keys(Keys.CONTROL, "a")  # 模拟ctrl+a
复制代码
# iframe

browser.switch_to_frame("f1")  # 找到 f1 iframe
browser.switch_to_window("f1")  # 找到内嵌窗口 f1
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
复制代码

三、其他使用

# 操作cookie

browser.get_cookie("name")  # 根据name获取单个cookie
browser.get_cookies()  # 获取所有cookie
browser.delete_all_cookies()  # 删除所有cookies
browser.delete_cookie("name")  # 根据name删除对应cookie
browser.add_cookie({"k1": "v1", "k2": "v2"})  # 设置cookies
复制代码
# 获取截屏

browser.get_screenshot_as_file("/usr/download/down_image.png")  # 保存当前窗口截图
browser.get_screenshot_as_png()  # 获取当前png截图的二进制字符串
复制代码
# 获取窗口信息

browser.get_window_rect()  # 获取当前窗口xy坐标及当前窗口的高度和宽度
browser.get_window_position(windowHandle="current")  # 获取当前窗口的x,y坐标
browser.get_window_size(windowHandle="current")  # 获取当前窗口的高度和宽度
复制代码
# 多窗口切换

driver.get("http://example.com")  # 打开一个窗口
now_handle = drvier.current_window_handle  # 获取当前窗口句柄

driver.find_element_by_name('example').click()  # 点击某个元素打开新的窗口(target="_black"的元素)
all_handle = drvier.window_handles  # 获取所有窗口句柄
drvier.switch_to.window(now_handle)  # 切换为第一窗口
driver.close()  # 关闭当前窗口
复制代码
# 通过input上传附件
self.browser.find_element_by_xpath('//input[@class="file-selector-file"]').send_keys("/Users/mac/Documents/myspider/selenium_spider/test.mp4")  # 必须要用绝对路径
复制代码

3.1 切换标签页

每个标签页都有对应的窗口句柄,可以通过窗口句柄切换到对应的标签页。

# 1. 获取当前所有的标签页的句柄构成的列表
current_windows = driver.window_handles
 
# 2. 根据标签页句柄列表索引下标进行切换
driver.switch_to.window(current_windows[0])
复制代码

3.2 切换iframe

selenium操作iframe内容需要先switch_to到iframe,操作完成后需要切换回来

login_frame = driver.find_element_by_id('login_frame') # 根据id定位 frame元素
driver.switch_to.frame(login_frame) # 转向到该frame中

# 利用切换标签页的方式切出frame标签
windows = driver.window_handles
driver.switch_to.window(windows[0])
复制代码

3.3 cookie操作

# 获取cookie
cookies_dict = {cookie["name"]: cookie["value"] for cookie in driver.get_cookies()}

# 删除一个cookie
driver.delete_cookie("CookieName")

# 删除所有cookie
driver.delete_all_cookies()

# 添加一个cookie
add_cookie(cookie_dict)
复制代码

3.4 执行JS代码

script = 'window.scrollTo(0,document.body.scrollHeight)'

browser.execute_async_script(script, *args)  # 在当前的window/frame中异步执行JS代码
browser.execute_script(script, *args)  # 在当前的window/frame中同步执行JS代码

script: JS代码(str)
*args: 要传入js的参数(iterable)
复制代码

3.5 上传文件

通过input上传文件

self.browser.find_element_by_xpath('//input[@class="file-selector-file"]').send_keys("/Users/mac/Documents/myspider/selenium_spider/test.mp4")  # 必须要用绝对路径
复制代码

3.6 截图

browser.get_screenshot_as_file("/usr/download/down_image.png")  # 保存当前窗口截图
browser.get_screenshot_as_png()  # 获取当前png截图的二进制字符串
复制代码

3.7 鼠标事件


from selenium.webdriver.common.action_chains import ActionChains

 el = driver.find_element_by_name('tj_trnews')  # 目标元素

ActionChains(driver).context_click(el).perform()  # 右击目标元素
ActionChains(driver).double_click(el).perform()  # 双击目标元素

source = driver.find_element_by_id('lg')   # 目标元素原始位置
target = driver.find_element_by_id('kw')  # 拖动的目标位置
ActionChains(driver).drag_and_drop(source, target).perform()  # 拖动元素

ActionChains(driver).move_to_element(el).perform()  # 鼠标移动的目标元素上
ActionChains(driver).click_and_hold(el).perform()  # 移动到目标元素按下鼠标左键
复制代码

3.8 控制已打开的浏览器

.\chrome.exe --remote-debugging-port=6001 --user-data-dir="C:\ProgramFiles\Chrome"

def init_driver():
    options = webdriver.ChromeOptions()
    options.add_experimental_option("debuggerAddress", "127.0.0.1:6001")
    driver = webdriver.Chrome(options=options)
    return driver
复制代码

四、代码示例

4.1 初始化driver

#!/usr/bin/env python
# coding:utf-8
import time

from selenium import webdriver
from selenium.webdriver.support.select import Select


def chromedriver_demo():
    driver = webdriver.Chrome()

    driver.delete_all_cookies()

    driver.add_cookie({'name': 'ABC', 'value': 'DEF'})

    driver.get_cookies()

    driver.execute_script('window.open("https://www.baidu.com");')

    """
    // chrome地址栏命令
    about:version - 显示当前版本
   about:memory - 显示本机浏览器内存使用状况
   about:plugins - 显示已安装插件
   about:histograms - 显示历史记录
   about:dns - 显示DNS状态
   about:cache - 显示缓存页面
   about:gpu -是否有硬件加速
   about:flags -开启一些插件
   chrome://extensions/ - 查看已经安装的扩展

    // chrome参数 
    –user-data-dir=”[PATH]” 指定用户文件夹User Data路径,可以把书签这样的用户数据保存在系统分区以外的分区。
   –disk-cache-dir=”[PATH]“ 指定缓存Cache路径
   –disk-cache-size= 指定Cache大小,单位Byte
   –first run 重置到初始状态,第一次运行
   –incognito 隐身模式启动
   –disable-javascript 禁用Javascript
   –omnibox-popup-count=”num” 将地址栏弹出的提示菜单数量改为num个。我都改为15个了。
   –user-agent=”xxxxxxxx” 修改HTTP请求头部的Agent字符串,可以通过about:version页面查看修改效果
   –disable-plugins 禁止加载所有插件,可以增加速度。可以通过about:plugins页面查看效果
   –disable-javascript 禁用JavaScript,如果觉得速度慢在加上这个
   –disable-java 禁用java
   –start-maximized 启动就最大化
   –no-sandbox 取消沙盒模式
   –single-process 单进程运行
   –process-per-tab 每个标签使用单独进程
   –process-per-site 每个站点使用单独进程
   –in-process-plugins 插件不启用单独进程
   –disable-popup-blocking 禁用弹出拦截
   –disable-plugins 禁用插件
   –disable-images 禁用图像
   –incognito 启动进入隐身模式
   –enable-udd-profiles 启用账户切换菜单
   –proxy-pac-url 使用pac代理 [via 1/2]
   –lang=zh-CN 设置语言为简体中文
   –disk-cache-dir 自定义缓存目录
   –disk-cache-size 自定义缓存最大值(单位byte)
   –media-cache-size 自定义多媒体缓存最大值(单位byte)
   –bookmark-menu 在工具 栏增加一个书签按钮
   –enable-sync 启用书签同步
   –single-process 单进程运行Google Chrome
   –start-maximized 启动Google Chrome就最大化
   –disable-java 禁止Java
   –no-sandbox 非沙盒模式运行
    """


def init_driver(driver_path: str, timeout=20, user_agent: str = None, headless=False,
                proxy: str = None, binary_location: str = None, user_data_dir: str = None,
                crx_dir=None):
    chrome_options = webdriver.ChromeOptions()

    chrome_options.add_argument("blink-settings=imagesEnabled=false")  # 设置图片不加载
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("disable-infobars")  # 隐藏"Chrome正在受到自动软件的控制"
    chrome_options.add_argument("lang=zh_CN.UTF-8")  # 设置中文
    chrome_options.add_argument("window-size=1920x3000")  # 指定浏览器分辨率
    chrome_options.add_argument("--hide-scrollbars")  # 隐藏滚动条, 应对一些特殊页面
    chrome_options.add_argument("--remote-debugging-port=9222")
    # chrome_options.binary_location = r"/Applications/Chrome"  # 手动指定使用的浏览器位置

    if headless:
        chrome_options.add_argument("--headless")

    if not user_agent:
        user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.58"
        chrome_options.add_argument("user-agent=%s" % user_agent)

    if proxy:
        chrome_options.add_argument("proxy-server=%s" % proxy)

    if user_data_dir:
        chrome_options.add_argument("--user-data-dir=%s" % user_data_dir)

    if binary_location:
        chrome_options.binary_location = binary_location  # 手动指定使用的浏览器位置

    if crx_dir:
        chrome_options.add_extension(crx_dir)  # 自定义加载扩展crx

    driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=driver_path)
    driver.set_page_load_timeout(timeout)
    driver.set_script_timeout(timeout)
    return driver


def init_driver_with_exists_chrome():
    """
    Start Chrome:
    C:\Users\user\AppData\Local\Google\Chrome\Application\chrome.exe --remote-debugging-port=6001 --user-data-dir="C:\ProgramFiles\Chrome2"
    """
    options = webdriver.ChromeOptions()
    options.add_experimental_option("debuggerAddress", "127.0.0.1:6001")
    driver = webdriver.Chrome(options=options)
    return driver


def wait_html(driver):
    while 1:
        time.sleep(0.5)
        if "Certification" in driver.page_source:
            print("Success!!! Certification")
            break
        print("Certification")

    # pass. to do next


def auto_input(driver):
    # input keys
    driver.find_element_by_xpath('//input[@name="CMT_SSN_1"]').send_keys("")

    # click button 1
    driver.find_element_by_xpath('//input[@name="CCA_QUIT_IND"][@value="N"]').click()
    # click button 2 (with js)
    driver.execute_script("""
        var e = document.createEvent("MouseEvents");
        e.initEvent("click", true, true);
        document.getElementById("nextBtn").dispatchEvent(e);
        """)
    # click button 3
    element = driver.find_element_by_id('login')
    webdriver.ActionChains(driver).move_to_element(element).click(element).perform()

    # selection
    Select(driver.find_element_by_xpath('//select[@name="CMT_ID_TYPE_CD"]')).select_by_index(2)
    Select(driver.find_element_by_xpath('//select[@name="CWE_CONTACT_OUTCOME_CD_02"]')).select_by_value("3")


if __name__ == "__main__":
    driver_path = "spider_data/chromedriver.exe"
    init_driver(driver_path)

复制代码

五、参考文章

  1. Python+Selenium基础入门及实践
  2. python中selenium使用
  3. Selenium Webdriver常用方法
文章分类
后端
文章标签