Как я могу сделать простой веб-браузер на Python 3.6? - PullRequest
0 голосов
/ 25 ноября 2018

Пока это то, что у меня есть, и в каждом месте, где я смотрел, написано, что этот код должен работать, но это не так.

import socket

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('data.pr4e.org', 80))
mysock.send(b'GET http://data.pr4e.org/romeo.txt HTTP/1.0\n\n')

while True:
    data = mysock.recv(512)
    if ( len(data) < 1 ) :
        break
    print (data)

mysock.close()

Это вывод, который я получаю:

b'HTTP/1.1 400 Bad Request\r\nDate: Sun, 25 Nov 2018 19:23:51 GMT\r\nServer: 
Apache/2.4.18 (Ubuntu)\r\nContent-Length: 308\r\nConnection: 
close\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<!DOCTYPE HTML 
PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>400 Bad 
Request</title>\n</head><body>\n<h1>Bad Request</h1>\n<p>Your browser sent a 
request that this server could not understand.<br 
/>\n</p>\n<hr>\n<address>Apache/2.4.18 (Ubuntu) Server at do1.dr-chuck.com 
Port 80</address>\n</body></html>\n'

Это то, что в примере говорится, что я должен получить ответ:

HTTP/1.1 200 OK
Date: Sun, 14 Mar 2010 23:52:41 GMT
Server: Apache
Last-Modified: Tue, 29 Dec 2009 01:31:22 GMT
ETag: "143c1b33-a7-4b395bea"
Accept-Ranges: bytes
Content-Length: 167
Connection: close
Content-Type: text/plain
But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief

Почему я не получаю тот же вывод?

1 Ответ

0 голосов
/ 26 ноября 2018

В некотором смысле ваш код работает, потому что он может успешно отправить запрос на сервер, и вы вернете верный результат.Вы можете видеть, что само сообщение об ошибке приходит с сервера.

Но вы не получите ожидаемый результат обратно, так что это действительно проблема.Непосредственное открытие http://data.pr4e.org/romeo.txt в браузере работает правильно, поэтому давайте посмотрим немного дальше, например, на вопросы, как заголовок ошибки 400 с сокетами , которые решают практически ту же проблему.

После некоторых экспериментов кажется, что веб-серверу требуется конец строки в стиле Microsoft Windows: и \r , и \n.Просто \n, как в вашей попытке, не работает - вы получите эту ошибку обратно.Просто \r заставляет сервер ждать бесконечно (или, скорее, «довольно долго и, конечно, дольше, чем я был готов ждать этого эксперимента»).

Итак, эта простая модификация заставляет вашу оригинальную программу работать:

mysock.send(b'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n')

и возвращает после нескольких заголовков следующую поэзию:

... But soft what bytes through yonder port breaks
It is a request and Http is the Sun ...

(по общему признанию, слегка перефразирован)

В некоторых операционных системах (Я знаю только Microsoft Windows), стандартный код для конца строки \n автоматически получает , расширенный до \r\n.Поэтому разумно предположить, что ваш рабочий пример кода был написан и протестирован на компьютере Windows, и его автор никогда не знал (или не заботился), что сервер Apache ожидает этот явный тип окончания строки.

...