如何通过代理使用CURL?

147
我希望能够设置curl使用代理服务器。URL由HTML表单提供,这没有问题。但是没有代理时它可以正常工作。我在这个和其他网站上找到了代码,但它们都不起作用。如果能帮我找到正确的解决方案,我将非常感激。我觉得以下代码很接近,但我可能错过了什么。谢谢。
下面的代码我从这里改编而来:http://www.webmasterworld.com/forum88/10572.htm,但它返回了一个有关第12行缺少T_VARIABLE的错误消息。
<?

$url = '$_POST[1]';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 0);
curl_setopt($ch, CURLOPT_PROXY, '66.96.200.39:80');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,'GET');
curl_setopt ($ch, CURLOPT_HEADER, 1)
curl_exec ($ch); 
$curl_info = curl_getinfo($ch);
curl_close($ch);
echo '<br />';
print_r($curl_info);
?>

以下内容来自curl通过代理返回无内容

<?

$proxy = "66.96.200.39:80";
$proxy = explode(':', $proxy);
$url = "$_POST[1]";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, $proxy[0]);
curl_setopt($ch, CURLOPT_PROXYPORT, $proxy[1]);
curl_setopt($ch, CURLOPT_HEADER, 1);

$exec = curl_exec($ch);

echo curl_error($ch);
print_r(curl_getinfo($ch));
echo $exec;
?>

pelican-cement.com网站目前已上线,但无法正常工作。

更新:感谢您的所有帮助,我已进行了以上更改。现在它只返回一个空白屏幕。

<?

$url = $_POST['1'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 0);
curl_setopt($ch, CURLOPT_PROXY, '66.96.200.39:80');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,'GET');
curl_setopt ($ch, CURLOPT_HEADER, 1);
curl_exec ($ch); 
$curl_scraped_page = curl_exec($ch);
curl_close($ch);

echo $curl_scraped_page;
?> 

3
第12行缺少一个分号。 - Pekka
另外,您需要将 $url = '$_POST[1]' 更改为 $url = $_POST[1] - 否则,$url 将成为一个字符串,而不是您想要的 URL。 - yoavmatchulsky
此外,$_POST 数组中的键是字符串而不是整数,因此您需要将其写成 $_POST['1'] - fiiv
<? $url = $_POST['1']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 0); curl_setopt($ch, CURLOPT_PROXY, '66.96.200.39:80'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); curl_setopt($ch, CURLOPT_CUSTOMREQUEST,'GET'); curl_setopt ($ch, CURLOPT_HEADER, 1); curl_exec ($ch); $curl_scraped_page = curl_exec($ch); curl_close($ch); echo $curl_scraped_page; ?> - user586011
2
pelican-cement.com上的表单有名为“firstname”和“lastname”的输入,但没有名为“1”的输入。 - John Flatness
3
请在下方添加您的解决方案并接受它。不要将解决方案放入问题中,那样效果不佳。 - hakre
4个回答

247

这是一个已经去掉你的bug并能正常工作的版本。

$url = 'http://dynupdate.no-ip.com/ip.php';
$proxy = '127.0.0.1:8888';
//$proxyauth = 'user:password';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
$curl_scraped_page = curl_exec($ch);
curl_close($ch);

echo $curl_scraped_page;

如果你的代理服务器需要用户名和密码,我添加了CURLOPT_PROXYUSERPWD

我将CURLOPT_RETURNTRANSFER设置为1,这样数据将返回到$curl_scraped_page变量中。

我删除了第二个多余的curl_exec($ch);,这会导致无法返回变量。

我将您的代理IP和端口合并为一个设置。

我还删除了CURLOPT_HTTPPROXYTUNNELCURLOPT_CUSTOMREQUEST,因为它们是默认值。

如果不想返回头,请注释掉CURLOPT_HEADER

要禁用代理,只需将其设置为null。

curl_setopt($ch, CURLOPT_PROXY, null);
任何问题都可以随时问我,我每天都使用 cURL 。

@coding_idiot 大多数网络主机出于安全考虑会阻止非80或443端口的访问。 - sousdev
我已经解决了。我相信其他人也会从中受益。 - coding_idiot
@GravyCode:如果我们从某些服务中获取代理,那么我是否需要传递用户名/密码? - Pragnesh Chauhan
1
我该如何知道代理端口是否被网络主机阻止? - user1788736
谢谢!我在这个问题上卡了一个星期。原来是缺少了代理。 - undefined
显示剩余4条评论

42

我已经解释了使用CURL代理所需的各种CURL选项。

$url = 'http://dynupdate.no-ip.com/ip.php';
$proxy = '127.0.0.1:8888';
$proxyauth = 'user:password';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);         // URL for CURL call
curl_setopt($ch, CURLOPT_PROXY, $proxy);     // PROXY details with port
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);   // Use if proxy have username and password
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); // If expected to call with specific PROXY type
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);  // If url has redirects then go to the final redirected URL.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);  // Do not outputting it out directly on screen.
curl_setopt($ch, CURLOPT_HEADER, 1);   // If you want Header information of response else make 0
$curl_scraped_page = curl_exec($ch);
curl_close($ch);

echo $curl_scraped_page;

3
这些评论很有帮助,但其他人应该注意到,额外的选项实际上并不是必需的 - Nate

0
root@APPLICATIOSERVER:/var/www/html# php connectiontest.php
61e23468-949e-4103-8e08-9db09249e8s1 OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 10.172.123.1:80 root@APPLICATIOSERVER:/var/www/html#

在 PHP 脚本文件中声明代理设置后,问题已得到解决。

$proxy = '10.172.123.1:80';
curl_setopt($cSession, CURLOPT_PROXY, $proxy); // 带端口的代理详细信息

-2

这是一个经过充分测试的函数,我在我的项目中使用它,并附有详细的自我解释注释


有很多时候,除了80端口之外的端口被服务器防火墙阻止,因此代码在本地主机上运行良好,但在服务器上却无法正常工作。

function get_page($url){

global $proxy;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_HEADER, 0); // return headers 0 no 1 yes
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return page 1:yes
curl_setopt($ch, CURLOPT_TIMEOUT, 200); // http request timeout 20 seconds
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow redirects, need this if the url changes
curl_setopt($ch, CURLOPT_MAXREDIRS, 2); //if http server gives redirection responce
curl_setopt($ch, CURLOPT_USERAGENT,
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7");
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies.txt"); // cookies storage / here the changes have been made
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies.txt");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // false for https
curl_setopt($ch, CURLOPT_ENCODING, "gzip"); // the page encoding

$data = curl_exec($ch); // execute the http request
curl_close($ch); // close the connection
return $data;
}

1
这个帮了我:curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // https为false - villamejia
2
@villamejia 注意,使用CURLOPT_SSL_VERIFYPEER = false时要小心。这意味着cURL在连接到https服务器时不会进行任何证书检查,从而使连接容易受到可能的中间人攻击 - 因此数据安全性不再得到保障。最好使用CURLOPT_CAPATH来提供一个包含一组有效根认证机构的目录(例如,在Debian / Ubuntu上为“/etc/ssl/certs”)。 - Ale

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接