web-dev-qa-db-fra.com

socket python GET

Sur les autres postes sur le dépassement de pile, cela devrait fonctionner

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                 

s.connect(("www.cnn.com" , 80))
s.sendall("GET / HTTP/1.1\r\n")
print s.recv(4096)
s.close

mais pour une raison quelconque, il se bloque (à recv) et n’imprime jamais. Je sais qu'une demande sur www.cnn.com divisera ses données, mais je devrais au moins lire quelque chose dans recv, non?

p.s. Je sais que ce n'est pas la meilleure façon de le faire et qu'il existe des bibliothèques telles que httplib et urllib2, mais je ne peux pas les utiliser pour ce projet (c'est pour l'école). Je dois utiliser la bibliothèque socket

6
james smith

Vous avez oublié d'envoyer une ligne vierge après votre ligne de demande:

s.sendall("GET / HTTP/1.1\r\n\r\n")

De plus, HTTP 1.1 indique que vous devez ajouter le champ d'en-tête Host comme indiqué dans la section Host de HTTP 1.1 RFC .

s.sendall("GET / HTTP/1.1\r\nHost: www.cnn.com\r\n\r\n")
12
Takis

Votre code est presque correct, mais vous devez envoyer 2 séquences \r\n pour satisfaire le protocole HTTP.

Une demande GET valide ressemblera à ceci (remarquez 2 lignes):

 GET/HTTP/1.1 
 

Donc, votre code devrait être:

s.sendall('GET / HTTP/1.1\r\n\r\n')

De plus, des en-têtes supplémentaires sont requis pour les demandes HTTP 1.1 valides, tels que Host:. Vous devez les ajouter à votre demande, quelque chose comme ceci:

s.sendall('''GET / HTTP/1.1
Host: cnn.com

''')
5
mhawke

Désolé de perdre tout le temps de tout le monde. Je viens de trouver cette solution ici sur Stack Overflow (j'ai juste reformulé ma recherche Google pour trouver)

import socket
request = b"GET / HTTP/1.1\nHost: www.cnn.com\n\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("cnn.com", 80))
s.send(request)
result = s.recv(10000)
while (len(result) > 0):
    print(result)
    result = s.recv(10000)

Et toutes les réponses étaient également correctes à propos de la fin de \r\n\r\n, mais celles renvoyées par 301 statuts. Cette solution semble suivre la redirection en quelque sorte? En tout cas, cette solution a fonctionné pour moi

3
james smith

Essayez de remplacer cette ligne:

s.sendall("GET / HTTP/1.1\r\n")

avec:

s.sendall("GET / HTTP/1.1\r\n\r\n")
                             ^^^^

De plus, je pense que vous devez remplacer s.close par s.close() car c’est une fonction.

1
Kevin Guan