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;
?> 
user586011
fonte
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.

GravyCode
fonte
É 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;
Somnath Muluk
fonte
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;
}
hammad1238
fonte
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