selenium从源码讲用法

该资料在selenium源代码里面找的:selenium > webdriver > remote > webdriver.py

对浏览器的操作

打开浏览器的参数

# 源码:
def __init__(self, command_executor='http://127.0.0.1:4444/wd/hub',
             desired_capabilities=None, browser_profile=None, proxy=None,
             keep_alive=False, file_detector=None, options=None):
    """
        Create a new driver that will issue commands using the wire protocol.
		创建一个将使用wire协议发出命令的新驱动程序。
        :Args:
         - command_executor - Either a string representing URL of the remote server or a custom
             remote_connection.RemoteConnection object. Defaults to 'http://127.0.0.1:4444/wd/hub'.
         - desired_capabilities - A dictionary of capabilities to request when
             starting the browser session. Required parameter.
         - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object.
             Only used if Firefox is requested. Optional.
         - proxy - A selenium.webdriver.common.proxy.Proxy object. The browser session will
             be started with given proxy settings, if possible. Optional.
         - keep_alive - Whether to configure remote_connection.RemoteConnection to use
             HTTP keep-alive. Defaults to False.
         - file_detector - Pass custom file detector object during instantiation. If None,
             then default LocalFileDetector() will be used.
         - options - instance of a driver options.Options class
         
         -命令执行器-表示远程服务器URL的字符串或自定义远程_连接.远程连接对象。默认为'http://127.0.0.1:4444/wd/轮毂'。
         -所需的能力-一个字典的能力要求时正在启动浏览器会话。必需参数。
          -浏览器配置文件-Aselenium.webdriver.firefox.火狐_profile.FirefoxProfile文件对象。仅在请求Firefox时使用。可选。
           -代理-Aselenium.webdriver.common文件.代理。代理对象。浏览器会话将 如果可能,可以从给定的代理设置开始。可选。
           -保持激活-是否配置远程_连接.远程连接使用HTTP保持活动状态。默认为False。
           -文件检测器-在实例化期间传递自定义文件检测器对象。如果没有,然后将使用默认的LocalFileDetector()。
           -选项-驱动程序实例选项。选项班
        """

打开网页

driver.get(url)

返回当前页的标题

driver.title()

在当前页面同步执行js语法

# 源码:
def execute_script(self, script, *args):
    """
        Synchronously Executes JavaScript in the current window/frame.
		在当前窗口/帧中同步执行JavaScript。
        :Args:
         - script: The JavaScript to execute.
         - \*args: Any applicable arguments for your JavaScript.

        :Usage:  使用方法
            driver.execute_script('return document.title;')
        """
    converted_args = list(args)
    command = None
    if self.w3c:
        command = Command.W3C_EXECUTE_SCRIPT
        else:
            command = Command.EXECUTE_SCRIPT

            return self.execute(command, {
                'script': script,
                'args': converted_args})['value']

在当前页面异步执行js语法

# 源码:
def execute_async_script(self, script, *args):
    """
        Asynchronously Executes JavaScript in the current window/frame.
		在当前窗口/帧中异步执行JavaScript。
        :Args:
         - script: The JavaScript to execute.
         - \*args: Any applicable arguments for your JavaScript.

        :Usage:  使用方法
            script = "var callback = arguments[arguments.length - 1]; " \
                     "window.setTimeout(function(){ callback('timeout') }, 3000);"
            driver.execute_async_script(script)
        """
    converted_args = list(args)
    if self.w3c:
        command = Command.W3C_EXECUTE_SCRIPT_ASYNC
        else:
            command = Command.EXECUTE_ASYNC_SCRIPT

            return self.execute(command, {
                'script': script,
                'args': converted_args})['value']

获取当前页的 URL

driver.current_url()

获取当前页的源代码

driver.page_source()

切换到活动元素

# 源码:
def switch_to_active_element(self):
    """ Deprecated use driver.switch_to.active_element
        弃用driver.切换到.活动元素"""
    warnings.warn("use driver.switch_to.active_element instead",
                  DeprecationWarning, stacklevel=2)
    return self._switch_to.active_element

切换到iframe

iframe = driver.find_element_by_css_selector('iframe')
driver.switch_to.frame(iframe)

在浏览器历史记录中后退一步

driver.back()

在浏览器历史中向前迈进了一步

driver.forward()

刷新当前页面

driver.refresh()

隐式等待

隐形等待是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步。注意这里有一个弊端,那就是程序会一直等待整个页面加载完成,也就是一般情况下你看到浏览器标签栏那个小圈不再转,才会执行下一步,但有时候页面想要的元素早就在加载完成了,但是因为个别js之类的东西特别慢,我仍得等到页面全部完成才能执行下一步,我想等我要的元素出来之后就下一步怎么办?有办法,这就要看selenium提供的另一种等待方式——显性等待wait了。
需要特别说明的是:隐性等待对整个driver的周期都起作用,所以只要设置一次即可,我曾看到有人把隐性等待当成了sleep在用,走哪儿都来一下…

driver.implicitly_wait(30)  # 参数是秒数

设置页面异步js执行超时

driver.set_script_timeout(30)  # 参数是秒数

设置等待页面加载完成的时间量

在指定时间内页面还没加载完成时,就会停止加载。

driver.set_page_load_timeout(30)  # 参数是秒数

返回驱动程序当前使用的所需功能

driver.desired_capabilities()

获取设备的当前方向

orientation = driver.orientation

设置设备的当前方向

# 源码:
@orientation.setter
def orientation(self, value):
    """
        Sets the current orientation of the device

        :Args:
         - value: orientation to set it to.

        :Usage:
            driver.orientation = 'landscape'
        """
    allowed_values = ['LANDSCAPE', 'PORTRAIT']
    if value.upper() in allowed_values:
        self.execute(Command.SET_SCREEN_ORIENTATION, {'orientation': value})
        else:
            raise WebDriverException("You can only set the orientation to 'LANDSCAPE' and 'PORTRAIT'")
  • 注意:别见怪,这个方法确实和上一个方法的方法名相同,我也不知道为什么。

获取可用日志类型的列表

driver.log_types()

获取给定日志类型的日志

# 源码:
def get_log(self, log_type):
    """
        Gets the log for a given log type

        :Args:
         - log_type: type of log that which will be returned

        :Usage:
            driver.get_log('browser')
            driver.get_log('driver')
            driver.get_log('client')
            driver.get_log('server')
        """
    return self.execute(Command.GET_LOG, {'type': log_type})['value']

对浏览器窗口操作

关闭当前窗口

driver.close()

退出驱动程序并关闭所有相关窗口

driver.quit()

返回当前窗口的句柄

driver.current_window_handle()

返回当前会话中所有窗口的句柄

driver.window_handles()

窗口最大化

driver.maximize_window()

窗口全屏

driver.fullscreen_window()

窗口最小化

driver.minimize_window()

切换窗口

driver.switch_to.window(num)

窗口截图

# 源码:
def get_screenshot_as_file(self, filename):
    """
        Saves a screenshot of the current window to a PNG image file. Returns
           False if there is any IOError, else returns True. Use full paths in
           your filename.
		将当前窗口的屏幕截图保存到PNG图像文件中。退换商品如果存在任何IOError,则返回False。在中使用完整路径你的文件名。
        :Args:
         - filename: The full path you wish to save your screenshot to. This
           should end with a `.png` extension.

        :Usage:  使用方法
            driver.get_screenshot_as_file('/Screenshots/foo.png')
        """
    if not filename.lower().endswith('.png'):
        warnings.warn("name used for saved screenshot does not match file "
                      "type. It should end with a `.png` extension", UserWarning)
        png = self.get_screenshot_as_png()
        try:
            with open(filename, 'wb') as f:
                f.write(png)
                except IOError:
                    return False
                finally:
                    del png
                    return True

获取作为二进制数据的当前窗口的屏幕截图

driver.get_screenshot_as_png()

获取作为base64编码字符串的当前窗口的屏幕截图

获取作为base64编码字符串的当前窗口的屏幕截图这对HTML中的嵌入图像很有用。

driver.get_screenshot_as_base64()

设置当前窗口的宽度和高度

  • 宽度:以像素为单位设置窗口的宽度
  • 高度:要将窗口设置为的高度(以像素为单位)
driver.set_window_size(800,600)

获取当前窗口的宽度和高度

driver.get_window_size()

设置当前窗口的x、y位置。(窗口。移动到)

  • x: 用于设置窗口位置的x坐标(以像素为单位)
  • y: 设置窗口位置的y坐标(以像素为单位)
driver.set_window_position(0,0)

获取当前窗口的x,y位置

driver.get_window_position()

得到窗口的高度和宽度当前窗口。

driver.get_window_rect()

设置窗口的x、y坐标以及窗口的高度和宽度当前窗口

driver.set_window_rect(x=10, y=10)
driver.set_window_rect(width=100, height=200)
driver.set_window_rect(x=10, y=10, width=100, height=200)

cookie 操作

返回一组字典,对应于当前会话中可见的cookies

driver.get_cookies()

按名字查找cookie

按名字查找cookie。如果找到,则返回cookie;如果没有,则返回None。

driver.get_cookie('my_cookie')

删除具有指定名称的单个cookie

driver.delete_cookie('my_cookie')

删除会话范围内的所有Cookie

driver.delete_all_cookies()

使用 cookie

# 源码:
def add_cookie(self, cookie_dict):
    """
        Adds a cookie to your current session.
		将cookie添加到当前会话。
        :Args:
         - cookie_dict: A dictionary object, with required keys - "name" and "value";
            optional keys - "path", "domain", "secure", "expiry"

        Usage:
            driver.add_cookie({'name' : 'foo', 'value' : 'bar'})
            driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/'})
            driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure':True})

        """
    self.execute(Command.ADD_COOKIE, {'cookie': cookie_dict})
  • 注意:使用完之后要刷新一下才看到效果。

对DOM元素的操作

显式等待

  • '''隐式等待和显示等待都存在时,超时时间取二者中较大的'''
    

配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException。

WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

until  # 一直等到该元素出现为止
until_not# 一直等到该元素不见为止

WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
'''判断title,返回布尔值'''

WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))
'''判断title,返回布尔值'''

WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
'''判断某个元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement'''

WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su')))
'''判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0'''

WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))
'''判断元素是否可见,如果可见就返回这个元素'''

WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有1个元素存在于dom树中,如果定位到就返回列表'''

WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有一个元素在页面中可见,如果定位到就返回列表'''

WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'设置'))
'''判断指定的元素中是否包含了预期的字符串,返回布尔值'''

WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下'))
'''判断指定元素的属性值中是否包含了预期的字符串,返回布尔值'''

# WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))
'''判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False'''
# 注意这里并没有一个frame可以切换进去

WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap')))
'''判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素'''
# 注意#swfEveryCookieWrap在此页面中是一个隐藏的元素

WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click()
'''判断某个元素中是否可见并且是enable的,代表可点击'''
driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click()
# WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click()

# WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su')))
'''等待某个元素从dom树中移除'''
# 这里没有找到合适的例子

WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))
'''判断某个元素是否被选中了,一般用在下拉列表'''

WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''

WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''
driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()

定位元素

driver.find_element_by_id('foo')				 # 通过id查找元素。
driver.find_element_by_xpath('//div/td[1]')	       # 通过xpath查找元素。
driver.find_element_by_link_text('Sign In')  	   # 按链接文本查找元素。
driver.find_element_by_partial_link_text('Sign')   # 通过元素链接文本的部分匹配来查找元素。
driver.find_element_by_name('foo')				  # 通过name查找元素。
driver.find_element_by_tag_name('h1')			  # 通过标签查找元素。
driver.find_element_by_class_name('foo')   		   # 通过class查找元素。
driver.find_element_by_css_selector('#foo')  	   # 通过css查找元素。
  • 注意,定位元素中如果带s的,比如find_elements_by_id(),这个属于找到相关的所有元素,并以列表的形式放回。
# xpath定位技巧
find_element_by_xpath("//a[text()='我的素材']")  # 通过元素的文本定位元素。
find_element_by_xpath('//input[@placeholder="选择转化类型"]')  # 通过元素的属性值来定位元素。

以下方法都是通过先定位再指定的操作

获取标签名称

find_element_by_xpath().tag_name

获取标签文本

find_element_by_xpath().text

鼠标事件

find_element_by_xpath().click()

鼠标动作链

ActionChains 常用方法:
perform()  执行所有ActionChains 中存储的行为;
context_click()  右击;
double_click()   双击;
drag_and_drop()  拖动;
move_to_element()  鼠标悬停。
#定位到要双击的元素
qqq =driver.find_element_by_xpath("xxx") 
#对定位到的元素执行鼠标双击操作 
ActionChains(driver).double_click(qqq).perform()
#定位元素的原位置 
element = driver.find_element_by_name("source") 
#定位元素要移动到的目标位置 
target = driver.find_element_by_name("target")
#执行元素的移动操作 
ActionChains(driver).drag_and_drop(element, target).perform()

键盘操作

driver.find_element_by_id('kw').send_keys('selenium') #在搜索框中输入"selenium" 
driver.find_element_by_id('kw').send_keys(Keys.SPACE) #输入空格键
driver.find_element_by_id('kw').send_keys('python') #在搜索框中输入"python"
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a') #输入Control+a模拟全选
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'c') #输入Control+c模拟复制
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'v') #输入Control+v模拟粘贴
driver.find_element_by_id('kw').send_keys(Keys.ENTER) #输入回车代替点击搜索按钮

提交表单

find_element_by_xpath().submit

没用过

清空输入的文本

find_element_by_xpath().clear()

获取元素的属性

find_element_by_xpath().get_property('class')

获取元素的属性

此方法将首先尝试返回带有名字。如果具有该名称的属性不存在,则返回同名属性的值。如果没有属性返回名称“None”。

find_element_by_xpath().get_attribute('class')

返回元素是否被选中

场景:返回元素是否被选中。可用于检查是否选中了复选框或单选按钮。

find_element_by_xpath().is_selected()

返回元素是否已启用

find_element_by_class_name().is_enabled()

上传文件或者输入文本

find_element_by_class_name().send_keys()

1、input标签上传

driver.find_element_by_xpath('').send_keys('文件的绝对路径')
  • 可以使用下面代码来输出本地文件,以列表的形式
import os
filePath = 'D:\\视频'
for dirpath, dirnames, filenames in os.walk(filePath):
    path = [os.path.join(dirpath, names) for names in filenames]
    print(path)

2、控制win窗口上传

import win32gui
import win32con

# Chrome browser
def upload_file(file_path):
    # 一级窗口
    no1 = win32gui.FindWindow("#32770","打开")
    # 二级窗口,4个参数:父级;从父级的第几个儿子开始检索,0表示第一个;自身类名;文本内容,没有则None
    combo_box_ex32 = win32gui.FindWindowEx(no1, 0, "ComboBoxEx32", None)
    # 3级窗口
    combo_box = win32gui.FindWindowEx(combo_box_ex32,0,"ComboBox",None)
    # 4级窗口
    edit = win32gui.FindWindowEx(combo_box,0,"Edit",None)
    # 二级打开按钮
    button = win32gui.FindWindowEx(no1, 0, "Button", "打开(&O)")
    # 输入文件地址
    win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, file_path)
    # 点击打开按钮 提交文件
    win32gui.SendMessage(no1, win32con.WM_COMMAND, 1, button)

upload_file("C:\\1\\nihao.7z")

这个是点击了上传,弹出win窗口选择文件那个的

元素对用户是否可见

find_element_by_class_name().is_displayed()

返回元素的x,y位置

# 源码:
@property
def location_once_scrolled_into_view(self):
    """THIS PROPERTY MAY CHANGE WITHOUT WARNING. Use this to discover
        where on the screen an element is so that we can click it. This method
        should cause the element to be scrolled into view.

        Returns the top lefthand corner location on the screen, or ``None`` if
        the element is not visible.
		此属性可能会在没有警告的情况下更改。用这个来发现
        屏幕上某个元素的位置,以便我们可以单击它。这种方法
        应使元素滚动到视图中。
        返回屏幕左上角的位置,如果
        元素不可见。
        """
    if self._w3c:
        old_loc = self._execute(Command.W3C_EXECUTE_SCRIPT, {
            'script': "arguments[0].scrollIntoView(true); return arguments[0].getBoundingClientRect()",
            'args': [self]})['value']
        return {"x": round(old_loc['x']),
                "y": round(old_loc['y'])}
    else:
        return self._execute(Command.GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW)['value']
find_element_by_id('su').location_once_scrolled_into_view
输出:{'x': 821, 'y': 199}

返回元素的大小

元素的大小,就是css写的那个标签占位置大小。

find_element_by_id('su').size
输出:{'height': 44, 'width': 108}

返回包含元素大小和位置的字典

find_element_by_id('su').rect
输出:{'height': 44, 'width': 108, 'x': 844, 'y': 199.421875}

以base64编码字符串的形式获取当前元素的屏幕截图

find_element_by_id('su').screenshot_as_base64
输出:
iVBORw0KGgoAAAANSUhEUgAAAGwAAAAsCAYAAACAPl2hAAAAAXNSR0IArs4c6QAAAqVJREFUeJztmz9s2kAUh38m5U9qPISlUsWaoQtLB6RMWVgLrN6Yg8qKIjEhVayWYM7mtb2ZhSkSK2tXFpZUAhxIGqCDgboEgwMc9ivv23y27w59d/fenYXy5Wt/BuagCEOTVndIWs2MFFgYMVgYMVgYMVgYMVgYMVgYMVgYMVgYMVgYMVgYMVgYMVgYMQgKi6Ba0yBuY353xBeUQ39eyRXjKFwqO79v/XyCXn/e/ND1e5j5M/xqD3Bj7tzUVvb9LTI4uLCN6CpEGmiWLNS3PhxDwwgjuUMznqTvhd23C5d2ZH4Peyet5jXkEgrQe/Ega8EMne9DVFoSO0WMI8awCD4nFVj96c7vV2saGvpqeQwNY135/4mkGRZBtRZF6nzNrcsohBF9XT6a4K78iB8rxYmrOETeEUfSGkR6Tb2O8q7k2OYnUpdEr7EkV4yj4BKsHu6HuGkBi0GQ6KzKsOMJ/JCUjEAY0aMOkKPGsEOQdJlh3ZXr4q2GzIc9GnKZ8U7U/guynTOItAaR2v78IQiusOsQLgA8LAueUSl7z/zq3wZvSG52w+pPAXOMrGnP/oKhIdMeSG1TqjDVLV6tY+R2w3t6Lz+dd2M+mHQVIi0vpQeCHMM+KlAxQ681RqU13rCHWyQ4U9z7IsuBaSFrxiCMsLQmArskvtqzmRayUCEMDVfzgbA8iej9RrY89rO7DsYATk7YfM/WXdmzmdYyXthL7RTN0lB6rAoSwRSmh5E6n6LpXOLm54cqAFvUBJ+MMDKGhswJnYgEMOmIoJoKodseoO6UNJrgrjT4N20ujf++U9Mg8vaVf8mHfAKYdDjT90fonmbN21J+yhz3tP5E4H+vMEtYGDFYGDFYGDFYGDFYGDFYGDFYGDFYGDFYGDFYGDFYGDFYGDH+AJBc9OyJKSz1AAAAAElFTkSuQmCC

获取作为二进制数据的当前元素的屏幕截图

find_element_by_id('su').screenshot_as_png
输出:
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00l\x00\x00\x00,\x08\x06\x00\x00\x00\x80>]\xa1\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x02\xa5IDATx\x9c\xed\x9b?l\xda@\x14\x87\x7f&\xe5Oj<\x84\xa5R\xc5\x9a\xa1\x0bK\x07\xa4LYX\x0b\xac\xde\x98\x83\xca\x8a"1!U\xac\x96`\xce\xe6\xb5\xbd\x99\x85)\x12+kW\x16\x96T\x02\x1cH\x1a\xa0\x83\x81\xba\x04\x83\x03\x1c\xf6+\xef\xdb|\xb6\xef\x0e}w\xf7\xde\x9d\x85\xf2\xe5k\x7f\x06\xe6\xa0\x08C\x93VwHZ\xcd\x8c\x14X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181\x08\n\x8b\xa0Z\xd3 nc~w\xc4\x17\x94C\x7f^\xc9\x15\xe3(\\*;\xbfo\xfd|\x82^\x7f\xde\xfc\xd0\xf5{\x98\xf93\xfcj\x0fpc\xee\xdc\xd4V\xf6\xfd-28\xb8\xb0\x8d\xe8*D\x1ah\x96,\xd4\xb7>\x1cC\xc3\x08#\xb9C3\x9e\xa4\xef\x85\xdd\xb7\x0b\x97vd~\x0f{\'\xad\xe65\xe4\x12\n\xd0{\xf1 k\xc1\x0c\x9d\xefCTZ\x12;E\x8c#\xc6\xb0\x08>\'\x15X\xfd\xe9\xce\xefWk\x1a\x1a\xfajy\x0c\rc]\xf9\xff\x89\xa4\x19\x16A\xb5\x16E\xea|\xcd\xad\xcb(\x84\x11}]>\x9a\xe0\xae\xfc\x88\x1f+\xc5\x89\xab8D\xde\x11G\xd2\x1aDzM\xbd\x8e\xf2\xae\xe4\xd8\xe6\'R\x97D\xaf\xb1$W\x8c\xa3\xe0\x12\xac\x1e\xee\x87\xb8i\x01\x8bA\x90\xe8\xac\xca\xb0\xe3\t\xfc\x90\x94\x8c@\x18\xd1\xa3\x0e\x90\xa3\xc6\xb0C\x90t\x99a\xdd\x95\xeb\xe2\xad\x86\xcc\x87=\x1ar\x99\xf1N\xd4\xfe\x0b\xb2\x9d3\x88\xb4\x06\x91\xda\xfe\xfc!\x08\xae\xb0\xeb\x10.\x00<,\x0b\x9eQ){\xcf\xfc\xea\xdf\x06oHnv\xc3\xeaO\x01s\x8c\xaci\xcf\xfe\x82\xa1!\xd3\x1eHmS\xaa0\xd5-^\xadc\xe4v\xc3{z/?\x9dwc>\x98t\x15"-/\xa5\x07\x82\x1c\xc3>*P1C\xaf5F\xa55\xde\xb0\x87[$8S\xdc\xfb"\xcb\x81i!k\xc6 \x8c\xb0\xb4&\x02\xbb$\xbe\xda\xb3\x99\x16\xb2P!\x0c\rW\xf3\x81\xb0<\x89\xe8\xfdF\xb6<\xf6\xb3\xbb\x0e\xc6\x00NN\xd8|\xcf\xd6]\xd9\xb3\x99\xd62^\xd8K\xed\x14\xcd\xd2Pz\xac\n\x12\xc1\x14\xa6\x87\x91:\x9f\xa2\xe9\\\xe2\xe6\xe7\x87*\x00[\xd4\x04\x9f\x8c02\x86\x86\xcc\t\x9d\x88\x040\xe9\x88\xa0\x9a\n\xa1\xdb\x1e\xa0\xee\x944\x9a\xe0\xae4\xf87m.\x8d\xff\xbeS\xd3 \xf2\xf6\x95\x7f\xc9\x87|\x02\x98t8\xd3\xf7G\xe8\x9ef\xcd\xdbR~\xca\x1c\xf7\xb4\xfeD\xe0\x7f\xaf0KX\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181X\x181\xfe\x00\x90\\\xf4\xec\x89),\xf5\x00\x00\x00\x00IEND\xaeB`\x82'

将元素截图下来保存到本地

find_element_by_id('su').screenshot('1.png')

而且这个还可以有返回值的,返回值为布尔值。

处理 js 弹出对话框

对话框有三种:alert,confirm,prompt。

操作方法:

driver.switch_to.alert.accept()      #点击OK
driver.switch_to.alert.text      # 得到对话框内容
driver.switch_to.alert.dismiss()   # 点击取消
driver.switch_to.alert.send_keys()   # 输入内容

例子:

# 针对这种对话框,python提供了一种方式,alert
#触发alert
driver.find_element_by_id('b1').click()
#切换到alert框上面
al = driver.switch_to.alert
#获取alert框上面的信息
print(al.text)
#使用accept方法点击“确定”
al.accept()

小技巧/现成方法

增加标签属性

刷新 iframe

  • 场景,在 iframe 里面刷新当前的 iframe。
classname = 'bui-input bui-input-with-suffix'  # class值
js = 'window.location.reload(true)'  # 需要增加的js语法
se_js = 'document.getElementsByClassName("{}")[0].setAttribute("onclick","{}")'.format(classname, js)
driver.execute_script(se_js)  # 执行

点击 bui-input bui-input-with-suffix 属性的标签,就可以出发这个js代码了

界面化打包

界面化打包exe,不显示黑窗口的,打包前要先去 selenium 源码(Lib/site-packages/selenium/webdriver/common/service.py)里修改一下源码:

# 浏览到第 72 行代码
# 原本是这样的===========================================
self.process = subprocess.Popen(cmd, env=self.env,
                                            close_fds=platform.system() != 'Windows',
                                            stdout=self.log_file,
                                            stderr=self.log_file,
                                            stdin=PIPE)
# 修改后是这样的=========================================
self.process = subprocess.Popen(cmd, env=self.env,
                                            close_fds=platform.system() != 'Windows',
                                            stdout=self.log_file,
                                            stderr=self.log_file,
                                            stdin=PIPE, creationflags=134217728)

进入iframe

iframe = driver.find_element_by_css_selector('iframe#qqoginFrame')
driver.switch_to.frame(iframe)

页面跳转

windows = driver.window_handles
driver.switch_to.window(windows[-1])

下拉框需要滑动的

test = driver.find_elements_by_css_selector('')  # 定位下拉框里的所有li标签
    overflow = 1
    for i in range(len(test)):
        if test[i].text:
            print(test[i].text)
            # if 'new4' in test[i].text:
            #     test[i].click()
        if not overflow % 8:  # 每看到8个元素就滑动1次
            driver.execute_script("arguments[0].scrollIntoView();", test[i])
        overflow += 1

滚动到可见元素

target = driver.find_element_by_xpath('')
driver.execute_script("arguments[0].scrollIntoView();", target)

使用 cookie

cookie_list = []
for cookie in cookie_list:
    driver.add_cookie(cookie)
driver.refresh()  # 使用之后记得刷新一下页面

设置浏览器参数

chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_experimental_option('excludeSwitches', ['enable-automation'])  # 开发者模式
chromeOptions.add_argument('log-level=3')  # 关闭日志
chromeOptions.add_argument('--headless')  # 隐藏浏览器
chromeOptions.add_argument('--disable-gpu')  # 如果不加这个选项,有时定位会出现问题
driver = webdriver.Chrome(chrome_options=chromeOptions)

反反机器人

option = webdriver.ChromeOptions()
option.add_experimental_option("excludeSwitches", ["enable-automation"])
option.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(chrome_options=option)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
        })
      """
})
driver.execute_cdp_cmd("Network.enable", {})
driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {"headers": {"User-Agent": "browser1"}})

不过好像没啥用,没有证明过是否有用。

自定义浏览器默认下载的路径

def set_download_path(driver, path):
    """path=需要保存的路径
    禁止下载弹窗,设置下载路径
    """
    path = path.rstrip(os.sep)
    driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
    params = {'cmd': 'Page.setDownloadBehavior',
    'params': {'behavior': 'allow', 'downloadPath': path}}
    driver.execute("send_command", params)
    if not os.path.exists(path):
        os.makedirs(path)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您使用Selenium获取的网页源码不正确,可能有以下几种原因: 1. 网页动态加载 如果网页内容是通过JavaScript动态加载的,则在Selenium获取网页源码时可能只能获取到部分内容。这时,您可以使用Selenium的`execute_script`方法来执行JavaScript代码,以获取完整的网页源码。例如: ``` from selenium import webdriver driver = webdriver.Chrome() driver.get("http://www.example.com") html = driver.execute_script("return document.documentElement.outerHTML") print(html) ``` 2. 网页编码问题 如果网页编码与Selenium默认编码不同,则获取的网页源码可能会出现乱码。您可以尝试指定网页编码并重新获取网页源码。例如: ``` from selenium import webdriver driver = webdriver.Chrome() driver.get("http://www.example.com") source = driver.page_source.encode('utf-8') print(source.decode('utf-8')) ``` 3. 网页访问速度过慢 如果网页访问速度过慢,可能会导致Selenium获取的网页源码不完整或不正确。您可以尝试增加获取网页源码的等待时间,以确保网页完全加载。例如: ``` from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.get("http://www.example.com") wait = WebDriverWait(driver, 10) element = wait.until(EC.presence_of_element_located((By.TAG_NAME, "body"))) html = driver.page_source.encode('utf-8') print(html.decode('utf-8')) ``` 在上面的代码中,我们使用了`WebDriverWait`类来等待网页元素的出现,以确保网页已经完全加载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值