Py telnetlib OKI 2.7 但在 3.6 下出错
Py telnetlib OKI with 2.7 but error under 3.6
我的案例类似于 python 'telnetlib'
连接 Google.com
使用 python Anaconda 2.7.10 shell 我有运行良好的 blow 脚本:
HOST ="www.google.com"
tn=telnetlib.Telnet(HOST,"80")
tn.write("GET /index.html HTTP/1.1\nHost:"+HOST+"\n\n")
l=tn.read_all()
print(l)
回馈:
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: http://www.google.it/index.html?
gfe_rd=cr&dcr=0&ei=A7KiWv_2G6fCXojstrAO
Content-Length: 276
Date: Fri, 09 Mar 2018 16:10:43 GMTenter code here
如果我现在移动到 Python Anaconda 3.6.3 与上面相同的脚本,我会出现以下错误:
Traceback (most recent call last):
File "<ipython-input-4-0f3256299055>", line 3, in <module>
tn.write("GET /index.html HTTP/1.1\nHost:"+HOST+"\n\n")
File "C:\Users\FP\Anaconda3\lib\telnetlib.py", line 287, in write
if IAC in buffer:
TypeError: 'in <string>' requires string as left operand, not bytesenter code here
你对此有什么建议吗?我修改了一些关于 telnetlib 的文档,但到目前为止还没有找到解决方案 :-(。知道我可能会尝试做什么吗?
非常感谢!法比奥.
问题最终归结为 Python 2 和 Python 3 中字符串定义方式的差异。如果你从未读过这方面的内容,你可以查找一些 material 在线,例如 this. telnetlib
works with bytes
objects (Telnet generally works with 7-bit ASCII characters), strings (str
objects) in Python 3 are text representation without an specific encoding (until you call their .encode()
method to convert them to bytes
). When you call the .write()
方法与一个常规字符串,它检查它是否包含 telnetlib.IAC
,这是字节对象 b'\xff'
(255);由于两个对象(参数和 telnetlib.IAC
)具有不同的类型,因此失败。
显然,解决方法是一直只使用 bytes
个对象(类似于字符串,但前缀为 b
):
HOST = b"www.google.com"
tn=telnetlib.Telnet(HOST, 80)
tn.write(b"GET /index.html HTTP/1.1\nHost:"+HOST+b"\n\n")
l=tn.read_all()
print(l)
好的是,你也可以在 Python 2 中使用 b
前缀的字符串(来自 Python 2.6),它们只是常规的 Python 2 个字符串,因此代码适用于两个版本。您还可以查看 2to3
to make code porting to Python 3 easier (more on the topic here).
等工具
我猜 telnet 将希望以字节为单位工作,而不是您拥有的 unicode。
也许尝试编码?
tn.write(("GET /index.html HTTP/1.1\nHost:"+HOST+"\n\n").encode('ascii'))
我的案例类似于 python 'telnetlib'
连接 Google.com使用 python Anaconda 2.7.10 shell 我有运行良好的 blow 脚本:
HOST ="www.google.com"
tn=telnetlib.Telnet(HOST,"80")
tn.write("GET /index.html HTTP/1.1\nHost:"+HOST+"\n\n")
l=tn.read_all()
print(l)
回馈:
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: http://www.google.it/index.html?
gfe_rd=cr&dcr=0&ei=A7KiWv_2G6fCXojstrAO
Content-Length: 276
Date: Fri, 09 Mar 2018 16:10:43 GMTenter code here
如果我现在移动到 Python Anaconda 3.6.3 与上面相同的脚本,我会出现以下错误:
Traceback (most recent call last):
File "<ipython-input-4-0f3256299055>", line 3, in <module>
tn.write("GET /index.html HTTP/1.1\nHost:"+HOST+"\n\n")
File "C:\Users\FP\Anaconda3\lib\telnetlib.py", line 287, in write
if IAC in buffer:
TypeError: 'in <string>' requires string as left operand, not bytesenter code here
你对此有什么建议吗?我修改了一些关于 telnetlib 的文档,但到目前为止还没有找到解决方案 :-(。知道我可能会尝试做什么吗?
非常感谢!法比奥.
问题最终归结为 Python 2 和 Python 3 中字符串定义方式的差异。如果你从未读过这方面的内容,你可以查找一些 material 在线,例如 this. telnetlib
works with bytes
objects (Telnet generally works with 7-bit ASCII characters), strings (str
objects) in Python 3 are text representation without an specific encoding (until you call their .encode()
method to convert them to bytes
). When you call the .write()
方法与一个常规字符串,它检查它是否包含 telnetlib.IAC
,这是字节对象 b'\xff'
(255);由于两个对象(参数和 telnetlib.IAC
)具有不同的类型,因此失败。
显然,解决方法是一直只使用 bytes
个对象(类似于字符串,但前缀为 b
):
HOST = b"www.google.com"
tn=telnetlib.Telnet(HOST, 80)
tn.write(b"GET /index.html HTTP/1.1\nHost:"+HOST+b"\n\n")
l=tn.read_all()
print(l)
好的是,你也可以在 Python 2 中使用 b
前缀的字符串(来自 Python 2.6),它们只是常规的 Python 2 个字符串,因此代码适用于两个版本。您还可以查看 2to3
to make code porting to Python 3 easier (more on the topic here).
我猜 telnet 将希望以字节为单位工作,而不是您拥有的 unicode。
也许尝试编码?
tn.write(("GET /index.html HTTP/1.1\nHost:"+HOST+"\n\n").encode('ascii'))