任何网页抓取应用最基本的操作,就是先获取 HTML 文件,然后再对其进行处理。当然,实现这一目标的方法多种多样。不过,在今天的文章中,我们将探讨如何在 Python 中使用 CURL 进行网页抓取。以下是本文将涵盖内容的一小部分预览:
- 什么是 cURL 以及如何通过命令行调用它
- 如何使用 cURL 命令从任意网站收集信息
- 如何在 Python 中使用 cURL 构建一个简单的网页爬虫

任何网页抓取应用最基本的操作,就是先获取 HTML 文件,然后再对其进行处理。当然,实现这一目标的方法多种多样。不过,在今天的文章中,我们将探讨如何在 Python 中使用 CURL 进行网页抓取。以下是本文将涵盖内容的一小部分预览:
简而言之,cURL 主要是一款用于从服务器获取数据的命令行工具。我知道一提到命令行,事情可能看起来很复杂。不过,我可以向您保证,正如您将在本文中发现的那样,实际上 cURL 可能是您作为程序员使用过的最简单的工具之一。
要在命令行中使用 cURL,只需打开一个新的终端窗口,输入 `curl` 并跟上你想要抓取的 URL。例如:
~ » curl 'https://api.ipify.org?format=json'
这条简单的命令正在访问 ipify 的 API,向服务器请求信息,就像传统浏览器所做的那样。此示例的输出将是一个包含您 IP 地址的 JSON 对象。虽然看起来可能不像,但您刚刚为未来的网页爬虫搭建了基础架构。这一切仅需一行代码。
cURL 实际上是一款更高级的工具。若想深入了解 cURL 的使用方法,可查阅官方文档。您也可以使用 `--help` 选项来查看各种可用选项。
在上例中,我们从 ipify 服务器收到的响应是一个 JSON 文件。这是因为该特定的 API 端点返回的是 JSON 格式的数据。在网页抓取方面,你通常会遇到提供 HTML 文件的传统网站,此时你需要对这些文件进行解析并从中提取数据。
不过,目前我们的重点不在于数据处理,而在于数据提取。虽然我们知道可以使用 cURL 抓取网站,但具体该如何操作呢?如果您尚未尝试过,不妨直接让 cURL 访问任何您确知是传统 HTML 网站的通用 URL。我们以 httpbin.org 为例:
curl 'https://httpbin.org/forms/post'
在终端中输入该命令,你将收到纯 HTML 作为响应:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!-- Example form from HTML5 spec http://www.w3.org/TR/html5/forms.html#writing-a-form's-user-interface -->
<form method="post" action="/post">
<p><label>Customer name: <input name="custname"></label></p>
<p><label>Telephone: <input type=tel name="custtel"></label></p>
<p><label>E-mail address: <input type=email name="custemail"></label></p>
<fieldset>
<legend> Pizza Size </legend>
<p><label> <input type=radio name=size value="small"> Small </label></p>
<p><label> <input type=radio name=size value="medium"> Medium </label></p>
<p><label> <input type=radio name=size value="large"> Large </label></p>
</fieldset>
<fieldset>
<legend> Pizza Toppings </legend>
<p><label> <input type=checkbox name="topping" value="bacon"> Bacon </label></p>
<p><label> <input type=checkbox name="topping" value="cheese"> Extra Cheese </label></p>
<p><label> <input type=checkbox name="topping" value="onion"> Onion </label></p>
<p><label> <input type=checkbox name="topping" value="mushroom"> Mushroom </label></p>
</fieldset>
<p><label>Preferred delivery time: <input type=time min="11:00" max="21:00" step="900" name="delivery"></label></p>
<p><label>Delivery instructions: <textarea name="comments"></textarea></label></p>
<p><button>Submit order</button></p>
</form>
</body>
</html>如你所见,使用 cURL 提取数据是一种直截了当的解决方案,无需实际编写代码。它仅仅是发送一条命令并接收一些信息。如果你想构建一个真正的网页抓取项目,就需要以某种方式利用收集到的数据。而作为程序员,我们希望通过编程方式对数据进行处理。这就是 Python 发挥作用的地方。
毫无疑问,Python 是最受欢迎的编程语言之一。它不仅功能强大,其简洁的语法也使其成为初学者的理想选择。此外,它拥有一个庞大的社区,成员们总是乐于伸出援手。因此,如果你在任何时候遇到问题而陷入困境,不妨在 Stackoverflow 等平台上提问,肯定会有人为你提供帮助。
特别是在网页抓取领域,Python 凭借其丰富的内置包成为绝佳选择。正如本文后文将要介绍的,数据处理需要解析 HTML 文件,从而“挖掘”其中的元素,并从特定网页中仅提取你目标的信息。
到目前为止,我们已经了解了如何在终端中使用 cURL,但如何将其与 Python 集成呢?其实有多种方法可以实现。例如,你可以使用 Python 的 `os` 模块来发送终端命令:
import os
curl = os.system(f'curl "https://httpbin.org/forms/post"')print(curl)
或者,您甚至可以围绕它构建自己的函数,并在整个项目中使用:
import os
def curl(website):
return os.system(f'curl "{website}"')print(curl('https://httpbin.org/forms/post'))
不过,正如我所说,Python 最大的优势之一在于其丰富的包生态。由于 cURL 功能极其多样,若要涵盖所有特性,我们编写的函数将变得异常复杂。因此,与其重复造轮子,我建议直接使用现成的 Python cURL 集成包:PycURL。
根据其官网介绍,PycURL 是 cURL 库的接口,因此继承了 libcURL 的所有功能。简而言之,PycURL 就是我们在 Python 中使用 cURL 的途径。至于安装,与其他 Python 包一样,我们将使用 pip。如果您不熟悉 pip,它是一个 Python 包管理系统,Python 开发者经常使用它来快速安装依赖项。
综上所述,要安装 PycURL,只需在终端中输入以下命令:
~ » pip install pycurl
既然我们正在讨论依赖项和 pip,值得一提的是,Python 社区为 HTML 解析提供了不少解决方案。其中最受欢迎的 HTML 解析包之一就是 BeautifulSoup。在 WebScrapingAPI,我们实际上专门写了一篇博客文章,介绍如何使用 Python 和 BeautifulSoup 提取和解析网页数据。
与 PycURL 一样,安装 BeautifulSoup 也只需一条命令:
~ » pip install beautifulsoup4
既然我们已经讲完了理论部分,并且知道如何在终端和 Python 中使用 cURL,那就让我们直接进入编码环节吧。在本节中,我们将通过构建一个实际的网页抓取工具来学习如何在 Python 中使用 cURL。那么,事不宜迟,让我们开始编码吧!
作为软件工程师,合理规划项目结构至关重要,这样不仅便于我们自己维护和阅读,也能让其他开发者轻松理解。为了保持条理,我们先创建一个新目录来存放所有项目文件。打开一个新的终端窗口,使用 `cd` 命令进入 Desktop 目录,并创建一个名为 `py_scraper` 的新文件夹:
~ » cd desktop && mkdir py_scraper && cd py_scraper
让我简要说明一下我们目前使用的命令:
在您常用的 IDE 中打开项目,并在 `py_scraper` 目录内创建一个名为 ‘scraper.py’ 的新文件。提示:您也可以通过命令行使用以下命令完成此操作:
~/desktop/py_scraper » touch scraper.py && code .
如果你使用的是 VSCode(就像我一样),现在会看到一个类似于下图的窗口:
此时终端应位于 `py_scraper` 目录下。 在编写实际的爬虫代码之前,我们需要做的最后一步是安装之前介绍过的包以及另一个包。但是,我们希望将它们仅限制在 `py_scraper` 目录内(而不是全局安装)。为此,我们需要使用 Python 的虚拟环境。这使我们能够隔离所安装的 Python 解释器、库和脚本。
要在 `py_scraper` 目录内创建一个新的虚拟环境,请使用以下命令:
~/desktop/py_scraper » python3 -m venv env
这将创建一个新的 `env` 文件夹,在安装所需包之前,我们需要先激活该环境。请使用以下命令进行激活:
~/desktop/py_scraper » source env/bin/activate
现在您已经创建并激活了虚拟环境,剩下的就是利用我们之前介绍过的 pip 命令来安装所需的包。
~/desktop/py_scraper » pip install pycurl beautifulsoup4 certify
现在您已准备好使用 PycURL 和 BeautifulSoup。要使用这些包,我们需要先将其导入到 `scraper.py` 文件中。只需在文件顶部添加以下代码片段:
import pycurl
import certify
from io import BytesIO
from bs4 import BeautifulSoup# All our logic will go underneath this line
现在您已导入这些包,让我们来处理网络爬虫的逻辑。根据我们迄今为止的讨论,我们知道需要涵盖两个方面:数据提取和数据处理。第一部分由 PycURL 负责,第二部分由 BeautifulSoup 负责。为了更好的结构,我建议我们将每个部分单独处理。
这里所说的“抓取”,指的是网页抓取工具中的数据提取部分。基于这一概念,并结合通过 PycURL 接口在 Python 中使用 curl 的知识,让我们编写代码:
# Setting global variables
TARGET_URL = 'https://httpbin.org/forms/post'
# Using cURL and Python to gather data from a server via PycURL
buffer = BytesIO()
curl = pycurl.Curl()
curl.setopt(curl.URL, TARGET_URL)
curl.setopt(curl.WRITEDATA, buffer)
curl.setopt(curl.CAINFO, certifi.where())
curl.perform()
curl.close()
# Using BytesIO to retrieve the scraped data
body = buffer.getvalue()
# Saving the output and printing it in terminal
data = body.decode('iso-8859-1')print(data)
在上面的代码中,我们首先声明全局变量 `TARGET_URL`,用于存储我们要提取数据的网站 URL。接下来,我们使用 `BufferIO` 创建一个缓冲区,初始化 PycURL 并设置两个选项:一个用于数据传输,另一个用于存储证书的文件名。最后,我们执行 cURL 操作,并在之后关闭会话。
就这样,您已成功使用 Python 发出 cURL 请求,并在控制台中打印出了 HTML 文件。现在我们需要处理第二部分,即数据处理。
在网页抓取中,如果不对原始数据进行处理,单纯获取数据是毫无意义的。任何网页抓取工具最基本的任务就是从 HTML 中提取数据。以本例为例,假设我们要从 `data` 变量(当前存储了所有抓取到的 HTML)中提取所有位于 `<p>` 标签内的文本。以下是使用 BeautifulSoup 实现的方法:
# Parsing data using BeautifoulSoup
soup = BeautifulSoup(data, 'html.parser')
# Finding elements using BeautifoulSoup
paragraphs = soup.find_all("p")
for p in paragraphs:
print(p.text)如您所见,借助 BeautifulSoup,仅需 4 行代码即可提取所需结果。运行完整脚本后,应能输出从目标网站收集的 HTML 文件中每个段落内的文本。
因此,假设您已按照说明操作,且您的 `scraper.py` 文件包含本节中编写的所有代码,让我们回到终端并运行该脚本:
~/desktop/py_scraper » python3 scraper.py
Customer name:
Telephone:
E-mail address:
Small
Medium
Large
Bacon
Extra Cheese
Onion
Mushroom
Preferred delivery time:
Delivery instructions:
Submit order使用 Python 和 cURL 构建网络爬虫是一个非常有用的项目,也可以作为开发更大规模网络爬取应用的起点。将这两项技术集成的推荐方法是使用 PycURL。你也可以编写自己的接口或函数来在 Python 中与 cURL 交互。这只是需要多花一点时间和精力 :)。
希望本文能成为您学习 cURL、掌握其与 Python 的结合使用以及构建基础网页爬虫的优质资源。此外,我邀请您对代码进行调整并加以改造,使其成为您自己的作品,这样您就能为个人作品集增添又一个项目。

Mihnea-Octavian Manolache 是 WebScrapingAPI 的全栈及 DevOps 工程师,负责开发产品功能并维护确保平台平稳运行的基础设施。