Python Selenium实现无头浏览器
Python 无头浏览器是一种无需真正的浏览器即可顺利抓取动态内容的工具。它将降低抓取成本并扩展您的抓取过程。使用基于浏览器的解决方案进行网页抓取可帮助您处理需要JavaScript 的网站。
另一方面,网络抓取可能是一个漫长的过程,尤其是在处理复杂的网站或大量数据列表时。在本指南中,我们将介绍 Python 无头浏览器、它们的类型、优缺点。
Python 中的无头浏览器是什么?
无头浏览器是一种没有图形用户界面 (GUI) 但具有真实浏览器功能的 Web 浏览器。
它具有所有标准功能,例如处理 JavaScript、单击链接等。Python 是一种编程语言,可让您享受其全部功能。
您可以自动化浏览器并使用 Python 无头浏览器学习语言。它还可以节省您在开发和抓取阶段的时间,因为它使用更少的内存。
Python 无头浏览器的好处
任何无头浏览器进程使用的内存都比真正的浏览器少。这是因为它不需要为浏览器和网站绘制图形元素。
此外,Python 无头浏览器速度很快,可以显着加快抓取过程。例如,如果您想从网站中提取数据,您可以对抓取工具进行编程,以从无头浏览器中获取数据,并避免等待页面完全加载。
它还允许多任务处理,因为您可以在无头浏览器在后台运行时使用计算机。
Python 无头浏览器的缺点
Python 无头浏览器的主要缺点是无法执行需要视觉交互的操作并且难以调试。
因此,您将无法检查元素或观察测试的运行。
此外,您对用户通常如何与网站交互的了解非常有限。
Python Selenium无头
最流行的 Python 无头浏览器是Python Selenium,其主要用途是自动化 Web 应用程序,包括 Web 抓取。
Python Selenium 具有与浏览器和 Selenium 相同的功能。因此,如果浏览器可以无头操作,Python Selenium 也可以。
Selenium 中包含哪些无头浏览器?
Chrome、Edge 和 Firefox 是 Selenium Python 中的三个无头浏览器。这三个浏览器可用于无头执行 Python Selenium。
1. 无头 Chrome Selenium Python
从版本 59开始,Chrome 附带了无头功能。您可以从命令行调用 Chrome 二进制文件来执行无头 Chrome。
chrome --headless --disable-gpu --remote-debugging-port=9222 https://zenrows.com
2. 边缘
该浏览器最初是使用 Microsoft 专有的浏览器引擎 EdgeHTML 构建的。然而,在 2018 年底,它被重建为带有 Blink 和 V8 引擎的 Chromium 浏览器,使其成为最好的无头浏览器之一。
3.火狐浏览器
Firefox 是另一种广泛使用的浏览器。要打开 headless Firefox,请在命令行或终端中键入命令,如下所示。
firefox -headless https://zenrows.com
如何在 Selenium Python 中实现无头?
让我们看看如何通过 Python Selenium headless 来实现无头浏览器自动化。
在此示例中,我们将从ScrapeMe中抓取 Pokémon 详细信息,例如名称、链接和价格。
页面如下所示。
先决条件
在使用 Python 无头浏览器抓取网页之前,我们先安装以下工具:
1.安装Selenium
安装Python后,让我们继续使用下面的命令代码在Python中安装Selenium。
pip install selenium
好消息是大多数时候,Python 会自动安装 Selenium,因此您不必担心。
2.安装Webdriver管理器
Python Selenium 需要安装相同浏览器版本的 Webdriver。您可以下载并设置ChromeDriver以与已安装的 Chrome 浏览器配合使用。
不幸的是,它存在一些缺点,例如忘记 Webdriver 二进制文件的特定路径或 Webdriver 与浏览器之间的版本不匹配。
为了避免这些问题,我们将使用Python 的Webdriver Manager 。该库可帮助您管理与您的环境相关的 Webdriver。
它将下载正确的 Webdriver 并提供二进制文件的相关链接。所以你不需要在脚本中显式地写它。
您还可以使用 pip 安装 WebDrive 管理器。只需打开命令行或终端并输入以下命令即可。
pip install webdriver-manager
现在我们准备使用 Python 无头浏览器抓取一些 Pokémon 数据。让我们开始吧!
第1步:打开页面
让我们编写一段代码来打开页面,以确认我们的环境已正确设置并准备好进行抓取。
运行下面的代码将自动打开Chrome并转到目标页面。
from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from webdriver_manager.chrome import ChromeDriverManager url = "https://scrapeme.live/shop/" with webdriver.Chrome(service=ChromeService(ChromeDriverManager().install())) as driver: driver.get(url)
该页面应如下所示:
第 2 步:切换到 Python Selenium Headless 模式
打开页面后,其余过程将变得更加容易。当然,我们不希望浏览器出现在显示器上,而是让Chrome无头运行。在 Python 中切换到无头 Chrome 非常简单。
我们只需要添加两行代码并在调用Webdriver时使用options参数即可。
# ... options = webdriver.ChromeOptions() options.headless = True with webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) as driver: # ...
完整的代码如下所示:
from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from webdriver_manager.chrome import ChromeDriverManager url = "https://scrapeme.live/shop/" options = webdriver.ChromeOptions() #newly added options.headless = True #newly added with webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) as driver: #modified driver.get(url)
如果运行代码,您将在命令行或终端上看到一些少量信息。
没有 Chrome 出现并侵入我们的屏幕。
但是代码是否成功到达页面呢?如何验证爬虫是否打开了正确的
页面?有没有错误?这些是您执行 Python Selenium headless 时提出的一些问题。
您的代码必须创建尽可能多的日志来解决上述问题。
日志可能会有所不同,这取决于您的需求。它可以是文本格式的日志文件,专用的日志数据库,也可以是终端上的简单输出。
为了简单起见,我们将通过在终端上输出抓取结果来创建日志。让我们在下面添加两行代码来打印页面 URL 和标题。这将确保 Python Selenium headless 按需要运行。
# ... with webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) as driver: # ... print("Page URL:", driver.current_url) print("Page Title:", driver.title)
我们的爬虫不会得到意想不到的结果,这是令人惊奇的。完成后,让我们抓取一些神奇宝贝数据。
第 3 步:抓取数据
在深入研究之前,我们需要使用真实的浏览器检查网页来找到保存数据的 HTML 元素。
为此,请右键单击任何图像并选择“检查”。Chrome DevTools 将在“元素”选项卡上打开。
让我们继续从显示的选项中查找包含名称、价格和其他信息的元素。浏览器将突出显示所选元素覆盖的区域,从而更容易识别正确的元素。
<a href="https://scrapeme.live/shop/Bulbasaur/" class="woocommerce-LoopProduct-link woocommerce-loop-product__link">
要获取名称元素,请将鼠标悬停在名称上,直到无头浏览器突出显示它。
<h2 class="woocommerce-loop-product__title">Bulbasaur</h2>
“h2”元素保留在父元素内。让我们将该元素放入代码中,以便 Selenium Python 中的无头 Chrome 可以识别应从页面中提取哪个元素。
Selenium 提供了多种选择和提取所需元素的方法,例如使用元素 ID、标签名称、类、CSS 选择器和 XPath。让我们使用 XPath 方法。
稍微调整初始代码将使抓取工具显示更多信息,例如 URL、标题和 Pokémon 名称。
这是我们的新代码的样子。
#... from selenium.webdriver.common.by import By #... with webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) as driver: #... pokemons_data = [] parent_elements = driver.find_elements(By.XPATH, "//a[@class='woocommerce-LoopProduct-link woocommerce-loop-product__link']") for parent_element in parent_elements: pokemon_name = parent_element.find_element(By.XPATH, ".//h2") print(pokemon_name.text)
接下来,从父元素下的“href”属性中提取 Pokémon 链接。此 HTML 标记将帮助抓取工具发现链接。
<a href="https://scrapeme.live/shop/Bulbasaur/" class="woocommerce-LoopProduct-link woocommerce-loop-product__link">
既然我们已经解决了这个问题,那么让我们添加一些代码来帮助我们的抓取工具提取并存储名称和链接。
然后我们可以使用 Python 字典来管理数据,这样就不会混淆。该字典将包含每个神奇宝贝的数据。
#... parent_elements = driver.find_elements(By.XPATH, "//a[@class='woocommerce-LoopProduct-link woocommerce-loop-product__link']") for parent_element in parent_elements: pokemon_name = parent_element.find_element(By.XPATH, ".//h2") pokemon_link = parent_element.get_attribute("href") temporary_pokemons_data = { "name": pokemon_name.text, "link": pokemon_link } pokemons_data.append(temporary_pokemons_data) print(temporary_pokemons_data)
现在让我们获取我们需要的最后一项神奇宝贝数据,即价格。
跳到真正的浏览器并快速检查保存价格的元素。然后,我们可以在代码上插入一个 span 标签,以便抓取工具知道哪个元素包含价格。
#... for parent_element in parent_elements: pokemon_name = parent_element.find_element(By.XPATH, ".//h2") pokemon_link = parent_element.get_attribute("href") pokemon_price = parent_element.find_element(By.XPATH, ".//span") temporary_pokemons_data = { "name": pokemon_name.text, "link": pokemon_link, "price": pokemon_price.text } print(temporary_pokemons_data)
剩下的唯一事情就是运行脚本;我们得到了所有神奇宝贝数据。
如果您在某个地方迷路了,完整的代码应该如下所示。
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service as ChromeService from webdriver_manager.chrome import ChromeDriverManager url = "https://scrapeme.live/shop/" options = webdriver.ChromeOptions() options.headless = True with webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) as driver: driver.get(url) print("Page URL:", driver.current_url) print("Page Title:", driver.title) parent_elements = driver.find_elements(By.XPATH, "//a[@class='woocommerce-LoopProduct-link woocommerce-loop-product__link']") for parent_element in parent_elements: pokemon_name = parent_element.find_element(By.XPATH, ".//h2") pokemon_link = parent_element.get_attribute("href") pokemon_price = parent_element.find_element(By.XPATH, ".//span") temporary_pokemons_data = { "name": pokemon_name.text, "link": pokemon_link, "price": pokemon_price.text } print(temporary_pokemons_data)
什么是最好的无头浏览器?
Selenium 无头 Python 并不是唯一的无头浏览器,因为还有其他替代方案,有些仅提供一种编程语言,而另一些则提供与多种语言的绑定。
除了 Selenium 之外,这里有一些最适合您的抓取项目的无头浏览器。
1.ZenRows
ZenRows是一款一体化网络抓取工具,它使用单个 API 调用来处理所有反机器人绕过,从旋转代理和无头浏览器到验证码。
提供的住宅代理可帮助您像真实用户一样抓取网页并浏览,而不会被阻止。
ZenRows 适用于几乎所有流行的编程语言,并且您可以利用正在进行的免费试用,无需信用卡。
2. Puppeteer
Puppeteer是一个 Node.js 库,提供 API 以在无头模式下操作 Chrome/Chromium。谷歌于 2017 年开发了它,并且势头不断增强。
它可以使用 DevTools 协议完全访问 Chrome,使得 Puppeteer 在处理 Chrome 时优于其他工具。
Puppeteer 也比 Selenium 更容易设置且速度更快。缺点是它仅适用于 JavaScript。因此,如果您不熟悉该语言,您会发现使用 Puppeteer 具有挑战性。
3.HtmlUnit
这种无头浏览器是用于 Java 程序的 GUI-Less 浏览器,并且在正确配置后它可以模拟特定的浏览器(即 Chrome、Firefox 或 Internet Explorer)。
JavaScript 支持相当好并且不断增强。不幸的是,您只能将HtmlUnit与 Java 语言一起使用。
4.Zombie.JS
Zombie.JS是一个用于测试客户端 JavaScript 代码的轻量级框架,也可用作 Node.js 库。
因为主要目的是为了测试,所以它可以完美地与测试框架一起运行。与 Puppeteer 类似,您只能将 Zombie.JS 与 JavaScript 结合使用。
5.Playwright
Playwright本质上是一个用于浏览器自动化的 Node.js 库,但它为其他语言(如 Python、.NET 和 Java)提供了 API。与 Python Selenium 相比,它相对较快。
结论
Python 无头浏览器为网络抓取过程提供了好处。例如,它最大限度地减少了内存占用,完美地处理 JavaScript,并且可以在无 GUI 环境中运行;另外,实现只需要几行代码。
在本指南中,我们向您展示了如何在 Selenium Python 中使用无头 Chrome 从网页抓取数据的分步说明。
本指南中讨论的 Python 无头浏览器的一些缺点如下:
- 它无法评估图形元素;因此,您将无法在无头模式下执行任何需要视觉交互的操作。
- 很难调试。