什么是 PhantomJS?
PhantomJS 是一个无头浏览器(Headless Browser),它就是一个没有图形用户界面的浏览器,你可以在命令行或脚本中控制它,像真实用户一样打开网页、点击链接、填写表单、执行 JavaScript,然后将页面的内容(包括由 JS 动态生成的内容)“截图”或“导出”成数据。

在它诞生之初,这对于 Python 爬虫开发者来说是一个革命性的工具,因为传统的 requests 库只能获取服务器返回的初始 HTML,无法执行页面上的 JavaScript,而很多现代网站(尤其是单页应用 SPA)的内容都是通过 JS 动态加载的,requests 对此无能为力,PhantomJS 则完美解决了这个问题。
PhantomJS 的工作原理
- 启动:你的 Python 脚本通过
Selenium这样的库启动一个 PhantomJS 进程。 - 导航:你告诉 PhantomJS 访问一个 URL,就像你在浏览器地址栏输入网址一样。
- 渲染:PhantomJS 会下载该网页的 HTML、CSS 和 JavaScript 文件,然后像 Chrome 或 Firefox 一样完整地渲染整个页面,执行所有脚本。
- 交互:你可以通过 Selenium 发送指令,找到 ID 为 'search' 的输入框并输入 'Python'”,或者“点击 class 为 'submit' 的按钮”。
- 获取数据:页面渲染和交互完成后,你可以获取页面的最终 HTML 源码、页面标题、特定元素的文本或属性等。
- 关闭:爬取完成后,关闭 PhantomJS 进程,释放资源。
如何使用 Python + PhantomJS + Selenium 进行爬虫?
下面是一个完整的步骤和代码示例。
环境准备
你需要安装必要的软件和 Python 库。
a. 安装 PhantomJS

你需要先从 PhantomJS 官网 下载对应你操作系统的版本。
- Windows: 下载
phantomjs-xxx-windows.zip,解压后将phantomjs.exe所在的目录添加到系统的PATH环境变量中。 - macOS:
brew install phantomjs(如果使用 Homebrew)。 - Linux:
sudo apt-get install phantomjs(对于 Debian/Ubuntu)。
b. 安装 Python 库
我们需要 selenium 库来控制 PhantomJS,以及 webdriver_manager 库来方便地管理浏览器驱动(虽然 PhantomJS 自带,但使用这个库可以简化路径配置)。
pip install selenium pip install webdriver_manager
编写第一个爬虫脚本
我们的目标是:访问一个动态加载内容的网站,获取页面标题和所有链接。

这里我们以一个经典的动态加载示例网站 https://spa-scraping-demo.herokuapp.com/ 为例。
代码示例:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
def scrape_with_phantomjs():
"""
使用 PhantomJS 进行网页爬取
"""
# --- 1. 初始化 PhantomJS 驱动 ---
# 注意:PhantomJS 已不再维护,可能存在兼容性问题。
# 推荐使用 Chrome 或 Firefox 的无头模式作为替代。
# driver = webdriver.PhantomJS() # 这种旧方式需要 phantomjs.exe 在 PATH 中
# 使用 webdriver_manager 自动管理路径 (更推荐的方式)
from webdriver_manager.phantomjs import PhantomJSDriverManager
driver = webdriver.PhantomJS(executable_path=PhantomJSDriverManager().install())
try:
# --- 2. 打开目标网页 ---
print("正在打开网页...")
url = "https://spa-scraping-demo.herokuapp.com/"
driver.get(url)
# --- 3. 等待页面内容加载 ---
# PhantomJS 是无头的,我们无法“看到”页面,所以必须等待。
# 这里我们显式等待,直到某个元素出现,证明内容已加载。
try:
# 等待直到 ID 为 'more-data' 的按钮出现,最长等待 10 秒
wait = WebDriverWait(driver, 10)
more_button = wait.until(EC.presence_of_element_located((By.ID, "more-data")))
print("页面初始内容加载完成。")
except TimeoutException:
print("等待页面元素超时,可能页面结构已改变或加载时间过长。")
return
# --- 4. 与页面交互,加载更多数据 ---
print("点击按钮加载更多数据...")
# 循环点击几次,以加载更多动态内容
for i in range(3):
try:
more_button.click()
print(f"第 {i+1} 次点击完成。")
# 每次点击后等待一段时间,让 JS 有时间加载新内容
time.sleep(2)
except Exception as e:
print(f"点击失败: {e}")
break
# --- 5. 获取所需数据 ---
# 获取页面标题
page_title = driver.title
print(f"\n页面标题是: {page_title}")
# 获取所有链接
print("\n页面上的所有链接:")
links = driver.find_elements(By.TAG_NAME, "a")
for i, link in enumerate(links):
link_text = link.text
link_href = link.get_attribute("href")
print(f"{i+1}. 文本: '{link_text}', 链接: {link_href}")
finally:
# --- 6. 关闭浏览器 ---
print("\n爬取完成,正在关闭浏览器...")
driver.quit()
if __name__ == "__main__":
scrape_with_phantomjs()
代码解析
webdriver.PhantomJS(): 这行代码启动了 PhantomJS 浏览器进程,Selenium 会通过它来控制浏览器。driver.get(url): 导航到指定的 URL。WebDriverWait和expected_conditions: 这是 Selenium 的“显式等待”机制,它比time.sleep()更智能,它会一直等待,直到某个条件(比如元素出现)被满足,或者超时,这对于处理异步加载的页面至关重要,避免了因网络延迟或 JS 执行时间不确定而导致的爬取失败。driver.find_elements(By.TAG_NAME, "a"): 这是定位元素的核心方法。By.TAG_NAME是通过标签名查找,"a"就是链接标签,还有其他定位方式,如By.ID,By.CLASS_NAME,By.CSS_SELECTOR,By.XPATH等。link.text和link.get_attribute("href"): 获取元素的文本内容和href属性。driver.quit(): 非常重要! 在finally块中调用,确保无论脚本是否出错,浏览器都会被关闭,释放系统资源。
⚠️ 重要警告:PhantomJS 已被弃用!
这是你必须知道的最重要的一点。
PhantomJS 项目已于 2025 年 8 月停止维护,这意味着:
- 安全漏洞:它不再接收安全更新,使用它可能让你的系统暴露在风险中。
- 兼容性问题:它无法模拟现代浏览器的最新特性(如最新的 JavaScript API、WebGL 等),很多现代网站会检测到它并拒绝访问。
- 功能缺失:不支持 DevTools,调试困难。
现代替代方案:headless 模式的 Chrome 或 Firefox
幸运的是,主流的现代浏览器都内置了无头模式,并且功能更强大、更稳定。你应该优先使用它们来代替 PhantomJS。
如何使用无头 Chrome?
只需要将 webdriver.PhantomJS() 替换为 webdriver.Chrome() 并添加 options.add_argument('--headless') 即可。
代码示例(无头 Chrome):
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
def scrape_with_headless_chrome():
# --- 1. 配置 Chrome 无头模式 ---
chrome_options = Options()
chrome_options.add_argument("--headless") # 启用无头模式
chrome_options.add_argument("--window-size=1920,1080") # 设置窗口大小,某些网站需要
chrome_options.add_argument("--disable-gpu") # 某些系统需要禁用 GPU 加速
# 可以添加更多参数来模拟真实浏览器,User-Agent
# chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
# --- 2. 初始化 Chrome 驱动 ---
# 使用 webdriver_manager 自动下载和管理驱动
driver = webdriver.Chrome(options=chrome_options, executable_path=ChromeDriverManager().install())
try:
# --- 3. 后续代码与 PhantomJS 完全一样 ---
url = "https://spa-scraping-demo.herokuapp.com/"
driver.get(url)
# ... (等待、交互、获取数据的代码与之前示例相同) ...
print(driver.title)
links = driver.find_elements(By.TAG_NAME, "a")
for link in links:
print(link.text, "->", link.get_attribute("href"))
finally:
driver.quit()
if __name__ == "__main__":
scrape_with_headless_chrome()
| 特性 | PhantomJS (已弃用) | 无头 Chrome / Firefox (推荐) |
|---|---|---|
| 状态 | 已停止维护 (2025) | 积极维护,持续更新 |
| 安全性 | 低,有未修复漏洞 | 高,随浏览器更新 |
| 兼容性 | 差,无法模拟现代浏览器 | 极佳,与真实浏览器行为几乎一致 |
| 功能 | 基本浏览器功能 | 完整功能,支持 DevTools、GPU、WebGL 等 |
| 性能 | 较慢 | 更快,基于 V8 引擎,优化更好 |
| 易用性 | 配置简单 | 配置稍复杂,但 webdriver_manager 简化了驱动管理 |
虽然 PhantomJS 在历史上曾扮演过重要角色,但现在你应该完全避免在新项目中使用它,请直接采用无头模式的 Chrome 或 Firefox 作为你的爬虫浏览器,它们更强大、更安全、更稳定,是当前业界标准的解决方案。
