Po prostu zaczynam od danych internetowych Pythona w Pythonie 3.6.1. Nauczyłem się gniazdami i miałem problem z moim kodem, którego nie mogłem się dowiedzieć. Witryna w moim kodzie działa dobrze, ale kiedy uruchomię ten kod otrzymuję 400 złego błędu żądania. Nie jestem pewien, jaki jest problem z moim kodem. Z góry dziękuję.

import socket

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

mysock.connect(('data.pr4e.org', 80))

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

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

mysock.close()
4
Srisai Nachuri 27 czerwiec 2017, 09:30

4 odpowiedzi

Najlepsza odpowiedź
GET http://data.pr4e.org/romeo.txt HTTP/1.0 \n\n

Witamy we wspaniałym świecie HTTP, gdzie większość użytkowników uważa, że jest to łatwy protokół, ponieważ jest to czytelny dla człowieka, ale w rzeczywistości może być bardzo złożonym protokołem. Biorąc pod uwagę Twoją prośbę powyżej istnieje kilka problemów:

  • Ścieżka nie powinna być pełnym adresem URL, ale tylko /romeo.txt. Pełny adres URL będzie używany tylko podczas prośby do proxy.
  • Koniec linii musi być \r\n nie \n.
  • Przed HTTP/1.0.
  • Podczas gdy nagłówek hosta jest wymagany tylko z HTTP / 1.1 wielu serwerów (w tym ten, który próbujesz uzyskać dostęp)

Mając to na uwadze, że wysyłane dane powinny być

GET /romeo.txt HTTP/1.0\r\nHost: data.pr4e.org\r\n\r\n

I przetestowałem, że działa doskonale z tą modyfikacją.

Ale biorąc pod uwagę, że HTTP nie jest tak prosty, jak może się spojrzeć, naprawdę polecam korzystanie z biblioteki, takich jak prośby o dostęp do celu. Jeśli to wygląda na zbyt wiele nadwyżek do ciebie, badanie Standard HTTP, aby wdrożyć go prawidłowo po prostu zgadywanie, jak działa http z niektórych przykładów - i zgadywanie to źle.

Należy również pamiętać, że serwery różnią się, jak przebaczają, że dotyczą złamanych implementacji takich jak twoje. Tak więc, co kiedyś pracowało z jednym serwerem może nie działać z następnym serwerem, a nawet z tym samym serwerem po aktualizacji oprogramowania. Korzystanie z solidnej i dobrze przetestowanej i utrzymanej biblioteki zamiast robienia wszystkiego na własną rękę, może zatem zaoszczędzić dużo problemów.

6
Steffen Ullrich 27 czerwiec 2017, 07:54

Ten kod zadziałał dla mnie:

GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n
  1. zmień \n\n do \r\n\r\n
  2. Wyjmij przestrzeń między HTTP/1.0 a \r\n\r\n
0
Roberto Caboni 24 czerwiec 2020, 07:30
'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'.encode()

Pracuje dla mnie.

2
Stephen Rauch 11 grudzień 2017, 01:37

Nie wysyłasz protokołu na serwerze WWW i wysyłasz tylko nazwę hosta oddzielnie w nagłówku Host, a tylko wtedy w http 1.1.

Dla http 1.0 powinno być:

mysock.send('GET /romeo.txt HTTP/1.0\r\n\r\n')

Alternatywnie możesz spróbować wysłać żądanie HTTP 1.1:

mysock.send('GET /romeo.txt HTTP/1.1\r\n')
mysock.send('Host: data.pr4e.org\r\n\r\n')
1
Martin Broadhurst 27 czerwiec 2017, 07:15