gpt4 book ai didi

php - 命令行 cURL 和 PHP cURL 之间的区别

转载 作者:行者123 更新时间:2023-12-01 22:15:02 24 4
gpt4 key购买 nike

我有一个像这样的 cURL 命令:

curl 'https://www.example.com' \
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36' \
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' \
-H 'accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7' \
-H 'authority: www.example.com'

在命令行中执行此操作(例如在我的 Mac 上的终端应用程序中),会得到预期的输出。

(如果您自己测试:如果此输出包含单词 Sicherheitsüberprüfung,则它已被地理封锁,您必须使用德国 IP 来测试它。)

我将确切的命令转移到 PHP cURL,如下所示:

<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers = array();
$headers[] = 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36';
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3';
$headers[] = 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7';
$headers[] = 'Authority: www.example.com';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
curl_close($ch);
echo $result;
?>

当我运行此代码时,我收到一条消息,表明我的请求被识别为自动请求/机器人:它显示 Sicherheitsüberprüfung,意思是安全检查

当然,我对命令行和 PHP cURL 请求使用相同的 IP。

为什么呢?命令行 cURL 和 PHP cURL 不一样吗?

或者我的 PHP 脚本有什么问题吗?

更新

我偶然发现了以下内容:我正在使用 Coda作为我 Mac 上的代码编辑器。它有一个内置的 PHP 渲染引擎。将其与我的 PHP 脚本一起使用,结果符合预期。这与我在命令行中得到的结果相同。

更新2

我做了Jannes Botis在他的回答中建议的内容。然后,我在 Coda 代码编辑器应用程序中运行 PHP 脚本(输出预期的内容),并使用 MAMP 作为本地主机(始终被识别为自动请求)。

我发现使用 MAMP 执行的代码使用的是 HTTP/2,而在 Coda 中执行的代码使用的是 HTTP/1.1。为了解决这个问题,我在脚本中添加了以下内容:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

现在,两者输出完全相同的字符串:

GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Authority: www.example.com

但是,它仍然是一样的:一个正在工作,另一个被识别为自动请求。

最佳答案

尝试在这两种情况下调试请求:

a) 终端:使用curl verbose mode : curl -v 并检查发送的http请求,特别是检查 header 列表

b) php curl:使用 CURLINFO_HEADER_OUT 打印 http 请求:

curl_setopt($ch, CURLINFO_HEADER_OUT, true);

curl_exec($ch);

$info = curl_getinfo($ch);
print_r($info['request_header']);

测试不同的 header ,使其工作的原因是将“Pragma:no-cache” header 添加到请求中:

$headers[] = 'Pragma: no-cache';

另一方面,在终端curl中,我必须将请求 header 大写,例如用户代理等

尝试使用 fsockopen 创建 TCP 连接:

$fp = fsockopen("ssl://"."www.example.com", 443, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$headers = array();
$headers[] = 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36';
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3';
$headers[] = 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7';
$headers[] = 'Authority: www.example.com';
$out .= $headers;
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);

并测试这是否有效。也许问题是 php curl 添加了一些信息到 http 请求,或者问题出在 tcp 连接级别,在那里添加了一些信息。

引用文献

关于php - 命令行 cURL 和 PHP cURL 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58693583/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com