2016-03-23 4 views
0

Я пытаюсь написать код, который получает html-код с веб-сайта, который вводит пользователь. Я должен написать это без использования urllib или других библиотек такого типа.Python HTTP GET. «Неверный запрос»

from socket import * 


url = (input("Please enter url: ")) 
host=gethostbyname(url) 

clientSocket = socket(AF_INET, SOCK_STREAM) 
clientSocket.connect((host,80)) 

clientSocket.send(("GET " + host + "HTTP/1.1\n\n").encode("UTF-8")) 

file = clientSocket.recv(1024) 
print("The html code: ", file.decode("UTF-8")) 
clientSocket.close() 

Код работает нормально. Однако, когда я ввода веб-сайт, таких как «www.stackoverflow.com» Я получаю «плохой запрос» ответ от хоста:

The html code: HTTP/1.1 400 Bad Request 

Date: Wed, 23 Mar 2016 16:14:27 GMT 

Content-Type: text/html 

Content-Length: 177 

Connection: close 

Server: -nginx 

CF-RAY: - 



<html> 

<head><title>400 Bad Request</title></head> 

<body bgcolor="white"> 

<center><h1>400 Bad Request</h1></center> 

<hr><center>cloudflare-nginx</center> 

</body> 

</html> 

Что бы правильно запрос, чтобы получить фактический HTML-код из сервер. Спасибо

ответ

1

Имя хоста не является URL-адресом. Кажется, что ваш скрипт запрашивает только имя хоста, поскольку вы используете gethostbyname(). Запрос GET ожидает увидеть URI для своего первого аргумента. Вам также нужно отправить каретки с вашими линиями, и вам нужно два, чтобы завершить запрос GET. Вы должны что-то вроде:

clientSocket.send(("GET/HTTP/1.1\r\n\r\n").encode("UTF-8")) 

Кроме того, если все, что вы хотите сделать, это загрузить URL, использовать библиотеку как urllib2, которая заботится обо всех деталях протокола HTTP для вас. Например:

import urllib2 

r = urllib2.urlopen('http://google.com/') 
print r.read() 
0

Вы не говорите HTTP/1.1, но вы указали так на первой строке.

Прежде всего, токен, следующий за GET, должен быть абсолютным путем на сервере; таким образом, начинаются с /.

Во-вторых, запрос HTTP/1.1 должен включать заголовок Host:.

И, в-третьих, ваш простой клиент должен, вероятно, сказать Connection: close, так как он не обрабатывает канальные соединения.


Вы можете иметь лучший успех со следующим сценарием:

from socket import * 

host = gethostbyname('stackoverflow.com') 
clientSocket = socket(AF_INET, SOCK_STREAM) 
clientSocket.connect((host,80)) 
clientSocket.send((
    "GET/HTTP/1.1\r\n" 
    "Host: stackoverflow.com\r\n" 
    "Connection: close\r\n\r\n").encode('utf-8')) 

file = clientSocket.recv(1024) 
print("The html code: ", file.decode("UTF-8")) 
clientSocket.close() 
+0

Спасибо! однако мой профессор просит, чтобы пользователь вводил url вместо меня, имея его там, в первую очередь. Здесь у меня проблемы, потому что разные сайты имеют разные пути, и я не знаю, как их обобщить. – JulianP

+0

затем используйте 'urlparse', чтобы разобрать его на компоненты –

+0

извините мое невежество, но я не уверен, как это сделать. Я только вступаю в сеть, и мой профессор не очень помогает. Все, что я сделал до сих пор, я получил в своих исследованиях, но чувствую, что я нахожусь в дорожном блоке, потому что не знаю многого. – JulianP

Смежные вопросы