羽流's Blog

  • 答题器
    • 新/错题反馈
    • 下载最新版
    • 网页版
  • Python
常见物质的熔点:
铁1535,铜1083,金1064,铝660,而我只需你的一个评论心就化了
  1. 首页
  2. Python
  3. 正文

headless创建全局driver对象,减少启动时间

2020年12月21日 4点热度 0人点赞 0条评论

原理说明

在使用selenium时,每次启动生成一个driver对象都比较耗时间,大概需要4秒左右,因此可以创建一个全局的,在需要时直接调用,减少启动所耗时间。

问题1:切换到新标签页

打开新标签页后在selenium中并没有定位到新打开的标签页,仍在上一个,因此需要手动切换到新打开的标签页。

因为每次打开的新标签页都是在最后一个,因此只要获得所有标签页然后切换到最后一个即可实现

# 获取当前浏览器的所有标签页 
handles = self.driver.window_handles 
# 定位到最后打开的标签页 
driver.switch_to.window(handles[-1])
问题2:保持浏览器不被关闭

driver对象有driver.quit()和driver.close()方法,其中quit()是直接退出整个浏览器,close()是关闭当前标签页,但如果仅有一个标签页时则退出浏览器。

在被多次调用时,打开的网页如果不关闭则标签不多变多占用内存资源,但如果全部关闭了,浏览器又会直接退出。在这里我的解决办法是启动时打开一个空白页,然后每次打开新的页面都打开一个新的标签,操作完后关闭该标签。这样就保证了浏览器不被关闭,留着一个空白页面也不占用内存。

打开新标签页的方法也有多种,我选择的是执行js代码

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

这里需要注意的是,如果打开的网页是本地文件,则不能一行直接打开新标签页并加载网页,因为js打开本地网页文件是不被允许的,这时需要打开一个空白页,然后切换到新打开的标签页,再使用driver.get()打开网页

open_new_tab_js = "window.open()"
driver.execute_script(open_new_tab_js)
# 获取当前浏览器的所有标签页
handles = self.driver.window_handles
# 定位到最后打开的标签页
driver.switch_to.window(handles[-1])
# 打开模板网页文件
driver.get("file:///path".format()
问题3:并发引出的若干问题

因为我使用切换到最后一个标签页来切换到新的标签页的,这时如果线程p1刚打开新的标签页准备切换到这个标签页,这时由于系统调度被剥夺,并且这时又有一个线程p2,p2打开了一个新的标签页,然后被系统调度剥夺,轮到p1运行,p1执行下一行代码切换到最后一个标签页,进行后续操作。这时可以发现,p1后续操作的页面是p2打开的页面。

因此将driver对象当做一个临界区资源,从打开新标签页开始到操作结束都视作临界区,进入临界区则对driver加锁,执行完后释放锁。

因为我的方法都是async异步方法,所以使用的锁是asyncio.Lock(),如果是多线程则使用threading.Lock()。在进入临界区前调用acquire()方法加锁,执行完后release()方法释放锁

代码实现

这里代码我以网页截图为例

class HtmlCapture:
    def __init__(self):
        chrome_options = Options()
        # chrome_options.add_argument('--headless')# 不显示界面,调试的时候显示方便观察
        chrome_options.add_argument('--disable-gpu')
        chrome_options.add_argument('--hide-scrollbars')  # 隐藏滚动条
        chrome_options.add_argument("start-maximized")  # 最大化
        path = 'C:/Program Files (x86)/Chromedriver/chromedriver.exe'
        print('正在创建全局HtmlCapture对象...')
        # 创建浏览器对象
        self.driver = webdriver.Chrome(executable_path=path, options=chrome_options)
        # 锁
        self.lock = asyncio.Lock()

    async def capture(self, save_file_path: str, template_name: str, js_code: str):
        # 加锁
        await self.lock.acquire()
        try:
            png_path = "{}.png".format(save_file_path)
            jpg_path = "{}.jpg".format(save_file_path)
            # 打开一个新标签页,这里不能直接指定网址,因为用js打开本地html文件是chrome不允许的
            open_new_tab_js = "window.open()"
            self.driver.execute_script(open_new_tab_js)
            # 获取当前浏览器的所有标签页
            handles = self.driver.window_handles
            # 定位到最后打开的标签页
            self.driver.switch_to.window(handles[-1])
            # 打开模板网页文件
            self.driver.get("file:///{}/awesome/data/{}.html".format(os.getcwd(), template_name))
            # 延迟0.2s用于打开网页
            await asyncio.sleep(0.2)
            self.driver.execute_script(js_code)  # 注入js

            # 获取元素位置信息进行截图,并留白
            table = self.driver.find_element_by_tag_name('table')
            left = table.location['x'] - 10
            top = table.location['y'] - 10
            right = left + table.size['width'] + 10
            bottom = top + table.size['height'] + 30

            # 截取全屏
            self.driver.save_screenshot(png_path)
            self.driver.close()
            self.driver.switch_to.window(handles[0])
            # 截取部分并转成jpg格式
            Image.open("{}.png".format(save_file_path)).convert('RGB').crop((left, top, right, bottom)).save(jpg_path)
        finally:
            # 解除锁
            self.lock.release()
标签: 暂无
最后更新:2020年12月21日

羽流

大三学生,摸索中的小菜鸡,喜欢瞎折腾
QQ: 835291398
Github: https://github.com/YuLiu-lab

打赏 点赞
< 上一篇

文章评论

取消回复

羽流

大三学生,摸索中的小菜鸡,喜欢瞎折腾
QQ: 835291398
Github: https://github.com/YuLiu-lab

最新 热点 随机
最新 热点 随机
headless创建全局driver对象,减少启动时间 模板网页注入JS代码并对指定元素网页截图 解决Nonebot复读功能无法复读表情包 消息框导致Tkinter输入框(Entry)无法输入 百度通用文字识别竖着识别文字 剑网三QQ机器人
模板网页注入JS代码并对指定元素网页截图headless创建全局driver对象,减少启动时间
关于科举同一问题多个答案的解决思路 百度通用文字识别竖着识别文字 解决Nonebot复读功能无法复读表情包 科举新/错题反馈 模板网页注入JS代码并对指定元素网页截图 Python调用Tesseract-OCR图像识别和打包后如何运行
标签聚合
tesseract 科举答题 jx3 答题器 Tesseract-OCR 剑网三科举 科举 Python
友情链接
  • 爱极客
  • Q Q
访问数据
  • 1
  • 48,940

COPYRIGHT © 2020 羽流's Blog. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

蜀ICP备20003606号