使用 Selenium 和 PhantomJS 抓取 Python.org

本篇文章将介绍 Selenium 和 PhantomJS,这两个框架与前面的文章中的框架有很大不同。 事实上,Selenium 和 PhantomJS 经常用于功能/验收测试。 我们希望展示这些工具,因为它们从抓取的角度提供了独特的优势。 我们将在本书后面介绍的一些功能包括填写表单、按下按钮以及等待动态 JavaScript 下载和执行的功能。

Selenium 本身是一个编程语言中立的框架。 它提供了多种编程语言绑定,例如 Python、Java、C# 和 PHP(等等)。 该框架还提供了许多专注于测试的组件。 三个常用的组件是:

  • 用于录制和重放测试的 IDE

  • Webdriver,通过发送命令并将结果发送到所选浏览器来实际启动 Web 浏览器(例如 Firefox、Chrome 或 Internet Explorer)

  • grid 服务器使用远程服务器上的 Web 浏览器执行测试。 它可以并行运行多个测试用例。

准备工作

首先我们需要安装 Selenium。我们用我们值得信赖的点来做到这一点:

~ $ pip install selenium
Collecting selenium
Downloading selenium-3.8.1-py2.py3-none-any.whl (942kB)
100% |████████████████████████████████| 952kB 236kB/s
Installing collected packages: selenium
Successfully installed selenium-3.8.1

这将安装适用于 Python 的 Selenium 客户端驱动程序(语言绑定)。 您可以在 https://github.com/SeleniumHQ/selenium/blob/master/py/docs/source/index 找到更多信息。

对于这个示例,我们还需要在目录中包含 Firefox 的驱动程序(名为 geckodriver)。 该文件是特定于操作系统的。 我已将 Mac 的文件包含在该文件夹中。 要获取其他版本,请访问 https://github.com/mozilla/geckodriver/releases

不过,运行此示例时您可能会收到以下错误:

FileNotFoundError: [Errno 2] No such file or directory: 'geckodriver'

如果这样做,请将 geckodriver(chromedriver) 文件放在系统 PATH 的某个位置,或将 01 文件夹添加到您的路径中。 哦,你需要安装 Firefox(chrome)。

最后,需要安装 PhantomJS。 您可以在以下位置下载并查找安装说明: http://phantomjs.org/

怎么做

此示例的脚本是 01/04_events_with_selenium.py。

  1. 下面是代码:

    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    
    # 需要安装 selenium==2.48.0
    def get_upcoming_events(url):
        cService = Service(executable_path=r"E:\BaiduSyncdisk\sourceCode\python\scrapy-demo\tools\chromedriver-120-64.exe")
        driver = webdriver.Chrome(service=cService)
        driver.get(url)
    
        events = driver.find_elements(By.XPATH, '//ul[contains(@class, "list-recent-events")]/li')
    
        for event in events:
            event_details = dict()
            event_details['name'] = event.find_element(By.XPATH, 'h3[@class="event-title"]/a').text
            event_details['location'] = event.find_element(By.XPATH, 'p/span[@class="event-location"]').text
            event_details['time'] = event.find_element(By.XPATH, 'p/time').text
            print(event_details)
    
        driver.close()
    
    
    get_upcoming_events('https://www.python.org/events/python-events/')
  2. 并使用 Python 运行脚本。 您将看到熟悉的输出:

    ~ $ python 04_events_with_selenium.py
    {'name': 'PyCascades 2018', 'location': 'Granville Island Stage, 1585
    Johnston St, Vancouver, BC V6H 3R9, Canada', 'time': '22 Jan. – 24 Jan.'}
    {'name': 'PyCon Cameroon 2018', 'location': 'Limbe, Cameroon', 'time': '24
    Jan. – 29 Jan.'}
    {'name': 'FOSDEM 2018', 'location': 'ULB Campus du Solbosch, Av. F. D.
    Roosevelt 50, 1050 Bruxelles, Belgium', 'time': '03 Feb. – 05 Feb.'}
    {'name': 'PyCon Pune 2018', 'location': 'Pune, India', 'time': '08 Feb. – 12
    Feb.'}
    {'name': 'PyCon Colombia 2018', 'location': 'Medellin, Colombia', 'time':
    '09 Feb. – 12 Feb.'}
    {'name': 'PyTennessee 2018', 'location': 'Nashville, TN, USA', 'time': '10
    Feb. – 12 Feb.'}

在此过程中,Firefox 会弹出并打开页面。 我们重复使用了之前的配方并采用了 Selenium。

image 2024 01 28 21 37 40 616

怎么运行的

本示例的主要区别在于以下代码:

driver = webdriver.Chrome()
driver.get(url)

这会获取 Firefox 驱动程序并使用它来获取指定 URL 的内容。 这是通过启动 Firefox 并自动转到页面,然后 Firefox 将页面内容返回到我们的应用程序来实现的。 这就是 Firefox 出现的原因。 另一个区别是,要查找内容,我们需要调用 find_element 通过 xpath 来搜索生成的 HTML。

还有更多

PhantomJS 在很多方面与 Selenium 非常相似。 它对各种 Web 标准提供快速和本机支持,具有 DOM 处理、CSS 选择器、JSON、Canvas 和 SVG 等功能。 它常用于 Web 测试、页面自动化、屏幕捕获和网络监控。

Selenium 和 PhantomJS 之间有一个关键区别:PhantomJS 是无头的并且使用 WebKit。 正如我们所看到的,Selenium 打开并自动化浏览器。 如果我们处于未安装浏览器的持续集成或测试环境中,并且我们也不希望打开数千个浏览器窗口或选项卡,那么这不是很好。 无头使得这一切变得更快、更高效。

PhantomJS 的示例位于 01/05_events_with_phantomjs.py 文件中。 有一行更改:

driver = webdriver.PhantomJS('phantomjs')

运行该脚本会产生与 Selenium / Firefox 示例类似的输出,但不会弹出浏览器,并且完成所需的时间也更少。