【问题标题】:Selenium Headless vs Non Headless硒无头与非无头
【发布时间】:2021-06-01 18:10:13
【问题描述】:

我目前正在做一个在 python 中使用 Selenium 的网页抓取项目。

在非无头模式下从 Web 驱动程序运行时,我的代码按预期工作。但是,当它以无头模式运行时,情况并非如此。例如,如果我尝试从网站中提取文本,非无头模式返回文本,而无头模式返回无。 (我在下面包含了一些代码供参考)。

首先,我使用以下代码构建了 webdriver(opt.headless 设置为 True 或 False,以便在无头和非无头之间切换)

def getHeadlessDriver():
     opts = webdriver.ChromeOptions()
     opts.headless = False
     driver = webdriver.Chrome(ChromeDriverManager().install(), options=opts)
     return driver

然后,我使用 find_elements_by_xpath 函数从网站中提取文本数据。下面提供了一个示例代码:

driver = getHeadlessDriver()
feedbacks = driver.find_elements_by_xpath(
    "//div[contains(@class, 'LiveFeedbackSectionViewController__LiveFeedbackStatusItem-sc-1ahetk9-4 cUJPkM')]")
for feedback in feedbacks:
     print(feedback.text)

我做了一些谷歌搜索以找到无头模式不起作用的解释,但我仍然不确定。据我了解,无头模式“作用相同”,只是没有图形用户界面。

我的代码的实现会不会有问题?或者无头模式除了没有图形用户界面之外还有其他区别吗?

谢谢。

【问题讨论】:

  • getHeadlessDriver 后面缺少括号。将其更改为getHeadlessDriver(),它应该可以工作:D
  • 缺少的括号是错字,抱歉。除了 GUI 之外,headless 和 non-headless 的功能是否相同?
  • 有些厚脸皮的网站在无头模式下无法加载整页。调试网站在无头模式下的不同之处,我建议你使用driver.save_screenshot(),然后查看图像,看看页面是否加载正确。

标签: python selenium selenium-webdriver selenium-chromedriver headless-browser


【解决方案1】:

如果您尝试抓取的网站具有由 javascript 呈现的动态元素,您将需要 Xvfb。

sudo apt-get install -y xvfb

"Xvfb 或 X 虚拟帧缓冲是一个显示服务器实现 X11 显示服务器协议。与其他显示服务器相比, Xvfb 在虚拟内存中执行所有图形操作,而无需 显示任何屏幕输出。"

在 python 中,Xvfb 有两个包装器。

1- xvfbwrapper

pip install xvfbwrapper

然后添加你的python文件:

from xvfbwrapper import Xvfb

display = Xvfb()
display.start()

2- pyvirtualdisplay

pip install PyVirtualDisplay

然后在你的代码中:

from pyvirtualdisplay import Display

display = Display(visible=0, size=(1024, 768))
display.start()

【讨论】:

    【解决方案2】:

    我想我找到了这个问题的潜在答案。

    在 Selenium 中使用无头浏览器时,它比使用非无头浏览器运行得更快。在这种情况下,python 程序可能会在 DOM 完全加载之前执行。

    换句话说,尝试访问 Web 元素的函数可能会返回 None,因为在调用函数之前未加载元素。

    为了解决这个问题,我们可以利用 Selenium 中包含的implicitly_wait 函数。例如,

    driver = webdriver.Chrome()
    driver.implicitly_wait(3) #units in seconds
    

    将告诉驱动程序等待传递给 implicitly_wait 函数的指定时间量(以秒为单位),以便加载 DOM。

    我已经使用这种方法在无头模式下测试了我的功能,现在它似乎可以正常工作。但是,如果有其他解决此问题的方法,请随时发表评论!

    【讨论】:

      【解决方案3】:

      我通常可以使用 time.sleep(10) 绕过这个问题,但是,我有一个特定的网站,我无法使用 time.sleep(10)driver.implicitly_wait(10) 抓取。

      我认为该网站有一个检查浏览器用户代理的系统。

      为了尝试绕过这个问题,我将用户代理添加到了无头窗口中,并且成功了。

      browser_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30'
      
      options_edge.add_argument(f'user-agent={self.user_agent}')
      

      您可以从以下网站获取您的用户代理:https://whatmyuseragent.com/(非附属)

      【讨论】:

        猜你喜欢
        • 2018-06-23
        • 2016-04-28
        • 2011-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-14
        相关资源
        最近更新 更多