Python 将ser.readline()编码为UTF-8

Python 将ser.readline()编码为UTF-8,python,gps,byte,nmea,Python,Gps,Byte,Nmea,我有一个Neo 6M GPS模块,我正试图从中打印坐标。它目前正在以字节形式打印NMEA语句,并将\r\n粘贴在末尾。以下是一个例子: b'$GPGGA,161812.3714042.759,N,07400.317,W,1,12,1.0,0.0,M,0.0,M,,*7B\r\N' 要将字符串解析为坐标,我需要去掉\r、\n和b' 为此,我正在尝试.strip(“b'rn\\”)。事实证明,您只能剥离字符串,而不能剥离字节。 为了克服字节和strip的不兼容性,我尝试将字节解码为如下字符串:(se

我有一个Neo 6M GPS模块,我正试图从中打印坐标。它目前正在以字节形式打印NMEA语句,并将
\r\n
粘贴在末尾。以下是一个例子:

b'$GPGGA,161812.3714042.759,N,07400.317,W,1,12,1.0,0.0,M,0.0,M,,*7B\r\N'

要将字符串解析为坐标,我需要去掉
\r
\n
b'

为此,我正在尝试.strip(“b'rn\\”)。事实证明,您只能剥离字符串,而不能剥离字节。 为了克服字节和strip的不兼容性,我尝试将字节解码为如下字符串:
(ser.readline().decode(“utf-8”).strip(“b'rn\”)

此操作未运行,我收到以下错误:

Traceback (most recent call last):
  File "gps2.py", line 10, in <module>
    newdata = (ser.readline().decode("utf-8")).strip("b'rn\\")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfe in position 0: invalid start byte
注意:我把我原来的评论改成了一个答案,当它比一个评论长的时候,是为了回应OP对原来问题的放大


您无法摆脱
b'
。它不在数据中。这是一个Python约定,它向您显示您的数据是bytestring而不是常规字符串。调用
decode()
将把bytestring变成字符串。另一方面,
\r\n
在数据中。它表明您的设备正在使用回车符/换行符对终止字符串。这两个都算作空白。开头的字符
0xfe
是字节顺序标记对
\xfe\xff
的第一部分,可以丢弃。因此,您只需要
ser.readline()[2:].decode(“utf-8”).strip()

至于你在问题中没有提到,但只是在随后的评论中提到的无法解释的数据:

无论是设备还是它的文档,我所能做的仅仅是推测你想要的数据前面的明显的二进制数据。它当然不是我能识别的任何类型的字符数据:它不是UTF-8,也不是有效的UTF-16,我的直觉是它也不是东亚MBC。它不太可能是浮点或整数,因为没有一个零字节,二进制数字数据(和UTF-32)往往有很多这样的字节

但是如果您想要的数据以一个已知的常量开始,比如
$GPGGA,
,那么从您得到的流中选择您想要的应该不是很困难。例如,假设您得到

b'i\x9a\xcab\x82\xbab\x8a\xb2b\x92\xc2b\x92\xca\x9ab\x8a\xa2R\xba\xc2jR":A\x1dMY\xb1\xcd\xb1\xc9\xb1\xc5\xc1\xb1\xc5\xe1\xb1\xd1\xd9\xb1\xc5\xd5\xdd\xb1\xc9\xc1\xb1\xc9\xd5\xb1\xc9\xd5\xb1\xc5\xc5\xd9\xb1\xc5\xd1\xb1\xc9\xd9\xb1\xd9\xc5\xb1\xc9\xe5\xc9\xb1\xc5\xd1\xb1\xc9\xdd\xb1\xc1\xc9\xb1\xc9\xd1\xdd\xb1\xc1\xd9\xa9\xdd\x195)\x91\x1dA\x1dMY\xb1\xcd\xb1\xcd\xb1\xc5\xc1\xb1\xc9\xe5\xb1\xd5\xd9\xb1\xc1\xd9\xcd\xb1\xc9\xd1\xb1\xcd\xc5\xb1\xd1\xe5\xb1\xc9\xc1\xe5\xb1\xc5\xd5\xa9\xdd\xcd5)\x91\x1dA\x1d11\xb1\xd5\xc5\xc9\xd5\xb9\xe5\xe5\xc1\xc5\xe1\xb19\xb1\xc1\xc1\xc1\xc9\xd5\xb9\xd5\xe1\xd1\xc1\xcd\xb1]\xb1\xc9\xc1\xc1\xdd\xcd\xd9\xb9\xc1\xc1\xb1\x05\xb1\x05\xa9\xdd\r5)\xff\xfe\xff$GPGGA,161812.371,4042.759,N,07400.317,W,1,12,1.0,0.0,M,0.0,M,,*7B\r\n'
(大部分都是从你的Pastebin文件中复制的)然后你将其存储在
dataout
中。然后,
dataout.partition(b'$GPGGA',)[-1].decode().strip()
将为您提供所需的数字,无论
$GPGGA,
左侧是否有无法解释的二进制数据


站在你的立场上,我仍然想知道二进制数据是什么。我认为这更可能是由于串行数据传输的复杂性而不是设备中的任何缺陷造成的。我的猜测是,这是真实数据,但可能包含意外的数据位(它调用bytesize)、停止位或奇偶校验。对
serial.serial()
的调用采用8个数据位、无奇偶校验、一个停止位的默认值。我不知道
串行
模块有多聪明,但可能是在看到一些数据后,它可以从错误的初始值中恢复。调制解调器可以在25年前通过查看(公认的,预先指定的)前2个字节的数据来做到这一点。

您无法摆脱
b'
。它不在数据中。这是一个Python约定,它向您显示您的数据是bytestring而不是常规字符串。调用
decode()
将把bytestring变成字符串。另一方面,
\r\n
在数据中。它表明您的设备正在使用回车符/换行符对终止字符串。这两个都算作空白。开头的字符0xfe是字节顺序标记对\xfe\xff的第一部分,可以丢弃。因此,您所需要的就是
ser.readline()[2:].decode(“utf-8”)).strip()
@BoarGules这在某种程度上是可行的。我没有提到,当你开始监听串口时,GPS模块基本上会吐出垃圾,然后开始正确输出。这是它的输出,长度和内容可能有所不同。它并不总是这样做,在这种情况下,您的代码可以工作。
b'i\x9a\xcab\x82\xbab\x8a\xb2b\x92\xc2b\x92\xca\x9ab\x8a\xa2R\xba\xc2jR":A\x1dMY\xb1\xcd\xb1\xc9\xb1\xc5\xc1\xb1\xc5\xe1\xb1\xd1\xd9\xb1\xc5\xd5\xdd\xb1\xc9\xc1\xb1\xc9\xd5\xb1\xc9\xd5\xb1\xc5\xc5\xd9\xb1\xc5\xd1\xb1\xc9\xd9\xb1\xd9\xc5\xb1\xc9\xe5\xc9\xb1\xc5\xd1\xb1\xc9\xdd\xb1\xc1\xc9\xb1\xc9\xd1\xdd\xb1\xc1\xd9\xa9\xdd\x195)\x91\x1dA\x1dMY\xb1\xcd\xb1\xcd\xb1\xc5\xc1\xb1\xc9\xe5\xb1\xd5\xd9\xb1\xc1\xd9\xcd\xb1\xc9\xd1\xb1\xcd\xc5\xb1\xd1\xe5\xb1\xc9\xc1\xe5\xb1\xc5\xd5\xa9\xdd\xcd5)\x91\x1dA\x1d11\xb1\xd5\xc5\xc9\xd5\xb9\xe5\xe5\xc1\xc5\xe1\xb19\xb1\xc1\xc1\xc1\xc9\xd5\xb9\xd5\xe1\xd1\xc1\xcd\xb1]\xb1\xc9\xc1\xc1\xdd\xcd\xd9\xb9\xc1\xc1\xb1\x05\xb1\x05\xa9\xdd\r5)\xff\xfe\xff$GPGGA,161812.371,4042.759,N,07400.317,W,1,12,1.0,0.0,M,0.0,M,,*7B\r\n'