Ошибка Python Socket 300 'Перемещено навсегда' - PullRequest
0 голосов
/ 05 декабря 2018

Я пытался запустить этот код, чтобы начать связь с различными сайтами, но не могу установить один.Может ли кто-нибудь помочь мне с тем, что мне здесь не хватает?

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

server = 'www.python.org'
port = 80 #defining port / acting like a browser

server_ip = socket.gethostbyname(server)
print(server_ip)

request = "GET / HTTPS/1.1\nHost: "+server+"\n\n"
s.connect((server_ip,port))
s.send(request.encode())
result = s.recv(4096)

while (len(result) > 0):
     print(result)
     result = s.recv(1024)

Каждый раз, когда на разных сайтах появляется следующее сообщение об ошибке:

<socket.socket fd=508, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>

151.101.152.223 b'HTTP /1.1 301 Перемещено навсегда10:03 GMT \ r \ nVia: 1.1 лак \ r \ nСоединение: закрыть \ r \ nX-Served-By: cache-bom18222-BOM \ r \ nX-Cache: HIT \ r \ nX-Cache-Hits: 0 \r \ nX-таймер: S1544029803.224270, VS0, VE0 \ r \ nСтрого-транспортная безопасность: max-age = 63072000;IncludeSubdomains \ г \ п \ г \ п '

1 Ответ

0 голосов
/ 05 декабря 2018

Этот запрос неверен для нескольких уровней:

port = 80 #defining port / acting like a browser
...
request = "GET / HTTPS/1.1\nHost: "+server+"\n\n"

Нет протокола HTTPS/1.1.Есть только HTTP/1.1.Чтобы получить доступ к URL-адресу https://.., необходимо сначала подключиться к сайту (порт по умолчанию 443, а не 80, как вы использовали), обновить сокет TCP до SSL и выдать правильный HTTP-запрос, т. Е. С HTTP/1.1 не HTTPS/1.1.

Кроме того, разделитель строки и заголовка должен быть \r\n вместо только \n, который вы использовали.Большинство серверов игнорируют эту разницу.

Кроме того, HTTP/1.1 неявно включает постоянные HTTP-соединения (HTTP keep-alive).Это означает, что сервер может не закрыть соединение сразу после ответа, как ожидает ваш код, но может долго ждать большего количества запросов в том же соединении.Для таких простых запросов лучше использовать HTTP/1.0, который не имеет неявного keep-alive, а также проще в других отношениях (без кодирования передачи по частям).

.... b'HTTP/1.1 301 Moved Permanently ... Location: https://www.python.org/

Это даже не ошибка.Это перенаправление HTTP, в котором говорится, что вы должны получить доступ к сайту с помощью https:// (что вы, вероятно, пытались сделать, но поступили неправильно).

В конце ваш код может выглядеть следующим образом:

import socket
import ssl

(server,port) = ('www.python.org',443)
request = "GET / HTTP/1.0\r\nHost: "+server+"\r\n\r\n"

s = socket.socket()
s.connect((server,port))
s = ssl.create_default_context().wrap_socket(s, server_hostname=server)
s.send(request.encode())

result = s.recv(4096)
while (len(result) > 0):
     print(str(result))
     result = s.recv(1024)

Тем не менее, даже если этот код работает, я действительно рекомендую использовать HTTP-библиотеку, такую ​​как запросы .Если вы вместо этого настаиваете на написании своего собственного стека HTTP, то, пожалуйста, изучите стандарт - протокол значительно сложнее, чем предлагает краткий обзор нескольких примеров.

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