Nstproxy 现已升级为 Nstdata。了解此次变化。 周一至周五 09:00 - 18:00(UTC+08:00) 公司地址
19H MAXGRAND PLAZA NO.3 TAI YAU STREET SAN PO KONG, KOWLOON HONG KONG
©2026 NST LABS TECH LTD. 保留所有权利。 2026 年 Python 网络爬虫指南Marcus ChenProduct & Network Architect
使用Python进行Web抓取:2026完整指南
TL;DR
- 使用
requests 和 Beautiful Soup 当允许的页面在其初始 HTML 响应中返回所需数据时。
- 当 JavaScript 在初始响应后创建内容时,使用浏览器渲染或托管的爬虫 API;解析一个空的 HTML 外壳无法解决渲染问题。
- 设置超时,识别你的客户端,按来源节奏请求,并明确处理
429 和其他可重试的错误。
- 在每个提取的记录中存储源 URL、提取时间、响应状态、解析器版本和验证结果。
- Nstdata Crawl 提供站点发现、递归爬取、JavaScript 渲染、多种输出类型和内置代理路由;Python 仍然负责下游解析和质量检查。
在使用 Python 抓取网站之前你需要什么?
你需要 Python 3、目标源和使用的许可,以及检查页面实际响应的方式。创建一个虚拟环境并安装静态示例中使用的两个软件包:Nstdata Crawl 产品 是获取和转换步骤的一个托管选项。
python3 -m venv .venv
source .venv/bin/activate
python -m pip install requests beautifulsoup4
在 Windows PowerShell 中,使用 .venv\Scripts\Activate.ps1 激活。使用浏览器的网络面板检查数据是否出现在文档响应、后来的 API 响应或渲染的 DOM 中。在收集数据之前,检查源的条款和适用的 robots 规则。 描述了爬虫访问规则;这不是内容许可。
如果你使用 Nstdata,你还需要一个帐户和一个 API 密钥。记录的头是 x-api-key。托管的爬虫请求不需要单独的代理主机、端口、用户名、密码或协议值。
Python 网页爬虫是如何工作的?
爬虫有四个阶段:请求、解析、验证和持久化。请求阶段获取响应或渲染页面。解析器将页面元素映射到字段。验证拒绝缺失或不可信的输出。持久化存储接受的记录及足够的来源信息以调试或删除它。将所有四个阶段混合在一个表达式中,使故障难以定位。
HTML 不是一个稳定的数据库模式。当站点重新设计卡片或插入同意屏幕时,CSS 选择器可能会失效。给每个解析器一个版本并对其进行针对性页面模板的测试。对于重复运行,保存一小段原始 HTML 或渲染输出样本,以便你能够区分源的变化和代码回归。
如何使用 Requests 和 Beautiful Soup 抓取静态页面?
当所需的内容存在于初始 HTML 中时,使用此方法。示例仅将 example.com 用作连接性和解析演示;将其替换为经过批准的源和你已检查的选择器。
方法 1:获取并解析一个 HTML 页面
import requests
from bs4 import BeautifulSoup
url = "https://example.com/"
response = requests.get(
url,
headers={"User-Agent": "ExampleResearchBot/1.0 (contact: team@example.org)"},
timeout=(5, 20),
)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
heading = soup.select_one("h1")
if heading is None:
raise ValueError("未找到预期的 h1")
record = {"source_url": response.url, "title": heading.get_text(" ", strip=True)}
print(record)
步骤 3. 保存结果,包括提取时间戳和解析器版本。在生产中,还要保存响应状态和内容哈希。raise_for_status() 捕获 HTTP 错误,但它不能判断 200 响应是否是登录页面或同意墙。
限制: requests 不会执行页面 JavaScript。JavaScript 页上的空选择器可能意味着该内容从未出现在 HTTP 响应中。
如何在不混合字段的情况下提取重复记录?
将每个字段查找的范围确定为一个容器元素。独立选择所有标题和所有价格可能会在卡片缺失元素时配对错误的值。
方法 2:解析卡片列表
步骤 1. 检查一个已批准的页面并识别一个稳定的容器选择器及其内部的标题、价格和链接选择器。用在该页面上观察到的选择器替换下面的示例选择器。
from urllib.parse import urljoin
def parse_cards(html: str, page_url: str) -> list[dict[str, str]]:
soup = BeautifulSoup(html, "html.parser")
items = []
for card in soup.select("article.product-card"):
title = card.select_one(".product-title")
price = card.select_one(".price")
link = card.select_one("a[href]")
if not (title and price and link):
continue
items.append({
"title": title.get_text(" ", strip=True),
"price_text": price.get_text(" ", strip=True),
"url": urljoin(page_url, link["href"]),
})
return items
步骤 3. 将记录样本与页面进行比较。在您了解站点的语言环境和货币之前,保留 price_text;过早将显示值转换为数字可能会失去意义。如果源揭示了稳定的产品标识符,请添加它。
限制: 这些选择器是示意性的,而不是 example.com 的选择器或每个商店承诺的 schema。
如何抓取 JavaScript 页面或整个网站?
当初始 HTML 省略内容或您需要跨链接页面进行发现时,请使用呈现和爬虫层。Nstdata Crawl 可以递归呈现 JavaScript 和发现页面。它的 Crawl API 文档 显示了单页面同步端点和站点作业端点。响应是提供者特定的;在映射到您的应用程序模式之前检查它。
方法 3: 从 Python 调用 Nstdata Crawl
步骤 1. 在 shell 中设置您的 API 密钥。切勿将其硬编码在脚本中或提交到仓库。
export NSTDATA_API_KEY="your-api-key"
步骤 2. 提交一个经过批准的页面,并检查 JSON 响应。端点和头信息遵循当前的 Nstdata 文档;在运行之前查看您帐户的实时文档中的确切请求体字段。
import os
import requests
api_key = os.environ["NSTDATA_API_KEY"]
response = requests.post(
"https://api.nstdata.io/api/v1/crawl/scrape/submit-sync",
headers={"x-api-key": api_key, "Content-Type": "application/json"},
json={"url": "https://example.com/", "formats": ["markdown"]},
timeout=(5, 90),
)
response.raise_for_status()
print(response.json())
步骤 3. 对于站点爬行,提交文档化的 /api/v1/crawl 作业,设定 maxDepth、maxPages、includeUrls 和 excludeUrls 的界限;然后轮询其状态并检索页面。在将每个页面插入到数据集中之前进行验证。大输出可能由存储令牌引用,而不是内联显示。
限制: Nstdata 是一个获取和转换服务,而不是任意商业模式提取器。您的 Python 代码仍决定哪些字段构成被接受的记录。密钥是实时调用的先决条件;上面的示例并不是声称的实时测试。
为什么 Python 抓取器返回空或不正确的数据?
| 症状 | 可能原因 | 下一个检查 |
|---|
选择器返回 None | 选择器错误或 JavaScript 渲染的内容 | 检查 response.text 和浏览器网络面板 |
200 与无关文本 | 同意、登录或错误页面 | 检查标题和所需页面元素 |
429 或重复超时 | 请求速率或源过载 | 减慢速度,遵循 Retry-After,并查看允许的访问 |
| 重复记录 | 通过查询变体或重复发现同一页面 | 定义规范 URL 和源 ID |
| 损坏的字符 | 响应编码不正确 | 检查标题、字节和文档字符集 |
不要绕过访问控制以让抓取器通过。如果源要求身份验证或限制自动访问,请使用允许的 API,获得许可或选择其他源。
如何使输出足够可靠以用于 AI 产品?
记录 source_url、fetched_at、parser_version 和内容哈希值。验证必需字段、语言、页面类型及明显的错误页面。将原始和处理后的结果分别保存,以便能够重放解析器修复。对于 RAG,在每个块中附加源 URL 和文档版本,并测试答案是否引用当前记录。对于模型训练,将权利和源出处添加到数据集清单中。
如何在调度之前测试 Python 抓取工具?
围绕页面类型而非仅仅是 URL 构建测试用例。包括一个正常页面、一个缺失字段、一个重定向、一个 HTTP 错误、如果可能出现的同意或登录页面,和一个相关的 JavaScript shell。将源 HTML 保存到受控测试位置,并断言解析器返回有效记录或明确拒绝理由。仅检查 requests.get() 是否返回 200 的测试将会遗漏最有可能污染数据集的失败。
将抓取测试与解析器测试分开。解析器测试用例应能够在没有网络访问的情况下重放,以便快速诊断选择器更改。一个小型在线烟雾测试可以确认当前源仍与测试用例匹配。当网站发生变化时,更新测试用例和解析器,经过审查新页面后再进行;在所有页面通过之前,不要默默放宽验证。
对于生产运行,按源和页面类型记录计数:提交、抓取、拒绝、接受、重试和终端失败。在每次部署后审查一部分接受和拒绝的输出。如果验证器将 cookie 横幅视为文章,则高接受率并不自动良好。
如何选择本地 Python 和托管爬虫 API 之间?
当你的团队可以掌控请求的速度、重试、提取和操作时,选择本地抓取稳定的静态页面。当页面依赖于 JavaScript、需要跨网站发现或浏览器和网络维护会分散产品架构时,选择托管渲染或抓取。在同一授权样本上测试这两种路径,并比较接受的记录、诊断工作量和端到端延迟。
在任何情况下, Python 应用程序应该定义最终的数据合同。对于 AI 知识库,该合同可能包括文档标题、规范 URL、Markdown 内容、标题路径和源时间戳。对于商业数据,它可能包括产品 ID、变体、货币、显示价格、可用性和证据 URL。 如果这些业务字段尚未经过验证,通用的页面到 JSON 输出只是一开始的起点。
从一个模板开始,证明数据是正确的,然后添加页面和并发。如果源提供了符合使用文档的馈送或 API,请在解析 HTML 之前对此进行评估。它可能提供比网站更稳定的标识符和更改信号,同时仍然需要许可证和使用审查。
常见问题
问:Beautiful Soup 对于 JavaScript 渲染的页面够用吗?
不够。Beautiful Soup 解析它接收到的 HTML;它不会执行 JavaScript。如果所需内容在初始响应中缺失,请使用渲染路径。
不。Nstdata 返回页面内容和支持的文物。你的应用程序映射并验证其产品所需的字段。
至少存储源 URL、获取时间、解析器版本、验证状态和内容哈希值。
支持 JavaScript 渲染,成功率达 99.8%
将任意网站转换为 Markdown、HTML、JSON、链接、PDF 等格式,无需管理爬取基础设施。