TypeError:在尝试发送 http 请求时需要一个类似字节的对象,而不是“str”
Posted
技术标签:
【中文标题】TypeError:在尝试发送 http 请求时需要一个类似字节的对象,而不是“str”【英文标题】:TypeError: a bytes-like object is required, not 'str' while trying to send a http request 【发布时间】:2022-01-04 03:02:16 【问题描述】:我正在尝试向用户输入的站点发送http响应,然后打印响应,代码如下:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
url = input("Enter a web address and press Enter: ")
s.connect((url, 80))
# s.send("GET / HTTP/1.0\r\n\r\n")
s.send(b"HTTP/1.1 200 OK\nContent-Type: text/html\r\n\r\n")
print(s.recv(1028))
s.close()
但是,我收到了上述错误。不太清楚为什么。我也尝试连接发送请求,但说我不能有类似字节的对象。任何帮助将不胜感激。
编辑:我尝试对路人发送的链接中的文本进行编码,但是我没有收到 html 响应,我收到了一个错误的请求:
b'HTTP/1.0 400 Bad Request\r\nContent-Type: text/html; charset=UTF-8\r\nReferrer-Policy: no-referrer\r\nContent-Length: 1555\r\nDate: Thu, 25 Nov 2021 22:48:41 GMT\r\n\r\n<!DOCTYPE html>\n<html lang=en>\n <meta charset=utf-8>\n <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">\n <title>Error 400 (Bad Request)!!1</title>\n <style>\n *margin:0;padding:0html,codefont:15px/22px arial,sans-serifhtmlbackground:#fff;color:#222;padding:15pxbodymargin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px* > bodybackground:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205pxpmargin:11px 0 22px;overflow:hiddeninscolor:#777;text-decoration:nonea imgborder:0@media screen and (max-width:772px)bodybackground:none;margin-top:0;max-width:none;padding-right:0#logobackground:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px@media only screen and (min-resolution:192dpi)#logobackground:url(/'
【问题讨论】:
这能回答你的问题吗? How do I encode a string to bytes in the send method of a socket connection in one line? 不是真的,我没有得到回复,html中的网站布局 您不会向网站发送回复。您发送请求,站点将发送响应作为回报。您应该发送s.send( b'GET / HTTP/1.0\r\n\r\n')
。更好的是,使用出色的 requests
模块隐藏所有这些并让您专注于问题。
【参考方案1】:
您正在向用户询问作为字符串的 URL:
url = input("Enter a web address and press Enter: ")
然后你将该字符串传递给socket.send
:
s.send("GET / HTTP/1.0\r\n\r\n")
但是,正如错误所说,socket.send
需要一个类似字节的对象。要从字符串中获取它,可以调用它的 encode
方法:
s.send("GET / HTTP/1.0\r\n\r\n".encode("utf-8"))
或从中创建一个bytes
对象并将其传递给socket.send
:
s.send(bytes("GET / HTTP/1.0\r\n\r\n"))
或者在字符串前面加上b
:
s.send(b"GET / HTTP/1.0\r\n\r\n")
【讨论】:
【参考方案2】:您必须使用套接字来执行此操作吗?为什么不使用urllib.request
?
import urllib.request
url = input("Enter a web address and press Enter: ")
with urllib.request.urlopen(url) as f:
print(f.read())
我正在运行它以点击https://www.example.com
:
Enter a web address and press Enter: https://www.example.com
b'<!doctype html>\n<html>\n<head>\n <title>Example Domain</title>\n\n <meta charset="utf-8" />\n <meta http-equiv="Content-type" content="text/html; charset=utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n <style type="text/css">\n body \n background-color: #f0f0f2;\n margin: 0;\n padding: 0;\n font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;\n \n \n div \n width: 600px;\n margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n \n a:link, a:visited \n color: #38488f;\n text-decoration: none;\n \n @media (max-width: 700px) \n div \n margin: 0 auto;\n width: auto;\n \n \n </style> \n</head>\n\n<body>\n<div>\n <h1>Example Domain</h1>\n <p>This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.</p>\n <p><a href="https://www.iana.org/domains/example">More information...</a></p>\n</div>\n</body>\n</html>\n'
以下是使用socket
的方法:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
url = input("Enter a web address and press Enter: ")
s.connect((url, 80))
request = f"GET / HTTP/1.1\r\nHost:url\r\n\r\n"
s.send(request.encode())
print(s.recv(4096))
s.close()
我修改了这个程序:https://www.geeks3d.com/hacklab/20190110/python-3-simple-http-request-with-the-socket-module/
如果您需要它一直阅读到 EOF,请使用此模式:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
url = input("Enter a web address and press Enter: ")
s.connect((url, 80))
request = f"GET / HTTP/1.1\r\nHost:url\r\n\r\n"
s.send(request.encode())
response = ""
while True:
chunk = s.recv(1024)
if len(chunk) == 0:
break
response += str(chunk)
print(response)
【讨论】:
是的,我正在尝试在 python 中自学套接字和网络。尝试使用任何外部软件包。urllib.request
不是外部的,它是 Python 的核心,就像 socket
一样。但我会更新一个有效的socket
示例。
为了读取到文件末尾,我们不需要解码直到 end= ' ' 吗?另外,为什么我们在编码时没有显式解码?
不知道,这似乎对我有用。我不使用 socket
发出 HTTP 请求。我使用requests
或urllib.request
。以上是关于TypeError:在尝试发送 http 请求时需要一个类似字节的对象,而不是“str”的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:无法读取未定义的nodejs请求http的属性'0'
错误:TypeError:无法调用未定义的方法“替换”[重复]
Uncaught TypeError: $(...).value is not a function 尝试通过 JQuery 发送值时