pyvirtualdisplay是如何在Xvfb上运行的,或者pyvirtualdisplay可以打开多少个Xvfb?

时间:2017-10-18 09:50:42

标签: python selenium xvfb pyvirtualdisplay

  1. 我曾使用以下代码打开几个Xvfb进行测试,并遇到了一些问题: 答:Xvfb状态的一些过程(在代码之后)是Z或SL,有时是Z +或SL +,但python进程正常进行 它的含义是什么?
    B.代码在乞讨时正常运行,但在结束时得到例外(在状态之后)。
  2. 代码

    #!/usr/bin/env python3
    # encoding: utf-8
    import os
    import time
    import random
    import multiprocessing
    from pyvirtualdisplay import Display
    from selenium import webdriver
    
    def main():
        display = Display(visible=0, size=(800, 600))
        display.start()
        print(os.getpid())
        browser = webdriver.Firefox()
        #time.sleep(20)
        for j in range(30):
            browser.get('http://www.google.com')
            print(browser.title)
            time.sleep(1) # !!!!!! this is sleep time
        browser.quit()
        display.stop()
    
    if __name__ == '__main__':
        tl = []
        for i in range(10):
            tl.append(multiprocessing.Process(target=main))
        start = time.time()
        for j in tl:
            j.start()
        for j in tl:
            j.join()
        print("end {}".format((time.time() - start)))
    

    状态

    root     18503  0.0  0.0      0     0 ?        Z    13:40   0:00 [Xvfb] <defunct>
    root     18504  0.1  0.7 233684 57364 ?        Sl   13:40   0:22 Xvfb -br -nolisten tcp -screen 0 800x800x24 :1049
    root     18506  0.0  0.0      0     0 ?        Z    13:40   0:00 [Xvfb] <defunct>
    root     18508  0.0  0.0      0     0 ?        Z    13:40   0:00 [Xvfb] <defunct>
    root     18509  0.0  0.0      0     0 ?        Z    13:40   0:00 [Xvfb] <defunct>
    root     18514  0.0  0.5 221140 44736 ?        Sl   13:40   0:11 Xvfb -br -nolisten tcp -screen 0 800x800x24 :1052
    root     18515  0.0  0.0      0     0 ?        Z    13:40   0:00 [Xvfb] <defunct>
    root     18516  0.0  0.0      0     0 ?        Z    13:40   0:00 [Xvfb] <defunct>
    root     18517  0.0  0.0      0     0 ?        Z    13:40   0:00 [Xvfb] <defunct>
    root     18520  0.0  0.4 212832 36468 ?        Sl   13:40   0:04 Xvfb -br -nolisten tcp -screen 0 800x800x24 :1055
    

    异常

    Process Process-10:
    Traceback (most recent call last):
      File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
        self.run()
      File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
        self._target(*self._args, **self._kwargs)
      File "/root/PycharmProjects/MyShiYanLou/auto_/test_xvfb.py", line 27, in main
        browser.quit()
      File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/firefox/webdriver.py", line 183, in quit
        RemoteWebDriver.quit(self)
      File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webdriver.py", line 592, in quit
        self.execute(Command.QUIT)
      File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webdriver.py", line 297, in execute
        self.error_handler.check_response(response)
      File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
        raise exception_class(message, screen, stacktrace)
    selenium.common.exceptions.WebDriverException: Message: Failed to decode response from marionette
    

1 个答案:

答案 0 :(得分:1)

你得到的例外不是因为pyvirtualdisplay可以打开一定数量的Xvfb,而是因为selenium将在你打开的最后一个虚拟显示中打开。

想象一下有两个进程AB

的情况
  1. A打开Xvfb
  2. B打开Xvfb
  3. AB打开的虚拟展示中打开webdriver(最后一个已打开)
  4. B关闭Xvfb
  5. A尝试获取网页,但由于打开了webdriver的Xvfb已经关闭,因此失败
  6. 避免该错误的最佳方法是在运行多个进程之前打开一个Xvfb:

    代码

    #!/usr/bin/env python3
    # encoding: utf-8
    import os
    import time
    import multiprocessing
    from pyvirtualdisplay import Display
    from selenium import webdriver
    
    def main():
        print(os.getpid())
        browser = webdriver.Firefox()
        for j in range(30):
            browser.get('http://www.google.com')
            print(browser.title)
            time.sleep(1)  # !!!!!! this is sleep time
        browser.quit()
    
    
    if __name__ == '__main__':
        display = Display(visible=0, size=(800, 600))
        display.start()
    
        tl = []
        for i in range(10):
            tl.append(multiprocessing.Process(target=main))
        start = time.time()
        for j in tl:
            j.start()
        for j in tl:
            j.join()
    
        display.stop()
    
        print("end {}".format((time.time() - start)))