Selenium Webdriver - PhantomJS在向文件输入元素发送send_keys()时挂起

6 投票
4 回答
2090 浏览
提问于 2025-04-18 13:03

我正在进行一些文件上传的测试。我发现当我使用PhantomJS时,我的测试代码在element.send_keys(file)这一行卡住了,但如果我使用Firefox,这段代码就不会卡住。

element = self.browser.find_element_by_xpath("//input[@type='file']")
element.send_keys(file)

有没有什么办法可以让PhantomJS正常上传文件?目前我使用的是Windows 7,Python 3.4.1,selenium 2.42.1,PhantomJS 1.9.7。

4 个回答

0

当我不能简单地改变文件输入标签的值时,我会使用这种方法。

我们将在控制台中运行这个程序,所以我们需要用到 PyVirtualDisplay 和窗口管理器 (我使用的是 dwm,你也可以试试 fluxbox,它容易安装,但需要比dwm更多的内存),还有Xephyr来进行调试。

为了运行窗口管理器,我们会使用 EasyProcess

接下来,我们会通过点击某个元素或按钮来调用文件上传对话框,然后用 pynput 模拟发送按键,所有这些操作都在我们的控制台中进行。

import time

from easyprocess import EasyProcess
from pynput.keyboard import Key, Controller
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


class ImageUploadAutomation:
    chrome = 'path/to/chrome'
    chrome_options = Options()
    # chrome_options.add_argument('--headless')
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-notifications")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--window-size=1280,900")
    chrome_options.add_argument("--start-maximized")
    chrome_options.add_argument("user-data-dir=selenium")
    chrome_options.add_experimental_option(
        "excludeSwitches", ["disable-popup-blocking"]
    )
    chrome_options.add_argument(
        "--disable-blink-features=AutomationControlled"
    )

    driver = None

    def upload(self, photo):
        # Change visible to 1 if you want to use Xephyr debug
        with Display(visible=0, size=(1280, 900)) as display:
            with EasyProcess(["dwm"]) as process:
                keyboard = Controller()
                url = "https://www.exmaple.com"

                self.driver = webdriver.Chrome(
                    executable_path=self.chrome,
                    chrome_options=self.chrome_options
                )
                self.driver.get(url)

                test = self.driver.find_element_by_xpath(
                    "//div[@aria-label='Add Photos']"
                )
                time.sleep(1)
                test.click()

                time.sleep(1)

                for key in photo.path:
                    keyboard.press(key)
                    keyboard.release(key)

                # keyboard.press(Key.enter)
                with keyboard.pressed(Key.enter):
                    pass
0

奇怪的是,我在我的Ubuntu终端里什么都无法运行,但在同一台服务器上通过Jupyter Notebook里的iPython却能正常运行。

为了让它能在终端作为.py脚本运行,我不得不在代码里添加一个虚拟显示。

如果有其他人遇到类似的问题,这里是我添加到脚本中的代码行,发送按键的功能就开始正常工作了。

from pyvirtualdisplay import Display

# Set screen resolution to 1366 x 768 like most 15" laptops. This is needed 
#to run in the shell. Seems fine in iPython
display = Display(visible=0, size=(1366, 768))
display.start()
0

应该使用 PhantomJS.uploadFile()。不过,我没有找到 Python 的 Selenium API。

var webPage = require('webpage');   
var page = webPage.create();
page.uploadFile('input[name=image]', '/path/to/some/photo.jpg');
1
browser = webdriver.PhantomJS()
browser.set_window_size(1200,800)

如果不设置窗口大小,浏览器就会保持在手机的大小,这样会导致一些错误。你也可以试试使用隐式等待。

撰写回答