zoukankan      html  css  js  c++  java
  • python

    为什么要使用Selenium?

    很多浏览器渲染页面的方式都很难找出其规律, 但是利用Selenium来驱动加载网页就可以直接拿到javaScript渲染后的结果了, 不需要再担心其相关的加密系统


    声明浏览器对象

    from selenium import webdriver
    browser = webdriver.Chrome()
    browser = webdriver.Firefox()
    browser = webdriver.Edge()
    browser = webdriver.PhantomJS()
    browser = webdriver.Safari()
    

    访问页面 -> get()

    browser.get("页面网址")
    print(browser.page_source())
    browser.close()
    

    获取单个节点 -> find_element() [只能获取单个节点]

    input_first = browser.find_element_by_id('q')
    input_second = browser.find_element_by_css_selector('#q')
    input_third = browser.find_element_by_xpath('//*[@id="q"]')
    print(input_first, input_second, input_third)
    

    更通用的方式 -> find_element()

    • 传入两个参数: 查找方式By和值
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    
    # 两者完全一致
    browser = webdriver.Chrome()
    browser.get('https://www.taobao.com/')
    input_first = browser.find_element(By.ID, 'q')
    input_afirst = browser.find_element_by_id('q')
    print(input_first)
    print(input_afirst)
    browser.close()
    

    获取多个节点

    在楼上的基础上, 每一个element后面都跟上一个s
    eg:
    find_elements_by_id()
    find_elements()


    节点交互

    1. 输入文字 -> send_keys()
    2. 清空文字 -> clear()
    3. 点击按钮 -> click()
    
    browser = webdriver.Chrome()
    browser.get('https://www.taobao.com/')
    input = browser.find_element_by_id('q')
    # send_keys() -> 输入文字
    input.send_keys('iPhone')
    time.sleep(1)
    # 清空输入的文字
    input.clear()
    input.send_keys('iPad')
    button = browser.find_element_by_class_name('btn-search')
    button.click()
    

    动作链 -> ActionChain()

    比如: 鼠标的拖拽、键盘按键等等

    browser = webdriver.Chrome()
    url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
    browser.get(url)
    browser.switch_to.frame('iframeResult')
    source = browser.find_element_by_css_selector('#draggable')
    target = browser.find_element_by_css_selector('#droppable')
    actions = ActionChains(browser)
    # .drag_and_drop()方法指定要拖拽的节点和拖拽的目标结点
    actions.drag_and_drop(source, target)
    # perform()方法才是真正的执行动作
    actions.perform()
    

    JavaScript -> execute_script('执行js代码')

    模拟下拉进度条

    browser = webdriver.Chrome()
    url = 'https://www.zhihu.com/explore'
    browser.get(url)
    # 利用execute_script('执行相关的js代码')
    browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    browser.execute_script('alert("To Bottom")')
    

    获取节点信息

    1. 获取属性 -> get_attribute()
    2. 获取文本值 -> text()
    3. 获取其他属性 -> 获取id(id) / 位置(location) / 标签名(tag_name) / 大小(size), 直接使用对应的属性即可

    切换Frame

    Iframe就是子Frame, 相当于页面的子页面
    Selenium打开页面后, 默认是在父级的Frame里面操作, 如果此时页面中还有子Frame是获取不到子Frame中的节点的, 所以就使用switch_to.frame()方法来切换Frame

    browser = webdriver.Chrome()
    url = 'http://runoob.com/try/try.php?filename=jqueryui-api-droppable'
    browser.get(url)
    # 切换frame, 同时页面中iframe的id为iframeResult
    browser.switch_to.frame('iframeResult')
    try:
        logo = browser.find_element_by_class_name('logo')
    except NoSuchElementException:
        print('NO LOGO')
    # 再次切换到父级的frame中去
    browser.switch_to.parent_frame()
    logo = browser.find_element_by_class_name('logo')
    print(logo)
    print(logo.text)
    

    当页面中包含子Frame时, 如果想要获取子Frame中的节点的时候, 首先需要调用switch_to.frame('iframe的id名'), 再进行相应的操作的.

    想要再次切换回原始的父级Frame使用 -> browser.switch_to.parent_frame()


    延时等待

    selenium中, get()方法会在网页框架结束后结束执行, 此时去获取page_source可能并不是浏览器完全加载完成出来的页面, 如果某些页面有额外的Ajax请求, 在网页的源代码中也不一定能成功获取到. 所以需要延时等待一定时间, 确保节点以及被加载出来了.

    等待分为两种:

    1. 隐式等待
    2. 显示等待
    隐式等待

    使用隐式等待, 则selenium在DOM中找到节点时, 将会继续进行等待, 等待一段时间后在查找DOM, 直到超出设定的时间.

    browser.implicitly_wait(10)
    
    显式等待

    隐式等待, 我们只能固定等待时间, 但是页面的加载时受到网络影响的, 所以其实效果并不太好.

    显式等待:
    指定要查找的结点, 然后指定一个最长的等待时间(^{1})和等待条件(^{2}), 如果到了规定时间仍没有加载出该节点就抛出超时异常.
    (这和隐式等待有什么区别...?)

    # 显示等待主要用到的是这几个
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    
    browser = webdriver.Chrome()
    browser.get("https://www.taobao.com/")
    # 设定等待时间
    wait = WebDriverWait(browser, 10)
    # 调用until()方法
    # EC.presence_of_element_located()表示节点出现 -> 内部是元组类型
    input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
    # element_to_be_clickable就是可点击
    button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
    
    等待条件

    image.png
    image.png

    显隐对比
    显式 隐式
    等到某种等待条件出现, 如果超出设定时间仍未出险, 则抛出异常 如果在DOM找不到元素, 则在隐式等待期间内, 每隔一段时间再去寻找, 直至超设定时间, 抛出异常
    抛出的异常为抛出异常TimeoutException 抛出的异常为NoSuchElementException

    前进和后退

    使用到的方法:

    • back() -> 页面后退, 回退到进入该页面前的页面
    • forward() -> 页面前进, 进入该页面后又进入的最新页面
    import time
    from selenium import webdriver
    browser = webdriver.Chrome()
    browser.get('https://www.baidu.com/')
    browser.get('https://www.taobao.com/')
    browser.get('https://www.zhihu.com/explore')
    browser.back()  # 模拟页面的回退, 从知乎发现回退到淘宝页面
    time.sleep(1)
    browser.forward()  # 模拟页面的前进, 从淘宝页面又前进到知乎发现了
    browser.close()
    

    Cookies

    使用到的方法:

    1. 获取Cookies -> browser.get_cookies()
    2. 添加Cookies -> browser.add_cookie({字典类型})
    3. 删除所有cookies (方法如其名, 最后就只剩下了一个空列表) -> browser.delete_all_cookies()
    from selenium import webdriver
    browser = webdriver.Chrome()
    browser.get('https://www.zhihu.com/explore')
    # 获取cookie
    print(browser.get_cookies())
    # 添加cookie
    browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'germey'})
    print(browser.get_cookies())
    # 删除所有cookie
    browser.delete_all_cookies()
    print(browser.get_cookies())
    

    选项卡管理

    [1] 选项卡是什么?
    就是平时用浏览器的时候, 切换页面点击的那个小长方形.

    [2] 使用到的方法:

    1. execute_script('window.open()') -> 利用js打开一个新选项卡
    2. 切换选项卡 -> switch_to.window()
    3. 获取所有选项卡 -> browser.window_handles 注意这个window_handles是一个属性而不是一个方法.
    import time
    from selenium import webdriver
    browser = webdriver.Chrome()
    '''
    工作流程为:
        打开百度页面, 执行js的window.open()打开一个新的选项卡, 获取所有的选项卡,
    利用switch_to.window()方法切换到当前页面的下一个选项卡, 也就是刚才打开的新选项卡, 在该选项卡中,
    打开淘宝页面, 停留一秒, 再次切换回初始的百度页面选项卡, 在该页面中打开知乎发现界面
    '''
    browser.get('https://www.baidu.com')
    # window.open()表示利用js新开启一个选项卡
    browser.execute_script('window.open()')
    # browser.window_handles是什么?
    # window_handles获取当前所有开启的选项卡, 返回的是选项卡的带好列表
    print(browser.window_handles)
    # switch_to_window()方法用来切换选项卡
    browser.switch_to.window(browser.window_handles[1])
    # 在browser.window_handles[1]选项卡下打开淘宝页面
    browser.get("https://www.taobao.com")
    time.sleep(1)
    browser.switch_to.window(browser.window_handles[0])
    browser.get("https://www.zhihu.com/explore")
    

    异常处理

    import time
    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException, NoSuchElementException
    
    browser = webdriver.Chrome()
    try:
        browser.get('https://www.baidu.com')
    except TimeoutError:
        print('超时')
    try:
        browser.find_element_by_id('hello')
    except NoSuchElementException:
        print('没有该元素')
    finally:
        browser.close()
    

    不打开浏览器

    每次运行selenium都要自动打开浏览器, 很烦

    # 重点在下面的三句, 这样就不会弹出浏览器窗口
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    browser = webdriver.Chrome(options=chrome_options)
    browser.get("https://www.baidu.com/")
    print(browser.find_element_by_id("su").get_attribute("value"))
    

    简单的操作实例

    """
    进入百度页面, 填写搜索信息(python), 点击搜索按钮, 将下拉框拉到底, 停留几秒, 回退到百度初始页面, 同时包含异常处理
    """
    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException, NoSuchElementException
    import time
    # 初始化
    driver = webdriver.Chrome()
    try:
        # 进入百度页面
        driver.get("https://www.baidu.com/")
    except TimeoutException:
        print("超时")
    try:
        # 找到输入框
        kw = driver.find_element_by_css_selector("#kw")
    except NoSuchElementException:
        print("找不到该元素")
    finally:
        # 输入关键字
        kw.send_keys("Python")
        time.sleep(5)
    try:
        # 找到搜索按钮
        button = driver.find_element_by_css_selector("#su")
    except NoSuchElementException:
        print("找不到该元素")
    finally:
        # 点击搜索
        button.click()
        time.sleep(3)
        # 将下拉框拉到底
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
        time.sleep(3)
        # 回退到初始页面
        driver.back()
        time.sleep(3)
        # 关闭浏览器
        driver.close()
    
  • 相关阅读:
    Eclipse对printf()不能输出到控制台的解决方法
    Eclipse launch failed.Binary not found解决方案
    Windows 7中使用Eclipse 使用CDT and WinGW 开发C/C++(转载)
    assets
    方法对头,报表模板维护其实很简单
    刷机包各个文件都是啥
    开机logo切换逻辑深入研究
    不同分辨率的LCM进行兼容
    SD卡驱动分析(二)
    SD卡驱动分析(一)
  • 原文地址:https://www.cnblogs.com/NFii/p/11693290.html
Copyright © 2011-2022 走看看