web-dev-qa-db-fra.com

file_get_contents retourne 403 interdit

Je suis en train de fabriquer un gratte site. Je l'ai fait sur ma machine locale et cela fonctionne très bien là-bas. Lorsque j'exécute la même chose sur mon serveur, une erreur interdite 403 est affichée . J'utilise le PHP Simple HTML DOM Parser . L'erreur que je reçois sur le serveur est la suivante:

Attention: file_get_contents (http://example.com/viewProperty.html?id=7715888) [function.file-get-contents]: échec pour ouvrir le flux: la requête HTTP a échoué! HTTP/1.1 403 Interdit dans /home/scraping/simple_html_dom.php on ligne 40

La ligne de code qui le déclenche est la suivante:

$url="http://www.example.com/viewProperty.html?id=".$id;

$html=file_get_html($url);

J'ai vérifié le fichier php.ini sur le serveur et allow_url_fopen est activé. La solution possible peut être d'utiliser curl, mais j'ai besoin de savoir où je me trompe.

23
absk

Ce n'est pas un problème avec votre script, mais avec la ressource que vous demandez. Le serveur Web renvoie le code d’état "interdit".

Il se peut qu’il bloque les scripts PHP pour éviter les éraflures ou votre adresse IP si vous avez effectué trop de demandes.

Vous devriez probablement parler à l'administrateur du serveur distant.

16
Pekka 웃

Je sais que c'est un vieux fil, mais j'ai pensé partager quelques idées.

Très probablement, si vous n'obtenez aucun contenu lors de l'accès à une page Web, il ne veut probablement pas que vous puissiez obtenir le contenu. Alors, comment identifie-t-il qu'un script tente d'accéder à la page Web, et non un humain? En règle générale, il s'agit de l'en-tête User-Agent de la requête HTTP envoyée au serveur.

Donc, pour que le site Web pense que le script accédant à la page Web est également un human, vous devez modifier l'en-tête User-Agent lors de la demande. La plupart des serveurs Web accepteraient probablement votre demande si vous définissez l'en-tête User-Agent sur une valeur utilisée par un navigateur Web commun.

Une liste des agents utilisateurs courants utilisés par les navigateurs est donnée ci-dessous:

  • Chrome: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'

  • Firefox: 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0'

  • etc...


$context = stream_context_create(
    array(
        "http" => array(
            "header" => "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
        )
    )
);

echo file_get_contents("www.google.com", false, $context);

Ce morceau de code simule l'agent utilisateur et envoie la demande à https://google.com .

Références:

À votre santé!

22
Ikari

Vous pouvez le changer comme ceci dans la classe d’analyse de la ligne 35 et suivantes.

function curl_get_contents($url)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}

function file_get_html()
{
  $dom = new simple_html_dom;
  $args = func_get_args();
  $dom->load(call_user_func_array('curl_get_contents', $args), true);
  return $dom;
}

Avez-vous essayé un autre site?

4
Dejan Marjanovic

Ecrivez ceci dans simple_html_dom.php pour moi cela a fonctionné

function curl_get_contents($url)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$html = curl_exec($ch);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}

function file_get_html($url, $use_include_path = false, $context=null, $offset = -1, $maxLen=-1, $lowercase = true, $forceTagsClosed=true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT, $defaultSpanText=DEFAULT_SPAN_TEXT)
{
    $dom = new simple_html_dom;
  $args = func_get_args();
  $dom->load(call_user_func_array('curl_get_contents', $args), true);
  return $dom;
    //$dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText);

}
4
r0adtr1p

Il semble que le serveur distant ait un type de blocage. Cela peut être par user-agent , si c'est le cas, vous pouvez essayer d'utiliser curl pour simuler l'agent utilisateur d'un navigateur Web comme ceci:

$url="http://www.example.com/viewProperty.html?id=".$id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$html = curl_exec($ch);
curl_close($ch);
4
Sergi

Je réalise que c'est une vieille question, mais ...

Il suffit de configurer mon bac à sable local sur Linux avec php7 et de le traverser. À l'aide des scripts d'exécution du terminal, php appelle php.ini pour la CLI. J'ai trouvé que l'option "user_agent" avait été commentée. Je l'ai commenté et ajouté un agent utilisateur Mozilla, maintenant cela fonctionne.

2
CrookedCreek

Avez-vous vérifié vos autorisations sur le fichier? J'ai mis en place 777 sur mon fichier (dans localhost, évidemment) et j'ai résolu le problème.

1
Andrea Syd Coi

Lorsque vous travaillez sur des appels de serveur à serveur, il s’agit essentiellement d’appel de script PHP. En raison de cela, de nombreux serveurs distants bloquent les appels avec des scripts php pour éviter la copie de sites Web. Cela peut facilement être surmonté en faisant apparaître votre script comme s'il provenait de main. Vous pouvez utiliser le code suivant.

$context = stream_context_create(
    array(
        "http" => array(
            "header" => "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
        )
    )
);

echo file_get_contents("https://www.google.co.in", false, $context);
0
Uma Shankar Goel

Dans mon cas, le serveur rejetait le protocole HTTP 1.0 via sa configuration .htaccess. Il semble que file_get_contents utilise la version HTTP 1.0. 

0
Steven

J'avais le même pb. J'ai juste activé Youtube API des développeurs de console de Google ... et ça a fonctionné (plus interdit :-)

Je ne sais pas si le sujet est déprécié, je pensais juste pour partager l'idée. 

0
Hamid ER-REMLI