嘿!作为一名拥有 5 年以上经验的网络抓取专家,我有机会使用所有顶级 Python 库。在本指南中,我将分享我所学到的有关使用 Python 进行网络抓取的所有知识。
我们将深入了解每个库的工作原理以及使用它们的最佳情况。我的目标是为您提供为任何项目选择正确的抓取工具所需的见解。让我们开始吧!
核心 HTTP 库:Python 抓取的基础
任何网页抓取项目的第一步都是下载网页内容。 Python 的 Requests 和 HTTPX 库使这变得非常简单。
请求:久经考验的真实 HTTP 库
Requests 是最流行的 HTTP 请求 Python 库,根据 89 年 Python 开发人员调查,2020% 的 Python 开发人员使用该库。
很容易看出原因。使用 Requests 发出请求只需一行代码:
response = requests.get(‘https://www.example.com‘)
Requests 通过相同的简单接口支持所有常见的 HTTP 动词,例如 GET、POST、PUT、DELETE。它处理:
- 对 URL 字符串中的参数进行编码
- 添加标头和 cookie
- 发送多部分文件上传
- 对 JSON 请求主体进行编码
它会根据 HTTP 标头自动解码响应内容。不需要像其他语言那样手动调用 json() 。
请求甚至处理:
- 以下重定向
- 重试请求
- 持久连接
- 浏览器风格的cookie
它是您在简单的界面中进行基本 HTTP 请求所需的一切。根据我的经验,我建议所有刚开始使用 Web 抓取的 Python 开发人员使用 Requests。
HTTPX:更高级的异步 HTTP 客户端
HTTPX 提供了相同的简单请求式接口,以及适用于复杂用例的高级功能:
- 异步请求
- HTTP / 2支持
- 超时处理
- Cookie 持久性
- 连接池
- 代理
- 类似浏览器的缓存
异步发出请求对于性能尤其重要。以下是如何使用 HTTPX 同时获取多个 URL:
import httpx
async with httpx.AsyncClient() as client:
futures = [client.get(url) for url in urls]
for response in await httpx.async_list(futures):
print(response.url)
根据基准测试,对于大批量请求,HTTPX 的吞吐量比 Requests 高 2-3 倍。
我建议使用 HTTPX 来构建更高级的异步网络抓取工具。与多处理和多线程相结合,它可以实现极高性能的数据收集管道。
解析 HTML:从网页中提取数据
获得 HTML 内容后,就可以对其进行解析并提取所需的数据。 Beautiful Soup 和 LXML 是两个不错的选择。
Beautiful Soup:简单的 HTML 解析
Beautiful Soup 名副其实,是一个用于在 Python 中解析和迭代 HTML 和 XML 的优秀库。根据 2020 年 Python 调查,它是用于处理 HTML 和 XML 的最流行的 Python 库。
它提供了用于导航、搜索和修改解析树的简单方法。例如,我们可以从页面中提取所有链接,如下所示:
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, ‘html.parser‘)
for link in soup.find_all(‘a‘):
print(link.get(‘href‘))
BeautifulSoup API 主要包括:
- 方法如
find()
,find_all()
搜索节点 - 属性如
name
,string
,attrs
访问节点属性 - 方法如
get_text()
,decompose()
修改节点
它不使用像 jQuery 这样的开闭标签汤,我个人认为它更容易阅读和编写。
根据我的经验,Beautiful Soup 非常适合中小型网络抓取任务。主要限制是速度,因为它的底层是纯 Python 代码。
LXML:更快的基于 C 的 HTML/XML 解析
如果您正在解析大量大型 XML/HTML 文档,我建议使用 长XML 反而。它是一个用于 Python 的 XML 解析库,构建在高性能 C 库 libxml2 和 libxslt 之上。
根据基准测试,LXML 可以解析 XML 文档 速度快 40 倍以上 比美丽汤和用途 内存减少 80%.
以下是使用 LXML 从电子商务网站提取产品信息的示例:
from lxml import html
root = html.parse(page)
# XPath query to extract product attributes
for product in root.xpath(‘//div[@class="product"]‘):
name = product.xpath(‘.//h2[@class="name"]/text()‘)[0]
description = product.xpath(‘.//div[@class="description"]/text()‘)[0]
price = product.xpath(‘.//span[@class="price"]/text()‘)[0]
print(name, description, price)
LXML 支持解析 HTML 和 XML,并提供 CSS 选择器、XPath 和 XSLT 支持来提取数据。
对于大规模生产爬虫,我建议使用 LXML 来获得巨大的解析速度增益。它是任何语言中最快的 XML 处理库之一。
浏览器自动化:抓取 JavaScript 网站
对于严重依赖 JavaScript 呈现内容的网站来说,传统的 HTTP 请求和 HTML 解析是不够的。一些例子包括:
- 单页应用程序 (SPA),例如 Gmail 和 Twitter
- 站点通过 AJAX 请求动态加载数据
- 使用 React 和 Angular 等 JavaScript 框架的页面
对于这些情况,您需要在真实浏览器中执行 JavaScript 以允许加载完整页面内容。 Python 拥有用于自动化浏览器的优秀库,例如 Selenium 和 Playwright。
Selenium:现有的浏览器自动化工具
十多年来,Selenium 一直是首选的浏览器自动化库。
它允许您以编程方式控制 Chrome、Firefox 和 Safari 等网络浏览器。您可以执行的一些示例操作:
- 导航至页面
- 单击按钮和链接
- 填写并提交表格
- 滚动页面
- 截图
- 捕获 HTML 快照
- 断言页面内容
一切都来自简单的 Python 界面。
以下是如何使用 Selenium 登录站点并提取私人数据:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://example.com")
driver.find_element(By.NAME, ‘username‘).send_keys(‘myuser‘)
driver.find_element(By.NAME, ‘password‘).send_keys(‘secret‘)
driver.find_element(By.ID, ‘login‘).click()
# Wait for dashboard page to load
WebDriverWait(driver, 10).until(EC.title_contains("Dashboard"))
print(driver.find_element(By.ID, ‘apiKey‘).text)
driver.quit()
以下是有关 Selenium 使用情况的一些关键统计数据:
- 仅在 BrowserStack 上每天执行超过 500,000 个 Selenium 测试
- StackOverflow 上有 6.5 万个与 Selenium 相关的问题
- 100,000+ Selenium GitHub star
然而,Selenium 有一些痛点:
- 脆弱的测试容易破坏浏览器版本
- 页面元素等待和超时需要特殊处理
- 跨环境管理驱动程序和浏览器的挑战
- 日志记录、报告和并行化的额外工作
因此,虽然 Selenium 仍然是测试和自动化的主要工具,但我通常更喜欢使用更现代的浏览器自动化库来执行一般的网络抓取任务。
剧作家:Selenium 的下一代继承者
Playwright 是微软开发的一个新的浏览器测试和自动化库。它提供了比 Selenium 更可靠、更高效、更简单的 API。
Playwright 的一些主要优势:
- 交互前自动等待元素 – 不再出现不稳定的定位器超时!
- 可靠的自动等待页面加载 – Playwright 等待网络空闲,避免竞争条件。
- 网络安全已禁用 – 页面正确加载,无需检测自动化。
- 功能齐全的API – 浏览器上下文、工作人员、内置移动模拟。
- 良好的可调试性 – 包括鼠标移动可视化、屏幕截图捕获、逐步调试。
- 跨浏览器支持 – 可跨 Chromium、Firefox 和 WebKit 使用一致的 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")
page.type("#username", "myuser")
page.type("#password", "secret")
page.click("#login")
page.wait_for_load_state(‘domcontentloaded‘)
print(page.text_content(‘#apiKey‘))
browser.close()
更加坚固可靠! Playwright 还提供了出色的内置处理程序,用于:
- 截图、视频、追踪、控制台日志
- 移动仿真和响应测试
- 网络操纵、缓存、节流
- 浏览器上下文管理
- 多页面架构和工作人员
出于这些原因,我建议在当今大多数浏览器自动化用例中使用 Playwright 而不是 Selenium。
用于大规模爬行的强大抓取框架
虽然上述库提供了构建块,但对于大规模抓取项目,您需要一个强大的框架。 Scrapy 和 Selenium Grid 是不错的选择。
Scrapy:重型网页抓取框架
如果您需要在大型网站上抓取数千或数百万个页面,Scrapy 是我的首选。
一些主要优点:
- 异步爬虫 – Scrapy 处理异步页面请求、爬行和数据处理。
- 强大的提取工具 – 用于解析页面的 CSS 和 XPath 查询引擎。
- 项目管道 – 干净的数据存储和处理架构。
- 节流和缓存 – 用于遵守抓取延迟和 robots.txt 的内置插件。
- 缩放 – 海量数据流的分布式爬取支持。
下面是一个用于爬行 HackerNews 的 Spider 类示例:
import scrapy
class HackerNewsSpider(scrapy.Spider):
name = ‘hackernews‘
def start_requests(self):
yield scrapy.Request(‘https://news.ycombinator.com/‘, callback=self.parse)
def parse(self, response):
for post in response.css(‘.athing‘):
yield {
‘title‘: post.css(‘.titlelink::text‘).get(),
‘votes‘: post.css(‘.score::text‘).get()
}
根据 Crawl.be 基准测试,Scrapy 可以爬过 每秒 175 页 每个爬虫。通过分布式爬行,它已被用于从海量站点中抓取数 TB 的数据。
如果您要大规模抓取,Scrapy 是我推荐的 Python 抓取框架的首选。异步架构和爬网管理工具非常适合大型爬网作业。
Selenium Grid:可扩展的浏览器自动化
Selenium Grid 允许您通过在多台机器上分布测试来扩展浏览器自动化。这消除了在一台机器上按顺序运行所有测试的瓶颈。
该架构由三个组件组成:
- 硒中心 – 用于将测试分发到节点的中央集线器
- Node – 连接到集线器运行测试的 Selenium 实例
- 测试 – 在节点上运行的测试逻辑
运行一个简单的网格:
# On main host
java -jar selenium-server-standalone.jar -role hub
# On each node
java -Dwebdriver.chrome.driver=chromedriver -jar selenium-server-standalone.jar -role node -hub <hubIp:port>
通过设置此网格,您可以跨数千个节点大规模并行化 Playwright、Selenium 或任何浏览器测试。
根据我的经验,Selenium Grid 对于扩展大型浏览器自动化和 JavaScript 抓取工作负载至关重要。分布式架构使您可以抓取更多数量级的页面。
无头浏览器:轻量级 JavaScript 执行
无头浏览器提供 JavaScript 支持,无需管理浏览器 UI 的所有开销。一些最重要的选项是:
- 剧作家 和 硒 可以在轻量级无头模式下运行。
- 碎片 在 Selenium、Playwright 或原始请求之上提供简单的浏览器抽象。
- 皮皮特师 提供Python接口来控制无头Chrome Puppeteer库。
例如,以下是如何在 Playwright 中启用无头模式:
from playwright.sync_api import sync_playwright
browser = playwright.chromium.launch(headless=True)
现在您可以执行 JavaScript、渲染网页、生成屏幕截图、提取 HTML – 所有这些都无需明显运行 Chromium 的资源使用。
根据测试,无头浏览器比完整的 Chrome 或 Firefox 使用的 CPU 少 75%,内存少 65%。
对于繁重的抓取工作负载,我建议使用无头浏览器选项。它们以较低的开销提供了 JavaScript 渲染的强大功能。
您应该使用哪个 Python 库来进行网页抓取?
有了所有这些选项,您如何为网络抓取项目选择正确的 Python 库?
以下是基于我见过的最常见用例的快速指南:
基本 HTTP 请求 – 使用请求库。
表现很重要 – HTTPX 用于异步,LXML 用于快速 HTML 解析。
重型 AJAX/JS 站点 – 选择 Playwright 或 Selenium 浏览器自动化。
大规模爬行 – Scrapy 网页抓取框架。
跨浏览器测试 – 用于分发的 Selenium Grid。
轻量级 JS 渲染 – 无头浏览器选项。
不存在一刀切的解决方案。关键是使用适合您特定需求的正确工具:
- 简单 – 美丽的汤和要求
- 迅速的 – Gevent、HTTPX、LXML
- JavaScript的 – 剧作家、Selenium、Pyppeteer
- 鳞片 – Scrapy 集群、Selenium Grid
- 可扩展性 – Scrapy 中间件和扩展
根据您的用例评估这些因素。通常最好的方法是结合库——例如,将 Scrapy 与 Playwright 和 LXML 结合使用。
Python 生态系统提供了惊人的灵活性。借助所有这些强大的库,您可以构建能够从几乎任何网站提取数据的抓取工具。
由 Python 提供支持的抓取
感谢您阅读有关用于网络抓取的顶级 Python 库的概述!我试图分享我作为抓取专家的经验中学到的重要知识。
以下是一些关键要点:
- 要求 – 简单的 HTTP 请求。
- HTTPX – 高级异步 HTTP 客户端。
- 美丽的汤 – 简单的 HTML 解析和迭代。
- 长XML – 超快的 HTML/XML 解析器。
- 硒 – 经验丰富的浏览器自动化工具。
- 剧作家 – Selenium 的下一代继承者。
- Scrapy – 重型网络爬行框架。
- 硒网格 – 可扩展的分布式浏览器测试。
- 无头浏览器 – 轻量级 JS 执行。
使用 Python 进行网页抓取从未如此简单。借助这个令人惊叹的库生态系统,您可以构建抓取工具来从几乎任何网站提取数据。
如果您还有其他问题,请告诉我!我总是很乐意更多地讨论 Python 抓取工具和策略。