0


Python Selenium.WebDriver 最强详解页面加载策略

Python Selenium.WebDriver 网页加载策略『详细』

文章目录


一、网页加载策略🍗

在通过Selenium加载一个网页时,Selenium都会等待页面加载完了才会运行下面的代码,这是因为

webdriver.get

方法会阻塞直到网页全部加载完成。

在这里插入图片描述
通常如果当页面加载花费大量时间时,可能是加载了很多外部资源「如:图像、css」,又或则是浏览的是国外网站,使用的网络环境差等问题,这些都是造成页面加载慢的原因。

**但对于某些网页来说,需要加载的元素往往比不需要使用到的网页更快的加载出来,那么如何才能在加载到需要的数据之后就停止阻塞并且执行

webdriver.get

方法下的代码是本文章要探究的问题。**


二、加载策略种类

Selenium支持的加载策略有三种,分别是

none

eager

normal

,且提供自带的方法让我们去设置启动策略。
关键字加载策略状态描述none****没有等待html下载完成,不等待解析完成就开始执行操作,

selenium

会直接返回eager****渴望等待整个dom树加载完成,即DOMContentLoaded这个事件完成。
只要 HTML 完全加载和解析完毕就开始执行操作,忽略加载样式表、图像和子框架normal****正常(默认)等待整个页面加载完毕再开始执行操作
在浏览器选项类的源码中能够看到,Selenium已经写好了设置加载策略的方法,同时也限制了加载策略的种类『源码第13行』

classOptions(object):def__init__(self):
        self._page_load_strategy ="normal"
        self._caps = DesiredCapabilities.EDGE.copy()@propertydefpage_load_strategy(self):return self._page_load_strategy

    @page_load_strategy.setterdefpage_load_strategy(self, value):if value notin['normal','eager','none']:raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.")
        self._page_load_strategy = value
    ......

三、配置加载策略

每种类型的

webdriver

都有一个对应的配置文件放在特定的类

DesiredCapabilities

里面,这个配置文件的数据结构为字典格式,通过定义键为

pageLoadStrategy

的键值对,可以使webdriver的页面加载策略发生改变。

模块位置 👇

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

1)、源码中是这么去使用加载策略的👇

可以看到,源码实质上就是在

DesiredCapabilities

配置文件中增加了一个

pageLoadStrategy

属性值『源码第32行』,而

page_load_strategy

则是 Selenium 提供设置加载策略的方法。

对于DesiredCapabilities类,在博客 Python Selenium.WebDriverWait 浏览器启动参数设置『Edge如何使用启动参数』 中也有提到过,不管是在浏览器启动参数类

Options

源码中,还是自定义的

Options

启动参数类中,都会用的上。本篇文章相当于对 Python Selenium.WebDriverWait 浏览器启动参数设置『Edge如何使用启动参数』 的扩展。

Options选项类部分源码

classOptions(object):def__init__(self):
        self._page_load_strategy ="normal"
        self._caps = DesiredCapabilities.EDGE.copy()......@propertydefpage_load_strategy(self):return self._page_load_strategy

    @page_load_strategy.setterdefpage_load_strategy(self, value):if value notin['normal','eager','none']:raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.")
        self._page_load_strategy = value
        
    @propertydefcapabilities(self):return self._caps
        
    ......defto_capabilities(self):"""
            Creates a capabilities with all the options that have been set and

            returns a dictionary with everything
        """
        caps = self._caps
        caps['pageLoadStrategy']= self._page_load_strategy

        return caps

DesiredCapabilities 部分源码

classDesiredCapabilities(object):......
    FIREFOX ={"browserName":"firefox","marionette":True,"acceptInsecureCerts":True,}

    INTERNETEXPLORER ={"browserName":"internet explorer","version":"","platform":"WINDOWS",}

    EDGE ={"browserName":"MicrosoftEdge","version":"","platform":"WINDOWS"}

    CHROME ={"browserName":"chrome","version":"","platform":"ANY",}......

2)、更改使用加载策略:👇

  • 使用 page_load_strategy 方法更改加载策略:from selenium import webdriverfrom selenium.webdriver.edge.options import Optionsdeftimer(func):"""计时装饰器,用于计算程序运行时间"""definner(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs)print(f"加载时间:{time.time()- start_time}")return res return inner@timerdefget_url(browser_, url_):"""对页面发起请求""" browser_.get(url_)if __name__ =='__main__': url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501" op = Options()# 设置页面加载策略为none# op.page_load_strategy = "none"# 设置页面加载策略为normal# op.page_load_strategy = "eager" browser = webdriver.Edge("msedgedriver 97.exe", capabilities=op.to_capabilities()) get_url(browser, url)程序流程: 使用 Edge 浏览器对目标网址发起请求,timer 为装饰器方法进行计时,对发起请求的 get_url 函数进行计时,分别计算各浏览器加载策略的耗时normal加载时间: 3.539372682571411eager加载时间: 2.0514888763427734none加载时间: 0.003000974655151367
  • 使用原生方法手动配置加载策略:可以看到其实就是先将选项类的配置转换为字典,再为这个字典添加键为 pageLoadStrategy 的键值对,再将这个字典传入浏览器的实例化参数中。from selenium import webdriverfrom selenium.webdriver.chrome.options import Optionsdeftimer(func):"""计时装饰器,用于计算程序运行时间"""definner(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs)print(f"加载时间:{time.time()- start_time}")return res return inner@timerdefget_url(browser_, url_):"""对页面发起请求""" browser_.get(url_)if __name__ =='__main__': url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501" op = Options() capabilities = op.to_capabilities()# 设置页面加载策略为none capabilities["pageLoadStrategy"]="none"# 设置页面加载策略为normal# capabilities["pageLoadStrategy"] = "eager" browser = webdriver.Chrome("chromedriver 97.exe", desired_capabilities=capabilities) get_url(browser, url)程序流程: 使用 Chrome 浏览器对目标网址发起请求,timer 为装饰器方法进行计时,对发起请求的 get_url 函数进行计时,分别计算各浏览器加载策略的耗时normal加载时间: 3.847010850906372eager加载时间: 2.529080390930176none加载时间: 0.002000093460083008

DesiredCapabilities类,其本质就是存放着关于浏览器启动的配置文件。
在Selenium3中,不同浏览器的Options选项类源码存在部分差异,为方便展示,上述参考源码使用的是Edge浏览器的选项类。
对于每次运行的计时结果,都会有差异。


四、对加载策略进行封装🎍

在上述

page_load_strategy

方法示例中,使用到 Edge 浏览器进行示例,不用 Chrome 浏览器是因为在 Chrome 的选项类中并没有自带加载策略方法供我们去使用,需要手动配置加载策略或则直接对这个方法进行自定义封装。
在这里插入图片描述
将 Edge 和 Chrome 加载策略配置好之后,在写法一样的情况下分别调用

to_capabilities

方法输出配置策略对其进行对比,会发现 Chrome 选项类的配置中少了

pageLoadStrategy

值,主要差异体现在有没有配置

pageLoadStrategy

值的加载策略

1)、Edge浏览器加载配置
配置部分代码

......
    url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501"
    op = Options()# 设置页面加载策略为none
    op.page_load_strategy ="none"# 设置页面加载策略为normal# op.page_load_strategy = "eager"# 打印配置策略print(op.to_capabilities())
    browser = webdriver.Edge("msedgedriver 97.exe", capabilities=op.to_capabilities())
    get_url(browser, url)

在这里插入图片描述
2)、Chrome浏览器加载配置
配置部分代码

......
    url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501"
    op = Options()# 设置页面加载策略为none
    op.page_load_strategy ="none"# 设置页面加载策略为normal# op.page_load_strategy = "eager"# 打印配置策略print(op.to_capabilities())
    browser = webdriver.Chrome("chromedriver 97.exe", options=op)
    get_url(browser, url)

在这里插入图片描述
3)、Chrome加载策略封装

在继承原有 Chrome 选项类的基础上,自定义加载策略方法,通过这种形式就可以弥补某些浏览器启动参数类方法不全的问题,或编写提升效率的方法

Chrome封装加载策略类

classChromeOptions(Options):def__init__(self):super(ChromeOptions, self).__init__()
        self._page_load_strategy ="normal"@propertydefpage_load_strategy(self):return self._page_load_strategy

    @page_load_strategy.setterdefpage_load_strategy(self, value):"""设置加载策略方法"""if value notin['normal','eager','none']:raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.")
        self._page_load_strategy = value

    defto_capabilities(self):"""使用已设置的所有启动参数,并返回包含所有内容的字典"""
        caps = self._caps
        chrome_options = self.experimental_options.copy()
        chrome_options["extensions"]= self.extensions
        if self.binary_location:
            chrome_options["binary"]= self.binary_location
        chrome_options["args"]= self.arguments
        if self.debugger_address:
            chrome_options["debuggerAddress"]= self.debugger_address
        # 添加加载策略键值对
        caps["pageLoadStrategy"]= self._page_load_strategy
        caps[self.KEY]= chrome_options

        return caps

调用执行
可以看到,需要的

pageLoadStrategy

值已被成功添加,且程序也能正常使用自定义的加载策略

url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501"
op = ChromeOptions()# 设置页面加载策略为none
op.page_load_strategy ="none"# 设置页面加载策略为normal# op.page_load_strategy = "eager"# 打印配置策略print(op.to_capabilities())
browser = webdriver.Chrome("chromedriver 97.exe", options=op)
get_url(browser, url)

在这里插入图片描述


五、配合显示等待使用加载策略

通过更改加载策略,Selenium不再等待页面加载完毕后才会执行

webdriver.get

下面的代码, 但这也会造成一个问题,在

webdriver.get

下面的代码通常都是页面元素的获取代码,但在页面没有加载结束的情况下去获取会造成程序抛出异常。

1)、显示等待

为了解决这个问题,这时候就需要用上 Selenium 的显示等待。
使用 Selenium 时能用上的等待方式共有三种,分别是显示等待、隐性等待、强制等待,这里只稍微提及一下显示等待。显示等待的作用:程序每隔xx秒看一眼,如果页面元素存在了,则代码继续执行下一步,否则继续循环检查,直到超过设置的最长时间抛出

TimeoutException

异常。

2)、配合显示等待

现使用 Selenium 配置

none

加载策略并打开博客页面,点击页面点赞标签,观察显示等待效果。
显示等待与加载策略配合使用,能够在一定程度上提高程序的执行效率,对于使用Selenium来说这是一个常见的技巧。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

classChromeOptions(Options):def__init__(self):super(ChromeOptions, self).__init__()
        self._page_load_strategy ="normal"@propertydefpage_load_strategy(self):return self._page_load_strategy

    @page_load_strategy.setterdefpage_load_strategy(self, value):"""设置加载策略方法"""if value notin['normal','eager','none']:raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.")
        self._page_load_strategy = value

    defto_capabilities(self):"""使用已设置的所有启动参数,并返回包含所有内容的字典"""
        caps = self._caps
        chrome_options = self.experimental_options.copy()
        chrome_options["extensions"]= self.extensions
        if self.binary_location:
            chrome_options["binary"]= self.binary_location
        chrome_options["args"]= self.arguments
        if self.debugger_address:
            chrome_options["debuggerAddress"]= self.debugger_address
        # 添加加载策略键值对
        caps["pageLoadStrategy"]= self._page_load_strategy
        caps[self.KEY]= chrome_options

        return caps

deftimer(func):"""计时装饰器,用于计算程序运行时间"""definner(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)print(f"加载时间:{time.time()- start_time}")return res
    return inner

@timerdefget_url(browser_, url_):"""对页面发起请求"""
    browser_.get(url_)deflike(browser_: webdriver, sec=3, poll_frequency=0.5):"""CSDN博客点赞方法

    Args:
        browser_: 浏览器对象
        sec: 显示等待时长
        poll_frequency: 显示等待轮询频率
    """
    xpaths ="//li[@id='is-like']"
    element = WebDriverWait(browser_, sec, poll_frequency=poll_frequency).until(
        ec.presence_of_element_located((By.XPATH, xpaths)))
    element.click()if __name__ =='__main__':
    url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501"
    op = ChromeOptions()# 设置页面加载策略为none
    op.page_load_strategy ="none"# 设置页面加载策略为normal# op.page_load_strategy = "eager"
    browser = webdriver.Chrome("chromedriver 97.exe", options=op)
    get_url(browser, url)# 执行点赞
    like(browser)

在这里插入图片描述


六、Selenium4对加载策略的改动💣

在Selenium4中对页面的选项类进行了改动,每个浏览器的 Options选项类不再是单个存在的方式,在 Selenium4 每个选项类都继承来自了

BaseOptions

类。
这是一个很重要的改进,对于各个浏览器来讲,在原本没有定义加载策略方法浏览器选项类中也能用上加载策略了,不需要自行另外再去自定义方法,我们只需直接调用自带方法即可配置加载策略。

BaseOptions类部分源码 🐾

classBaseOptions(metaclass=ABCMeta):"""
    Base class for individual browser options
    """......@platform_name.setterdefplatform_name(self, platform:str)-> NoReturn:"""
        Requires the platform to match the provided value: https://w3c.github.io/webdriver/#dfn-platform-name

        :param platform: the required name of the platform
        """
        self.set_capability("platformName", platform)@propertydefpage_load_strategy(self)->str:"""
        :returns: page load strategy if set, the default is "normal"
        """return self._caps["pageLoadStrategy
    ......

Chrome浏览器启动选项直接使用🐔

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

defget_url(browser_, url_):"""对页面发起请求"""
    browser_.get(url_)if __name__ =='__main__':
    url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501"
    op = Options()# 设置页面加载策略为none
    op.page_load_strategy ="none"# 设置页面加载策略为normal# op.page_load_strategy = "eager"
    driver = Service("chromedriver 97.exe")
    browser = webdriver.Chrome(service=driver, options=op)
    get_url(browser, url)

Edge浏览器启动选项直接使用🐔

from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options

defget_url(browser_, url_):"""对页面发起请求"""
    browser_.get(url_)if __name__ =='__main__':
    url ="https://blog.csdn.net/XianZhe_/article/details/120929106?spm=1001.2014.3001.5501"
    op = Options()# 设置页面加载策略为none
    op.page_load_strategy ="none"# 设置页面加载策略为normal# op.page_load_strategy = "eager"
    driver = Service("msedgedriver 97.exe")
    browser = webdriver.Edge(service=driver, options=op)
    get_url(browser, url)

参考文献💗

  • 官方手册- 文档就绪状态策略- 升级到 Selenium 4

相关博客🤩

  • Python Selenium.WebDriverWait 浏览器启动参数设置『Edge如何使用启动参数』
  • Python Selenium.WebDriverWait 对Cookies的处理及应用『模拟登录』
标签: python selenium 爬虫

本文转载自: https://blog.csdn.net/XianZhe_/article/details/121111810
版权归原作者 XianZhe_ 所有, 如有侵权,请联系我们删除。

“Python Selenium.WebDriver 最强详解页面加载策略”的评论:

还没有评论