当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] Curl 与 PowerShell:比较用例

作者:精品下载站 日期:2024-12-14 20:53:23 浏览:13 分类:玩电脑

Curl 与 PowerShell:比较用例


Curl 是一种多功能工具,允许您在各种情况下进行 HTTP 调用。它主要在 Linux 世界中存在多年,但最近在 Windows 10 中出现。但是脚本语言 PowerShell 可以完成与 curl 类似的任务。 PowerShell 是curl 的一个很好的替代品吗?有什么区别?让我们来看看吧!

在本文中,让我们并排比较 PowerShell 和curl,以发现哪一个在不同的环境中最有效。我们还将在不同的用例中进行比较,以便您根据您的个人情况做出最佳决定。

打破神话:PowerShell Cmdlet Curl

在我们深入研究本文之前,让我们打破一个流行的神话,即 PowerShell 的 Invoke-WebRequest 或 Invoke-RestMethod cmdlet 是 curl 的“替代品”。这根本不是真的。通过查看这些命令的帮助内容,可以清楚地看出每个命令都有不同的功能和用例。

看看curl文档是怎么说的:

curl 是一种使用受支持的协议之一(DICT、FILE、FTP、FTPS、GOPHER、HTTP、HTTPS、IMAP、IMAPS、LDAP、LDAPS、POP3、POP3S、RTMP)从服务器传输数据或向服务器传输数据的工具、RTSP、SCP、SFTP、SMB、SMBS、SMTP、SMTPS、TELNET 和 TFTP)。

该命令设计为无需用户交互即可运行。 Curl 提供了大量有用的技巧,例如代理支持、用户身份验证、FTP 上传、HTTP post、SSL 连接、cookie、文件传输恢复、Metalink 等等。

现在将其与 Invoke-WebRequestInvoke-RestMethod cmdlet 帮助文档进行比较。

Invoke-WebRequest cmdlet 向网页或 Web 服务发送 HTTP、HTTPS、FTP 和 FILE 请求。它解析响应并返回表单、链接、图像和其他重要 HTML 元素的集合。”

Invoke-RestMethod cmdlet 向表述性状态传输 (REST) Web 服务发送 HTTP 和 HTTPS 请求,这些服务返回丰富的结构化数据。 PowerShell 根据数据类型格式化响应。对于 RSS 或 ATOM 源,PowerShell 返回 Item 或 Entry XML 节点。对于 JavaScript 对象表示法 (JSON) 或 XML,PowerShell 将内容转换或反序列化为对象。”

详细分析每个工具的描述方式,curl 旨在成为通过多种协议从服务器传输数据或向服务器传输数据的首要解决方案。

与此相比,Invoke-WebRequestInvoke-RestMethod PowerShell cmdlet 专注于与服务器进行更常见的通信。这些 PowerShell cmdlet 还提供了通过 PowerShell 使用对象来处理返回数据的丰富体验。

Bash 与 PowerShell 中的长参数

由于curl 不像PowerShell 那样是一种脚本语言,因此它依赖于执行它的命令shell。大多数时候,命令 shell 是 Bash。

PowerShell cmdlet 和curl 都可能需要不同的参数,这些参数可能远远超过终端的宽度。为了使语法更易于阅读,每种 shell 脚本语言都有自己的处理方式。

以下面的代码为例。此示例演示使用少量数据将 HTTP POST 动词发送到 URL。这段代码可以放在一行上,但它很快就会开始覆盖屏幕或需要滚动。要修复此问题,在 Bash 中,您可以使用反斜杠将命令继续到新行。

curl --header "Content-Type: application/json" \
      --request POST \
      --data '{"title":"test post","user":2}' \
        https://jsonplaceholder.typicode.com/posts

将换行方法与使用任一 cmdlet 的 PowerShell 进行对比。通过使用 splatting,您可以构建执行相同任务的相同请求。

$param = @{
    Uri         = "<https://jsonplaceholder.typicode.com/posts>"
    Method      = "Post"
    Body        = '{"title":"test post","user":2}'
    ContentType = "application/json"
}
Invoke-RestMethod @param

您还可以混合和匹配展开参数和命名参数,如下所示。

$main = @{
    Uri         = "<https://jsonplaceholder.typicode.com/posts>"
    ContentType = "application/json"
}
$param = @{
    Method      = "Post"
}

Invoke-RestMethod @main @param -Body '{"title":"test post","user":2}'

使用 REST API

REST API 是与许多产品相关的常见功能。由于查询 REST API 是curl 和 PowerShell cmdlet 的常见用法,因此我们首先比较和对比这两个工具处理它们的各种方式。

请注意,您将学习的任务同样适用于标准 HTTP URI。 curl 和 PowerShell cmdlet 都可以与任何 HTTP 端点配合使用。

从 REST API 获取数据

首先,最简单的演示任务是从 REST API 获取响应。 curl 和 PowerShell cmdlet 都可以使用单个 URI 参数来执行此操作,如下所示。您可以在下面看到每个立即返回 JSON 响应的正文。

> curl <https://jsonplaceholder.typicode.com/todos/1>

[玩转系统] Curl 与 PowerShell:比较用例

PS> Invoke-WebRequest '<https://jsonplaceholder.typicode.com/todos/1>'
PS> Invoke-RestMethod '<https://jsonplaceholder.typicode.com/todos/1>'

[玩转系统] Curl 与 PowerShell:比较用例

与 Invoke-WebRequest 不同,Invoke-RestMethod cmdlet 会自动将响应数据从 JSON 转换为 PowerShell 对象。但您可以使用 ConvertFrom-Json cmdlet 对 Invoke-WebRequest 执行相同的操作,如下所示。

(Invoke-WebRequest '<https://jsonplaceholder.typicode.com/todos/1>').Content |
    ConvertFrom-Json

向 REST API 提交数据

Curl 和 PowerShell cmdlet 还可以使用 POST 动词将数据提交到 URI。通过 POST 提交数据时,您通常还会包含两个工具都具备的正文。

您可以在下面看到,使用curl的--request参数和Invoke-RestMethodMethod参数,您可以指定动词。对于正文,您将在curl 中使用--data 参数,并在Invoke-RestMethod 中使用Body 参数。

curl <https://jsonplaceholder.typicode.com/posts> --request POST --data "title=test post&user=2"

Invoke-RestMethod <https://jsonplaceholder.typicode.com/posts> -Method Post -Body @{;user=2}

默认情况下,curl 和 Invoke-RestMethod 将使用内容类型 application/x-www-form-urlencoded 发送 POST 请求。

如果 API 只允许特定的内容类型,或者您需要通过参数手动指定一种内容类型。下面您可以看到,curl 使用更通用的 header 参数,而 Invoke-RestMethod cmdlet 允许您使用 ContentType 单独指定内容类型范围。

## Curl
--header "Content-Type: application/json"

## Invoke-RestMethod
-ContentType application/json

您还可以使用curl的快捷方式-H参数来代替--header

使用自定义标头

在上面的示例中,您了解了如何使用curl 和PowerShell 将内容类型标头传递到URI。如果您愿意,您还可以同时添加更多内容。

要在curl中添加更多标头,您只需添加另一个--header-H,提供您想要发送的标头的键和值,如下所示。

curl -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      --request POST \
      -d '{"title":"test post","user":2}' \
         https://jsonplaceholder.typicode.com/posts

您也可以在 PowerShell 中执行相同的操作,如下所示。通过将包含标头键/值对的哈希表传递给 Headers 参数,您可以发送任意数量的标头。

$param = @{
    Uri     = "<https://jsonplaceholder.typicode.com/posts>"
    Body    = @{ title = "Test" }
    Method  = "Post"
}
Invoke-RestMethod @param -Headers @{ Accept = "application/json" }

解析 HTTP 响应

现在您已经了解了如何获取简单数据,让我们从中提取一些有用的信息。

与curl 相比,使用PowerShell 的一大优势是解析响应的本机能力。由于curl是一个实用程序而不是脚本语言,因此您通常需要使用另一个实用程序来解析响应。为了公平竞争,你会看到很多人使用 Python 或 Perl 或使用名为 jq 的工具来解析curl 的响应。 Jq 是一个允许您解析 JSON 数据的实用程序。

为了演示解析,使用前面的示例,您可能只想从响应中提取标题。下面的示例使用curl 通过--request 参数显式指定使用GET 动词(curl 默认所有请求都为GET)。该示例还使用静默 -s 参数来避免一些屏幕上的统计信息。

curl https://jsonplaceholder.typicode.com/todos/1 --request GET -s | jq .title

[玩转系统] Curl 与 PowerShell:比较用例

由于您了解到 Invoke-WebRequest cmdlet 和 Invoke-RestMethod cmdlet 之间的主要区别在于 Invoke-RestMethod 的本机解析能力对于响应,我们在此示例中跳过 Invoke-WebRequest

下面您将看到,与curl 一样,显式指定GET 方法不会改变任何内容。另请注意,命令和参数包含在括号中。这允许您使用点表示法引用对象属性 Title

(Invoke-RestMethod https://jsonplaceholder.typicode.com/todos/1 -Method Get).Title

[玩转系统] Curl 与 PowerShell:比较用例

抓取网页

当您从网页提取数据时,您可能需要对输出进行额外的处理。在 Bash 中,这可能意味着使用 HTML 解析器,例如 html-xml-utils 包提供的 hxselect。相比之下,PowerShell 的 Invoke-WebRequest cmdlet 可以自动解析您想要的大部分内容。

为了进行演示,我们从 www.google.com 中提取所有 HTML <a> 引用。

在 Bash 中,您需要安装 html-xml-utils 软件包。要查询网页并使用 hxselect 解析它,您必须将 Web 响应标准化为 xhtml (-x) 格式。您还需要使用文本处理工具(例如 Grep)来过滤和选择输出。

下面的示例命令使用 Grep 的正则表达式匹配 (-P) 和仅匹配 (-o) 将结果拆分到各自的行中:

curl https://www.google.com -s \
     | hxnormalize -x | hxselect "a" \
     | grep -Po '(?<=href=")[^\"]+(?=")'

[玩转系统] Curl 与 PowerShell:比较用例

在 PowerShell 中,您只需指定您想要这些 <a> 标记中的链接的 href 属性。

(Invoke-WebRequest www.google.com).links.href

[玩转系统] Curl 与 PowerShell:比较用例

提交表格

表单有很多用途,例如登录、搜索、上传等。虽然 PowerShell 可以轻松地从网页中选择表单并提供要填写的哈希表,但使用 Curl + Bash 需要更多工作。

在 PowerShell 中,您必须首先收集表单、填写并提交。下面的示例调用 $Form.fields 来查看表单的所有可用字段。然后用响应填充 $Result,您可以通过 $Result.links 检查 google 结果。

$Form = (Invoke-WebRequest www.google.com).forms[0]
$Form.fields['q'] = "Best PowerShell cmdlets"
$Result = Invoke-WebRequest -Uri "www.google.com$($Form.Action)" -Body $Form.Fields

使用 Curl,您必须努力查找字段,然后自己指定它们。第一个命令的输出显示有一个可用于搜索查询的 q 表单字段。然后,我在提交请求时指定要填充该字段的数据:

curl https://www.google.com -s \
      | hxnormalize -x | hxselect "form" | hxselect "input" \
      | grep -Po ""
 curl -F q="Curl is amazing at some things" https://www.google.com

[玩转系统] Curl 与 PowerShell:比较用例

使用网络会话/Cookie

当您需要在命令之间保存 cookie 时,例如网站登录以访问私人页面,您还需要在会话之间保存 cookie。

Curl 要求您使用“cookie jar”来保存这些 cookie,然后您可以在登录后将其用作输入“cookie”。您必须做一些工作才能找到所需的实际表单提交数据。

使用curl,您可以指定用于身份验证的用户名和密码以及curl“cookie jar”的位置。然后,使用从该调用获得的 cookie,在后续调用中指定“cookie jar”,如下所示。

curl --user <username>:<password> --cookie-jar ./filename <https://someSite.com>
curn --cookie ./filename <https://someSite.com/important>

PowerShell 还允许您使用 Invoke-WebRequest cmdlet 的 SessionVariable 参数来存储和使用 cookie/会话。

SessionVariable 将存储返回的 cookie。完成后,您可以使用 WebSession 参数将该 cookie 传递给后续请求。下面您可以看到填写表单并使用之前查询表单时返回的相同 cookie 的示例。

$result = Invoke-WebRequest -Uri https://someSite.com  -SessionVariable ss
$LoginForm = $result.Forms[0]
$LoginForm.Fields["user"] = "username"
$LoginForm.Fields["password"] = "password"
$result = Invoke-WebRequest -Uri $LoginForm.Action -WebSession $ss -Method Post

概括

PowerShell 的 Web cmdlet Invoke-WebRequestInvoke-RestMethod 是有用的 Web 查询和解析 cmdlet。它们与curl有一些相似之处,但是,正如您所看到的,这两种工具的方法不同。

由于 cmdlet 是 PowerShell 脚本语言的一部分,因此它们是根据 PowerShell 构建的。 PowerShell 方法在这方面与curl 实用程序不同,因为curl 必须依赖其他语言和工具来执行相同的任务。

相关链接

如需将许多curl 命令转换为PowerShell 格式的便捷PowerShell 模块,请查看Curl2PS。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯