开源是网络抓取真正赖以生存的土壤。负责获取页面、解析标记和驱动浏览器的工具,绝大多数都是免费的、由社区维护的项目,其中最优秀的已经被数百万真实抓取者历练了许多年。你可以阅读代码、提交问题、替换某个组件,并且永远不需要为解析层支付许可费。这种开放性也是该领域发展迅速的原因:2018 年重要的工具阵容,与今天重要的已大相径庭。
本文梳理了当今涵盖绝大多数真实工作的 8 个开源抓取库,跨越 Python、JavaScript 以及位于两者之上的浏览器自动化层。对于每一个,你将了解它是什么、用什么语言编写、擅长什么,以及何时应该使用它;在一行代码比一段话更能说明问题的地方,会附上简短的代码片段。最后的汇总表将每个库映射到其所擅长的任务,这样你就可以规划合适的技术栈,而不是默认使用上次用过的那个。
为什么用开源来做抓取?
抓取很少只用一个工具。你需要一个抓取器来获取 HTML,一个解析器来从中提取数据,以及(当页面只有在 JavaScript 运行后才存在时)一个浏览器自动化层来渲染它。开源库填充了每一个槽位,而且由于它们是模块化的,你可以自由组合:Python 抓取器配 Python 解析器,或者 Node 浏览器驱动连接轻量级 DOM 库。结果是一个你组装而成的技术栈,而不是一个你接受或拒绝的产品。
依赖开源的实际原因不止是成本。像 Scrapy 和 Beautiful Soup 这样的成熟项目已经解决了多年的边界情况,有大型社区回答问题,文档足够深入以带领初学者入门。你不会被锁定在某个供应商的路线图上,当目标网站更改其标记时,你可以当天就修补你的选择器。下面这些库是那些已经赢得信任的,大致从最常见的解析和抓取工具排列到更重型的浏览器自动化选项。
Beautiful Soup(Python)
Beautiful Soup 是经典的 Python HTML 解析器,当前版本是 Beautiful Soup 4。它经久不衰的原因在于一个特质:能够优雅地处理格式不规范的标记。现实世界的 HTML 充满了未闭合的标签和损坏的嵌套,而 Beautiful Soup 能将即使是杂乱的文档也转换成你可以按标签、类或属性搜索的 Python 对象导航树。其 API 读起来几乎像普通英语,这就是为什么它是初学者通常首先学习的解析器。
当标记不规则、项目规模中小,或可读性比原始速度更重要时,请使用 Beautiful Soup。它本身不获取页面,所以需要与 HTTP 客户端配合使用,而且在处理非常大的文档时比 lxml 慢。对于大多数抓取工作,这个差距永远不会成为问题。我们的 Python 中的 Beautiful Soup 指南深入介绍了其选择器和树导航。
from bs4 import BeautifulSoup soup = BeautifulSoup(html, "html.parser") title = soup.find("h1").text links = [a["href"] for a in soup.select("a[href]")]
Scrapy(Python)
Scrapy 不是解析器,而是一个完整的爬取框架,它仍然是构建大规模爬虫的 Python 开发者的首选。在大多数库只做一件事的地方,Scrapy 提供了完整的流程:一个并发获取多个页面的异步引擎、请求调度、链接跟随、重试,以及将结构化数据内置导出到 JSON、CSV 或 XML。它专为需要将工作组织成爬虫、条目定义和处理流程(而不是单个脚本)的大量页面抓取项目而构建。
当规模和结构是重点时,请使用 Scrapy:定期爬取、数以万计的 URL,或者必须经历清洗和存储步骤的数据。这种能力的代价是比快速抓取解析脚本更陡峭的学习曲线和更多的设置,因此对于一次性页面来说是杀鸡用牛刀。它可以跨 Linux、Windows 和 BSD 系统移植,由大型社区支持,并且可以通过添加新行为而不触及核心来进行扩展。像普通 HTTP 客户端一样,原生 Scrapy 不执行 JavaScript,但它与浏览器工具集成,用于目标需要渲染的情况。
import scrapy class BookSpider(scrapy.Spider): name = "books" start_urls = ["https://books.toscrape.com"] def parse(self, response): for book in response.css("article.product_pod"): yield {"title": book.css("h3 a::attr(title)").get()}
lxml(Python)
lxml 是 Python 解析器中的速度选项。基于 C 语言库 libxml2 和 libxslt 构建,它解析大型 HTML 和 XML 文档的速度比纯 Python 解析器快得多,并且提供完整的 XPath 1.0 支持,让你可以对深度嵌套的标记进行精确、富有表现力的查询。当你处理数千份文档或从结构化 XML 数据源中提取数据时,这种性能差异就是选择它的理由。
当速度重要、文档较大,或者你需要 XPath 而不是 CSS 选择器时,请使用 lxml。代价是它比 Beautiful Soup 更严格,因此非常破碎的标记可能会绊倒它,而且 API 对初学者不那么友好。许多团队同时使用两者:将 lxml 作为 Beautiful Soup 的底层解析器,兼得宽容导航和快速解析两者之长。如果你在权衡查询风格,XPath 与 CSS 选择器对两者进行了正面比较。
Requests 和 HTTPX(Python)
Requests 是大多数 Python 爬虫的起点 HTTP 客户端。它做好一件事:发送请求并返回响应,会话、Cookie、请求头和重定向都在干净的 API 中处理好。它不解析 HTML,也不运行 JavaScript,所以单独使用时只能看到服务器返回的原始标记。对于静态页面、公共目录以及任何直接返回 HTML 或 JSON 的端点,这就已经足够了,而且由于没有浏览器开销,速度很快。
HTTPX 是值得了解的现代搭档:一个几乎完全兼容的 API,增加了原生异步支持和 HTTP/2,当你想在不搭建完整框架的情况下并发发出许多请求时,这一点很重要。当你想要的内容存在于初始响应中时,将其中任一作为抓取层,然后与 Beautiful Soup 或 lxml 配合,将该响应转化为结构化数据。共同的局限性是其速度优势的另一面:两者都无法抓取用客户端 JavaScript 构建内容的页面,因为两者都不执行任何脚本。
import requests resp = requests.get("https://example.com") print(resp.status_code) # 200 html = resp.text # raw HTML, ready to parse
Cheerio(JavaScript)
Cheerio 是 Node.js 世界中快速、轻量的 HTML 解析器,是早期依赖 jQuery 风格选择的 Node 抓取工具的精神继承者。它在解析过的 DOM 上实现了熟悉的 jQuery 风格 API,因此你使用与在浏览器中相同的选择器来选取元素,但没有任何浏览器的重量。它的一个突出特点是让你可以快速从文档中挑选元素,而无需编写复杂的正则表达式,这简化了提取过程并保持代码的可读性。
当你用 JavaScript 抓取,且页面内容存在于服务端渲染的 HTML 中时,请使用 Cheerio。它纯粹是一个解析器,所以它需要与一个抓取调用(内置的 fetch、axios 或类似工具)配合以先获取标记,而且与任何静态解析器一样,它不运行客户端脚本。对于动态页面,你需要升级到完整的浏览器工具。我们关于如何 用 Node.js 构建网络爬虫的演示展示了 Cheerio 在完整流程中的使用。
const cheerio = require("cheerio"); const $ = cheerio.load(html); const title = $("h1").text(); const links = $("a[href]").map((i, el) => $(el).attr("href")).get();
Selenium(多语言)
Selenium 是浏览器自动化工具,也是该类别中支持最广泛、文档最完善的选项。它驱动一个真实的浏览器(Chrome、Firefox 及其他),因此页面完全按照用户看到的方式加载,包括 JavaScript。这使它成为动态网站的答案,在这些网站上,你下载的 HTML 几乎是空的,直到脚本运行并注入内容。由于它控制的是真实的浏览器,它也可以点击按钮、填写表单、滚动页面以及等待元素出现,这对于只有在交互后才加载的内容至关重要。其 WebDriver 协议有 Python、Java、JavaScript、Ruby 和 C# 的绑定,几乎适合任何技术栈。
当目标在客户端渲染,普通请求返回没有用处的数据,或者你需要在几个步骤中模拟真实用户时,请使用 Selenium。代价是重量:运行浏览器比 HTTP 请求更慢、更耗资源。只在真正需要渲染的地方使用它,其他静态内容保留更轻量的抓取解析技术栈。更广泛的模式,请参阅 如何爬取 JavaScript 网站。
浏览器自动化解决了渲染问题,但解决不了封锁问题,而这通常是你会遇到的下一道墙。无论你用哪个开源库进行解析,Crawlbase Crawling API 都可以作为其底层抓取层:你发送 URL,它在自己这端处理轮换 IP、对 JavaScript 重度页面的浏览器渲染以及封锁重试,然后将干净的 HTML 直接返回到 Beautiful Soup、lxml、Cheerio 或 Scrapy 爬虫中。它与你的技术栈协同工作而不是替代它,因此你保留解析逻辑,不必再维护反封锁基础设施。
Playwright(多语言)
Playwright 是现代浏览器自动化库,由 Microsoft 构建,旨在通过单一 API 驱动 Chromium、Firefox 和 WebKit。与旧工具相比,它依赖自动等待,在元素准备就绪之前暂停,而不是强制你手动添加等待时间,这使动态页面的爬虫明显更可靠。它有 Python、JavaScript、Java 和 .NET 的官方绑定,并开箱即用支持无头或完整浏览器运行。
当你需要抓取 JavaScript 重度或交互式网站,并希望比旧自动化工具更干净、更稳定的体验时,请使用 Playwright。它与 Selenium 做的是同样的基本工作,渲染真实页面并支持点击、填写表单和导航,只是使用了许多团队认为更快编写和调试的更新 API。代价与任何渲染工具相同,都是浏览器开销。我们的 Playwright 网络抓取指南涵盖了完整的设置。
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto("https://example.com") html = page.content() # fully rendered DOM browser.close()
Puppeteer(JavaScript)
Puppeteer 是普及了无头 Chrome 用于抓取和测试的 Node.js 浏览器自动化库。由 Chrome 团队维护,它让你从 JavaScript 对 Chromium 浏览器进行精细控制:导航、等待选择器、在页面内执行代码、拦截网络请求以及捕获截图或 PDF。对于希望在一种语言中端到端完成工作的 JavaScript 开发者来说,它是天然的渲染工具。
当你的技术栈是 Node.js 且你需要渲染或与动态页面交互时,请使用 Puppeteer。它默认专注于 Chromium,而 Playwright 跨越三个浏览器引擎,所以选择通常取决于跨浏览器覆盖对你是否重要。与每种浏览器工具一样,预期资源使用量比普通 HTTP 抓取更高,并将其保留给真正需要真实浏览器的页面。
两者在抓取方面高度重叠。Puppeteer 是已建立的 Node.js 和 Chromium 选择,有大量示例,而 Playwright 增加了一流的多浏览器支持、更多语言绑定和内置自动等待。如果你已经在 Node 上且只针对 Chromium,Puppeteer 是一个不错的默认选择。如果你还需要 Firefox 和 WebKit,或者你用 Python 编写,Playwright 通常是更容易的路径。
各库并排比较
这 8 个工具适合少数几个槽位:获取 HTML、解析 HTML,或用真实浏览器渲染 HTML。这张表将每个库映射到它所在的语言和它擅长的任务,这样你就可以将你的目标对应到表上,并组装技术栈,而不是猜测。
| 库 | 语言 | 最适合 |
|---|---|---|
| Beautiful Soup | Python | 解析杂乱或不规则的 HTML |
| Scrapy | Python | 大规模爬取和流程 |
| lxml | Python | 快速解析、大型文档、XPath |
| Requests / HTTPX | Python | 抓取静态页面和 API |
| Cheerio | JavaScript | Node 中快速的 jQuery 风格解析 |
| Selenium | 多语言 | 渲染动态页面并与其交互 |
| Playwright | 多语言 | 现代、多浏览器渲染 |
| Puppeteer | JavaScript | Node 中的无头 Chromium |
注意没有任何一行是万能答案。一个真实的爬虫会组合使用它们:Python 静态工作用 Requests 加 Beautiful Soup,Node 中的抓取调用后接 Cheerio,爬取规模扩大时用 Scrapy,页面只有在 JavaScript 运行后才存在时用 Selenium、Playwright 或 Puppeteer。技巧在于将槽位与目标匹配,而不是选择一个最爱。
如何选择合适的库
三个问题可以解决大部分决策。首先,你的项目用什么语言?Python 有最深厚的抓取生态系统(Requests、Beautiful Soup、lxml、Scrapy),而 JavaScript 依赖 Cheerio 进行解析和 Puppeteer 进行渲染。Selenium 和 Playwright 跨语言,所以两边都适合。其次,页面是在服务端还是客户端渲染其内容?静态 HTML 只需要抓取器加解析器;用 JavaScript 构建自己的页面需要浏览器工具。第三,规模是多少?一次性页面需要轻量的抓取解析脚本,而需要队列、重试和导出的数千个页面则指向 Scrapy。
对于初学者,Beautiful Soup 和 Cheerio 有最平缓的学习曲线,读起来接近普通语言。对于大型或定期爬取,Scrapy 的结构会带来回报。对于动态目标,如果你想要现代 API 和多浏览器支持,就从 Playwright 开始,或者如果你留在 Node 和 Chromium 上,就用 Puppeteer。将工具与答案匹配,技术栈就会自然组装起来。
负责任地抓取
无论你构建什么技术栈,都要有节制地抓取。遵守网站的服务条款和其 robots.txt,专注于公开可用的数据而非你无权访问的任何内容,并保持合理的请求频率,不要给你所依赖的服务器造成压力。负责任的节奏也是实用的:温和的、有清晰标识的流量远比激进的爬取更不容易被限速或封锁,因此好的礼仪和可靠的抓取往往指向同一个方向。更广泛的方法,请参阅如何 在不被封锁的情况下抓取网站。
核心要点
- 开源主导技术栈。驱动抓取的抓取器、解析器和浏览器驱动都是免费的、由社区维护的项目,你可以阅读、扩展和组合。
- 没有单一最佳库。一个真实的爬虫组合了抓取器、解析器,有时还有浏览器,因此要为任务匹配每个工具,而不是选择一个最爱。
- Python 和 JavaScript 领先。Python 带来了 Requests、Beautiful Soup、lxml 和 Scrapy;JavaScript 带来了 Cheerio 和 Puppeteer;Selenium 和 Playwright 跨越两者。
- 只在必要时才渲染。对静态页面使用抓取器和解析器,只有当页面需要 JavaScript 才能显示时,才使用 Selenium、Playwright 或 Puppeteer。
- 封锁是一个独立的问题。选择正确的库使你的代码正确,但在数千个请求中保持畅通(轮换、大规模渲染和重试)超出了任何单一解析器的构建范围。
常见问题
什么是开源抓取库?
它们是免费的、由社区维护的代码库,处理网络抓取的构建模块:通过 HTTP 获取页面、解析返回的 HTML 或 XML,以及(对于动态网站)驱动真实浏览器渲染 JavaScript。由于源代码是开放的,你可以检查它、扩展它,并将不同库的组件组合成一个技术栈,而无需为解析层付费。
哪个开源库最适合网络抓取?
没有单一最佳的,因为它们做不同的事情。对于 Python 中的静态页面,Requests 抓取加 Beautiful Soup 解析是最简单可靠的技术栈。需要速度或 XPath 时加 lxml,大规模爬取时用 Scrapy,当目标只有在 JavaScript 渲染内容时才用 Selenium、Playwright 或 Puppeteer。在 Node 中,Cheerio 处理解析,Puppeteer 处理渲染。
哪个库最适合 JavaScript 重度网站?
使用浏览器自动化库,因为普通 HTTP 客户端永远不会运行 JavaScript。Selenium 是支持和文档最广泛的,Playwright 是具有多浏览器支持和自动等待的现代选项,Puppeteer 是针对 Chromium 的 Node.js 项目的自然选择。这三者都在真实浏览器中加载页面,使脚本执行并注入内容。
我应该使用 Beautiful Soup 还是 lxml?
当标记混乱或可读性重要时使用 Beautiful Soup,因为它能优雅地处理损坏的 HTML,读起来几乎像普通英语。当你解析大型文档、需要最大速度或想要 XPath 查询时使用 lxml。两者并不互斥:lxml 可以作为 Beautiful Soup 的底层解析器,同时提供宽容的导航和快速解析。
开源库能处理封锁和 CAPTCHA 吗?
通常不能。解析和爬取库提取并组织数据,但在数千个请求中保持畅通是一个独立的问题:轮换 IP、真实节奏、浏览器渲染以及失败重试。这项工作超出了任何单一抓取库的构建范围,这就是为什么团队经常将他们的开源解析器与托管抓取层(如爬取 API)配对使用。
我可以在一个项目中混合使用不同语言的库吗?
你通常每个爬虫保持一种语言,但可以在其中自由混合库。一个 Python 爬虫可能使用 HTTPX 抓取、Beautiful Soup 或 lxml 解析,以及 Playwright 渲染少数需要浏览器的页面。Node 爬虫将抓取调用与 Cheerio 配对,并为动态目标添加 Puppeteer。这些库的模块化设计正是使这种组合变得容易的原因。
大规模爬取任何站点,无需与基础设施对抗。
Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。
