Como usar o CURL através de um proxy?


128

Eu estou olhando para definir curl para usar um servidor proxy. O URL é fornecido por um formulário html, o que não foi um problema. Sem o proxy, ele funciona bem. Encontrei código neste e em outros sites, mas eles não funcionam. Qualquer ajuda para encontrar a solução correta seria muito apreciada. Sinto que o fole está próximo, mas estou perdendo alguma coisa. Obrigado.

O código abaixo que eu adaptei daqui http://www.webmasterworld.com/forum88/10572.htm, mas ele retorna uma mensagem de erro sobre um T_VARIABLE ausente na linha 12.

<?

$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);
?>

O fole é de curl através de proxy não retorna conteúdo

<?

$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;
?>

está atualmente no site pelican-cement.com, mas também não funciona.

ATUALIZAÇÃO: Obrigado por toda a sua ajuda, fiz as alterações acima. Agora, ele retorna apenas uma tela em branco.

<?

$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
Está faltando um ponto e vírgula na linha 12
— Pekka

Além disso, você precisa mudar $ url = '$ _ POST [1]' para $ url = $ _ POST [1] - caso contrário, $ url será uma string em vez da URL que você quer
— yoavmatchulsky

Além disso, a chave na matriz $ _POST é uma string e não um inteiro assim que você quer dizer$_POST['1']
— fiiv

2
O formulário no pelican-cement.com possui entradas denominadas "nome e sobrenome", mas nenhuma com nome "1".
— John Flatness

2
@ user586011: adicione sua solução como resposta abaixo e aceite-a. Não coloque a solução em questão, isso não funciona bem.
— hakre 12/07/12

Respostas:


221

Aqui está uma versão funcional com os erros removidos.

$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;

Eu adicionei CURLOPT_PROXYUSERPWDcaso algum dos seus proxies exija um nome de usuário e senha. Defino CURLOPT_RETURNTRANSFERcomo 1, para que os dados retornem à $curl_scraped_pagevariável.

Eu removi um segundo extra curl_exec($ch);que interromperia o retorno da variável. Consolidei o IP e a porta do proxy em uma configuração.

Eu também removi CURLOPT_HTTPPROXYTUNNELe, CURLOPT_CUSTOMREQUESTcomo era o padrão.

Se você não quiser que os cabeçalhos retornem, comente CURLOPT_HEADER.

Para desativar o proxy, basta configurá-lo como nulo.

curl_setopt($ch, CURLOPT_PROXY, null);

Qualquer dúvida não hesite em perguntar, eu trabalho cURLtodos os dias.


É bom saber que você trabalha com o CURL todos os dias. Eu tentei configurar um proxy de meias e ele funciona na minha máquina local, mas não funciona no meu servidor linux dedicado. Qualquer ideia ?
— Coding_idiot 31/01

@coding_idiot A maioria dos hosts da web bloqueia portas que não são 80 ou 443 por motivos de segurança.
— sousdev

Eu já resolvi isso. Tenho certeza que outros se beneficiarão com isso.
— Codigo_idiot 27/09/2013

@GravyCode: se obtivermos proxy de alguns serviços, nesse caso, preciso passar o nome de usuário / senha?
— Pragnesh Chauhan

1
Como devo saber se a porta proxy está bloqueada pelo host?
— user1788736

35

Expliquei o uso de várias opções de CURL necessárias para o CURL PROXY.

$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
Esses comentários são úteis, mas outros devem observar que as opções adicionais não são realmente necessárias .
— Nate

-1

Aqui está uma função bem testada que eu usei para meus projetos com comentários auto-explicativos detalhados


Muitas vezes, quando portas diferentes de 80 são bloqueadas pelo firewall do servidor, o código parece estar funcionando bem no host local, mas não no servidor

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
Isso me ajudou: curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, false); // false para https
— villamejia

1
@villamejia Cuidado, porém, ao usar CURLOPT_SSL_VERIFYPEER = false. Isso significa que o cURL não fará nenhuma verificação de certificado ao se conectar ao servidor https, tornando a conexão vulnerável a um possível ataque do tipo intermediário - portanto, a segurança dos dados não é mais garantida. Melhor utilização CURLOPT_CAPATH para dar um diretório que contém um conjunto de autoridades de certificação raiz válidos ( /etc/ssl/certsem Debian / Ubuntu, por exemplo)
— Ale
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.