Не удается получить желаемый контент с помощью сокета - PullRequest
0 голосов
/ 27 октября 2018

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

Мой код:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_ip = socket.gethostbyname('data.pr4e.org')
s.connect((host_ip,80))
cmd = "GET http://data.pr4e.org/romeo.txt HTTP/1.0\n\n".encode()
s.send(cmd)

while True:
    data = s.recv(1024)
    if (len(data) <1 ):
        break
    print(data.decode())
s.close()

Ошибка, которую я получаю:

400 Bad Request

Your browser sent a request that this server could not understand.

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Здесь есть несколько проблем:

  1. Нечасто включать http://data.pr4e.org после GET (см. RFC 7230 ), если не разговариваете с прокси.Обычно вы будете писать GET /romeo.txt и указывать имя хоста в отдельном Host: data.pr4e.org заголовке .Серверы обязаны поддерживать форму, которую вы использовали, но они могут нарушать стандарт и задушить его.Это особенно вероятно, если вы заявляете, что используете HTTP / 1.0, что более строго, и запрещает эту форму, если только вы не разговариваете с прокси .
  2. Никто больше не использует HTTP / 1.0.Все современные браузеры и другие HTTP-клиенты используют HTTP / 1.1 или HTTP / 2.Некоторые серверы будут поддерживать HTTP / 1.0, но это не обязательно.Обратите внимание, что HTTP / 1.1 делает заголовок Host: обязательным , даже если вы указали полный URL после GET.
  3. HTTP / 1.0 использует \r\n ("CRLF") в качествеперевод строки (см. RFC 1945 ), поэтому \n не всегда можно понять.Опять же, некоторые серверы будут обрабатывать это правильно, но это не соответствует.Использование CRLF было перенесено в HTTP / 1.1 .
  4. print(data.decode()) добавит дополнительный символ новой строки в конце data.Это может стать проблемой, если TCP фрагментирует большой HTTP-ответ, так что recv() возвращает несколько непустых строк.Вместо этого используйте print(data.decode(), end='').
0 голосов
/ 27 октября 2018

Мне удалось получить желаемый результат, добавив \r\n\r\n в конец команды запроса, а не исходный \n\n:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostbyname('data.pr4e.org'), 80))
s.sendall("GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n".encode())
print(s.recv(1024))

Вывод:

...
Content-Type: text/plain\r\n\r\nBut soft what light through yonder window breaks\nIt is the east and Juliet is the sun\nArise fair sun and kill the envious moon\nWho is already sick and pale with grief\n'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...