Scrapling 命令行接口全解析:shell、extract 与 install 三大能力及其源码实现
【免费下载链接】Scrapling🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!项目地址: https://gitcode.com/GitHub_Trending/sc/Scrapling
本篇围绕 Scrapling 自 v0.3 引入的命令行接口(CLI)展开:先讲清安装与依赖准备,再逐一拆解scrapling shell(交互式抓取 Shell)、scrapling extract(免编程的终端抓取命令组)与scrapling install(Fetcher 依赖管理)三大能力。读完后,你将能在不写任何 Python 脚本的前提下完成页面抓取、格式转换与内容提取,并理解每条命令背后的源码调用链。
一、CLI 总览:三大核心能力
Scrapling 从 v0.3 版本开始内置了一套完整的命令行接口(当前仓库版本为 0.4.13,见 pyproject.toml),它提供三种主要能力(引自 docs/cli/overview.md):
- Interactive Shell(交互式 Shell):基于 IPython 的交互式网页抓取 Shell,内置大量快捷键与实用工具;
- Extract Commands(提取命令):无需任何编程即可在终端抓取网站内容;
- Utility Commands(工具命令):安装与管理工具。
最典型的使用方式:
# 启动交互式 shell scrapling shell # 将页面内容转换为 Markdown 并保存到文件 scrapling extract get "https://example.com" content.md # 获取任意命令的帮助 scrapling --help scrapling extract --help从源码看,整个 CLI 基于 Click 框架构建。scrapling/cli.py 中通过main.add_command(...)依次注册了四个命令/命令组:
# scrapling/cli.py # Adding commands main.add_command(install) main.add_command(shell) main.add_command(extract) main.add_command(mcp)其中extract是一个@group()命令组,下面挂载了get、post、put、delete、fetch、stealthy-fetch六个子命令;顶层还注册了--version选项,运行scrapling --version会输出形如Scrapling, version 0.4.13的版本信息。此外,[pyproject.toml](https://link.gitcode.com/i/50d264d5edbee3736238ee02ee5dccf0) 的[project.scripts]将scrapling入口绑定到scrapling.cli:main,并额外暴露了独立的scrapling-mcp入口(同样指向scrapling.cli:mcp`)。
需要注意:CLI 依赖 Click,若未安装任何 extras,导入时会抛出ModuleNotFoundError并提示安装——这为下面“安装要求”一节提供了源码依据。
二、安装要求:shell依赖组与scrapling install
docs/cli/overview.md 明确了使用 CLI 的两步准备:
第一步,安装shell额外依赖组:
pip install "scrapling[shell]"第二步,安装各 Fetcher 的运行时依赖:
scrapling install该命令会下载所有浏览器、系统依赖以及指纹操作(fingerprint manipulation)所需的依赖。
2.1shell依赖组到底装了什么
从 pyproject.toml 的[project.optional-dependencies]可以看到shell组的实际构成:
shell = [ "IPython>=8.37", # The last version that supports Python 3.10 "markdownify>=1.2.0", "scrapling[fetchers]", ]即:交互式 Shell 需要的 IPython、HTML 转 Markdown 用的 markdownify,以及整个fetchers组(curl_cffi、playwright、patchright、browserforge、click>=8.3.0等)。由于shell组传递依赖了fetchers,安装scrapling[shell]后所有 Fetcher(HTTP/动态/隐身浏览器)即可用。项目要求 Python >= 3.10。
2.2scrapling install的底层实现
scrapling install命令的完整实现位于 scrapling/cli.py:
@command(help="Install all Scrapling's Fetchers dependencies") @option( "-f", "--force", "force", is_flag=True, default=False, type=bool, help="Force Scrapling to reinstall all Fetchers dependencies", ) def install(force): # pragma: no cover if force or not __PACKAGE_DIR__.joinpath(".scrapling_dependencies_installed").exists(): __Execute( [python_executable, "-m", "playwright", "install", "chromium"], "Playwright browsers", ) __Execute( [python_executable, "-m", "playwright", "install-deps", "chromium"], "Playwright dependencies", ) from tld.utils import update_tld_names update_tld_names(fail_silently=True) # if no errors raised by the above commands, then we add the below file __PACKAGE_DIR__.joinpath(".scrapling_dependencies_installed").touch() else: print("The dependencies are already installed")从源码结构看,该命令做了三件事:
- 执行
python -m playwright install chromium下载 Chromium 浏览器; - 执行
python -m playwright install-deps chromium安装操作系统级依赖; - 调用
tld库的update_tld_names更新公共后缀(eTLD)数据,失败时静默处理。
全部成功后,会在scrapling包目录下创建标记文件.scrapling_dependencies_installed。下次运行scrapling install时检测到该文件即直接输出 "The dependencies are already installed",不再重复下载;使用--force(或-f)标志可强制重新安装所有 Fetcher 依赖。
三、交互式 Shell:scrapling shell
3.1 命令参数
scrapling/cli.py 中shell命令定义如下:
@command(help="Interactive scraping console") @option( "-c", "--code", "code", is_flag=False, default="", type=str, help="Evaluate the code in the shell, print the result and exit", ) @option( "-L", "--loglevel", "level", is_flag=False, default="debug", type=Choice(["debug", "info", "warning", "error", "critical", "fatal"], case_sensitive=False), help="Log level (default: DEBUG)", ) def shell(code, level): from scrapling.core.shell import CustomShell console = CustomShell(code=code, log_level=level) console.start()参数说明:
| 参数 | 短选项 | 默认值 | 说明 |
|---|---|---|---|
--code | -c | 空字符串 | 在 shell 中执行代码、打印结果后退出(便于脚本化) |
--loglevel | -L | debug | 日志级别,可选debug/info/warning/error/critical/fatal(不区分大小写) |
对应用法:
# 启动交互式 shell scrapling shell # 执行代码后退出(适合脚本化) scrapling shell -c "get('https://quotes.toscrape.com'); print(len(page.css('.quote')))" # 设置日志级别 scrapling shell --loglevel infoCustomShell是 scrapling/core/shell.py 中的自定义 IPython 子类,它自动预注入了get/post/put/delete/fetch/stealthy_fetch快捷函数、page/response/pages页面跟踪变量以及Fetcher、AsyncFetcher、DynamicFetcher、StealthyFetcher、Selector等常用类,并附带view()、uncurl()、curl2fetcher()等实用工具。完整的快捷键、页面历史管理与 curl 命令转换等用法,可参见专题文档 docs/cli/interactive-shell.md。
四、scrapling extract命令组:终端免编程抓取
这是 CLI 中最实用的部分。extract命令组的帮助文本为:
Fetch web pages using various fetchers and extract full/selected HTML content as HTML, Markdown, or extract text content.
运行scrapling extract --help可看到全部六个子命令:
Usage: scrapling extract [OPTIONS] COMMAND [ARGS]... Fetch web pages using various fetchers and extract full/selected HTML content as HTML, Markdown, or extract text content. Options: --help Show this message and exit. Commands: get Perform a GET request and save the content to a file. post Perform a POST request and save the content to a file. put Perform a PUT request and save the content to a file. delete Perform a DELETE request and save the content to a file. fetch Use DynamicFetcher to fetch content with browser... stealthy-fetch Use StealthyFetcher to fetch content with advanced...完整示例与逐命令参数说明见 docs/cli/extract-commands.md。下面结合源码讲清其工作机制与共性选项。
4.1 输出格式由文件扩展名决定
所有extract子命令都接受两个位置参数:URL和OUTPUT_FILE。输出格式完全由文件扩展名决定——这一规则在 scrapling/core/shell.py 的Convertor类中有明确映射:
class Convertor: """Utils for the extract shell command""" _extension_map: Dict[str, extraction_types] = { "md": "markdown", "html": "html", "txt": "text", }xxx.md:将 HTML 内容转换为 Markdown(经由markdownify);xxx.html:原样保存 HTML 内容;xxx.txt:提取纯文本,并通过get_all_text(ignore_tags=("script", "style", "noscript", "svg", "iframe"))忽略噪声标签、压缩连续空白。
若扩展名不属于这三种,Convertor.write_content_to_file会直接抛出ValueError("Unknown file type: filename must end with '.md', '.html', or '.txt'")。相对路径输出时,scrapling/cli.py 的__Request_and_Save会将其解析为相对于当前工作目录的绝对路径:
# Handle relative paths - convert to an absolute path based on the current working directory output_path = Path(output_file) if not output_path.is_absolute(): output_path = Path.cwd() / output_file if ai_targeted: kwargs.setdefault("block_ads", True) response = fetcher_func(url, **kwargs) Convertor.write_content_to_file(response, str(output_path), css_selector, main_content_only=ai_targeted)常用示例(引自 docs/cli/extract-commands.md):
# 将 HTML 内容转换为 Markdown 并保存 scrapling extract get "https://blog.example.com" article.md # 原样保存 HTML 内容 scrapling extract get "https://example.com" page.html # 保存网页的干净纯文本 scrapling extract get "https://example.com" content.txt4.2 CSS 选择器与--ai-targeted模式
所有子命令都支持-s/--css-selector选项,用于只提取页面中匹配的部分(返回全部匹配项)。选择器解析发生在Convertor._extract_content中:若指定了css_selector,会以page.css(css_selector)得到Selectors集合后逐块输出,否则输出整页内容。
--ai-targeted是所有 extract 命令共有的标志位:开启后只提取<body>主内容,剥离script/style/noscript/svg噪声标签,移除可被用于提示注入的隐藏元素(CSS 隐藏、aria-hidden、<template>标签)、零宽 Unicode 字符和 HTML 注释;对浏览器命令还会自动开启广告拦截。这一行为同样体现在上述__Request_and_Save源码中(ai_targeted时默认设置block_ads=True,并传入main_content_only=True)。其实现细节位于 scrapling/core/shell.py 的_strip_noise_tags与_sanitize_for_ai方法。
4.3 HTTP 命令:get / post / put / delete
这四个命令通过__http_command统一转发到scrapling.fetchers.Fetcher的同名方法:
def __http_command(method_name, url, output_file, css_selector, ai_targeted=False, **kwargs): from scrapling.fetchers import Fetcher __Request_and_Save(getattr(Fetcher, method_name), url, output_file, css_selector, ai_targeted=ai_targeted, **kwargs)它们的公共选项由装饰器工厂_common_http_options统一注入,docs/cli/extract-commands.md 中的scrapling extract get --help输出即为权威参考:
| 选项 | 说明 | 默认值 |
|---|---|---|
-H, --headers TEXT | HTTP 头,格式"Key: Value",可多次使用 | — |
--cookies TEXT | Cookie 串,格式"name1=value1;name2=value2" | — |
--timeout INTEGER | 请求超时(秒) | 30 |
--proxy TEXT | 代理地址,格式"http://username:password@host:port" | — |
-s, --css-selector TEXT | 只提取匹配元素(返回全部匹配) | — |
-p, --params TEXT | 查询参数"key=value",可多次使用 | — |
--follow-redirects / --no-follow-redirects | 是否跟随重定向 | True |
--verify / --no-verify | 是否校验 SSL 证书 | True |
--impersonate TEXT | 伪装浏览器,如chrome;逗号分隔(chrome,firefox,safari)时随机选择 | — |
--stealthy-headers / --no-stealthy-headers | 使用隐身浏览器请求头 | True |
--ai-targeted | 仅提取主内容并净化隐藏元素 | False |
post与put额外支持请求体选项(由_data_options注入):
-d, --data TEXT:表单数据字符串,如"param1=value1¶m2=value2";-j, --json TEXT:JSON 数据字符串,源码中通过__ParseJSONData用orjson解析,非法 JSON 会抛出ValueError。
典型用法:
# GET:带 Cookie、自定义 UA 与超时 scrapling extract get "https://scrapling.requestcatcher.com" content.md --cookies "session=abc123; user=john" scrapling extract get "https://api.site.com" data.json -H "User-Agent: MyBot 1.0" --timeout 60 # POST:提交表单数据 / JSON 数据 scrapling extract post "https://api.site.com/search" results.html --data "query=python&type=tutorial" scrapling extract post "https://api.site.com" response.json --json '{"username": "test", "action": "search"}' # PUT scrapling extract put "https://scrapling.requestcatcher.com/put" results.html --data "update=info" --impersonate "firefox" # DELETE scrapling extract delete "https://scrapling.requestcatcher.com/delete" results.html --impersonate "chrome"一个值得注意的实现细节:__BuildRequest会对含逗号的--impersonate值做拆分(kwargs["impersonate"] = [browser.strip() for browser in ...split(",")]),单值则保持字符串。tests/cli/test_cli.py 中的test_impersonate_comma_separated与test_impersonate_single_browser两个用例正好验证了这一行为。
4.4 浏览器命令:fetch 与 stealthy-fetch
fetch与stealthy-fetch分别调用DynamicFetcher.fetch与StealthyFetcher.fetch,处理 JavaScript 动态内容与反爬防护站点。二者共享由_common_browser_options注入的选项:
| 选项 | 说明 | 默认值 |
|---|---|---|
--headless / --no-headless | 是否无头模式运行浏览器 | True |
--disable-resources / --enable-resources | 丢弃非必要资源以提速 | False |
--network-idle / --no-network-idle | 等待网络空闲 | False |
--timeout INTEGER | 超时(毫秒) | 30000 |
--wait INTEGER | 页面加载后的额外等待(毫秒) | 0 |
--wait-selector TEXT | 等待某 CSS 选择器出现后再继续 | — |
-s, --css-selector TEXT | 只提取匹配元素 | — |
--locale TEXT | 用户语言区域 | 系统默认 |
--real-chrome / --no-real-chrome | 使用本机安装的 Chrome | False |
--proxy TEXT | 代理地址 | — |
-H, --extra-headers TEXT | 额外请求头,可多次使用 | — |
--executable-path TEXT | 自定义 Chromium 兼容浏览器可执行文件路径;未设置时回退环境变量SCRAPLING_EXECUTABLE_PATH | — |
--dns-over-https / --no-dns-over-https | DNS 走 Cloudflare DoH,防代理场景下的 DNS 泄露 | False |
--block-ads / --no-block-ads | 拦截已知广告/跟踪域名 | False |
--ai-targeted | 仅提取主内容并净化隐藏元素 | False |
stealthy-fetch在此之上另有四个隐身增强选项(scrapling/cli.py):
| 选项 | 说明 | 默认值 |
|---|---|---|
--block-webrtc / --allow-webrtc | 完全阻止 WebRTC | False |
--solve-cloudflare / --no-solve-cloudflare | 自动通过 Cloudflare 质询 | False |
--allow-webgl / --block-webgl | 是否允许 WebGL | True |
--hide-canvas / --show-canvas | 给 canvas 操作添加噪声 | False |
典型用法:
# 等待 JS 加载并结束网络活动 scrapling extract fetch "https://scrapling.requestcatcher.com/" content.md --network-idle # 等待特定内容出现 scrapling extract fetch "https://scrapling.requestcatcher.com/" data.txt --wait-selector ".content-loaded" # 可见浏览器模式运行(调试友好) scrapling extract fetch "https://scrapling.requestcatcher.com/" page.html --no-headless --disable-resources # 通过 Cloudflare 质询并只提取正文链接 scrapling extract stealthy-fetch "https://nopecha.com/demo/cloudflare" data.txt --solve-cloudflare --css-selector "#padded_content a" # 配合代理匿名抓取 scrapling extract stealthy-fetch "https://site.com" content.md --proxy "http://proxy-server:8080"选择策略可参考官方公式:简单网站/博客/新闻用get;现代 Web 应用或动态内容用fetch;受保护站点、Cloudflare 或反爬系统用stealthy-fetch。
关于--executable-path的回退逻辑,scrapling/cli.py 的__build_browser_kwargs实现了“命令行参数优先、环境变量次之”的取值顺序,而 tests/cli/test_cli.py 中的test_extract_fetch_with_executable_path、test_extract_fetch_executable_path_env_fallback、test_extract_fetch_without_executable_path三个用例精确验证了这三种情形(含“两者都未设置时不向 Fetcher 传executable_path”)。
4.5 Docker 方式使用
无需本地安装 Python 环境时,可直接使用官方镜像(示例引自 docs/cli/extract-commands.md):
docker run -v $(pwd)/output:/output pyd4vinci/scrapling extract get "https://blog.example.com" /output/article.md该镜像基于仓库中的 Dockerfile 构建,抓取结果挂载到宿主机的./output目录。
五、工具命令:install 之外,还有 mcp
除install外,顶层命令组还注册了mcp命令(scrapling/cli.py),用于运行 Scrapling 的 MCP(Model Context Protocol)服务器,把抓取能力暴露给 AI 客户端:
| 参数 | 默认值 | 说明 |
|---|---|---|
--http | False | 以 streamable-http 传输运行(否则为 stdio) |
--host | 0.0.0.0 | HTTP 传输时监听的主机 |
--port | 8000 | HTTP 传输时监听的端口 |
--executable-path | None | 浏览器工具使用的自定义 Chromium 兼容可执行文件 |
--auth-token | None | HTTP 模式下要求客户端携带Authorization: Bearer <token>;也可用环境变量SCRAPLING_MCP_AUTH_TOKEN避免出现在进程列表中 |
--allowed-host | 空 | 开启 DNS-rebinding 防护,仅接受指定主机(可重复,如mcp.example.com:8000);监听公网地址时推荐启用 |
scrapling-mcp是它的独立入口别名(见 pyproject.toml 的[project.scripts]),二者等价。更多 MCP 用法可参考 docs/ai/mcp-server.md。
六、测试验证与延伸阅读
CLI 的行为有大量自动化测试背书,全部位于 tests/cli/ 目录:
- tests/cli/test_cli.py:覆盖
--version输出、shell/mcp命令的参数转发、六个 extract 子命令的参数解析(headers/cookies/timeout/proxy/params/css-selector 等)、--executable-path与环境变量回退、--impersonate的逗号拆分逻辑; - tests/cli/test_shell_functionality.py:验证交互式 Shell 的快捷函数、
page/pages页面管理与Convertor的内容转换; - tests/cli/test_shell_core.py 同目录下的 tests/core/test_shell_core.py:对 Shell 核心机制做进一步单测。
测试普遍采用 Click 的CliRunner配合unittest.mock.patch拦截 Fetcher 调用,既确认退出码为 0,也校验了参数是否正确传入底层 Fetcher——这正是上文参数表格默认值与行为的来源。
进一步阅读建议:
- docs/cli/extract-commands.md:每个 extract 子命令的完整
--help输出与更多实战示例; - docs/cli/interactive-shell.md:Shell 快捷键、页面历史、curl 转换等细节;
- docs/fetching/choosing.md:理解 Response 对象与三类 Fetcher 的选择依据(extract 命令正是这三类 Fetcher 的终端化封装)。
总结
Scrapling 的 CLI 以 Click 为骨架,把库级的三类 Fetcher 能力完整搬到了终端:install负责一次性准备浏览器与系统依赖(以标记文件做幂等控制);shell提供带页面跟踪与 curl 转换的 IPython 环境;extract则以“URL + 输出文件”两个位置参数为入口,用文件扩展名决定 HTML/Markdown/纯文本三种输出形态,并通过统一的公共选项工厂暴露了请求头、Cookie、代理、浏览器伪装、隐身增强等几乎所有代码级参数。对需要快速落地抓取或为 AI 准备干净语料的场景,这套命令行工具提供了免编程、可脚本化的完整路径。
【免费下载链接】Scrapling🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!项目地址: https://gitcode.com/GitHub_Trending/sc/Scrapling
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考