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()
    
  • 相关阅读:
    取得窗口大小和窗口位置兼容所有浏览器的js代码
    一个简单易用的导出Excel类
    如何快速启动chrome插件
    网页表单设计案例
    Ubuntu下的打包解包
    The source file is different from when the module was built. Would you like the debugger to use it anyway?
    FFisher分布
    kalman filter
    Group delay Matlab simulate
    24位位图格式解析
  • 原文地址:https://www.cnblogs.com/NFii/p/11693290.html
Copyright © 2011-2022 走看看