파이썬에서 문자열의 b 접두사를 어떻게 제거합니까?


87

내가 가져 오는 많은 트윗에서 읽은이 문제가 있습니다.

b'I posted a new photo to Facebook'

나는 b그것이 바이트 라는 것을 나타냅니다. 그러나 이것은 내가 작성하는 CSV 파일에서 b사라지지 않고 향후 코드를 방해 하기 때문에 문제가 있음을 증명 합니다.

b내 텍스트 줄 에서이 접두사 를 제거하는 간단한 방법이 있습니까?

utf-8로 인코딩 된 텍스트가 필요하거나 tweepy가 웹에서 텍스트를 가져 오는 데 문제가있는 것 같습니다.


분석중인 링크 콘텐츠는 다음과 같습니다.

https://www.dropbox.com/s/sjmsbuhrghj7abt/new_tweets.txt?dl=0

new_tweets = 'content in the link'

코드 시도

outtweets = [[tweet.text.encode("utf-8").decode("utf-8")] for tweet in new_tweets]
print(outtweets)

오류

UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-21-6019064596bf> in <module>()
      1 for screen_name in user_list:
----> 2     get_all_tweets(screen_name,"instance file")

<ipython-input-19-e473b4771186> in get_all_tweets(screen_name, mode)
     99             with open(os.path.join(save_location,'%s.instance' % screen_name), 'w') as f:
    100                 writer = csv.writer(f)
--> 101                 writer.writerows(outtweets)
    102         else:
    103             with open(os.path.join(save_location,'%s.csv' % screen_name), 'w') as f:

C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py in encode(self, input, final)
     17 class IncrementalEncoder(codecs.IncrementalEncoder):
     18     def encode(self, input, final=False):
---> 19         return codecs.charmap_encode(input,self.errors,encoding_table)[0]
     20 
     21 class IncrementalDecoder(codecs.IncrementalDecoder):

UnicodeEncodeError: 'charmap' codec can't encode characters in position 64-65: character maps to <undefined>

텍스트 줄의 적어도 일부를 표시 할 수 있습니까?
— RomanPerekhrest

@RomanPerekhrest 죄송합니다. 무엇을 더 원하십니까? 코드 또는 출력?
— Stan Shunpike

파일을 열 때 항상 인코딩을 지정하십시오.
— MKesper

답변:


136

당신은 할 필요가 디코딩bytes 당신의 문자열을 원하는 :

b = b'1234'
print(b.decode('utf-8'))  # '1234'

질문을 업데이트했습니다. 이 방법은 효과가 없다고 생각합니다. 그렇다면 이유를 설명해 주시겠습니까?
— Stan Shunpike

4
.encode("utf-8").decode("utf-8")아무것도하지 않습니다 (아무것도 작동한다면) ... 당신은 파이썬 3을 사용하고 있습니까? py3는 bytes과 사이에 강한 구별이 str있습니다. 코드에서 cp1252인코딩 을 사용하는 것 같습니다. 파일을 열고 파일에 open(..., mode='w', encoding='utf-8')쓰기 만 시도 할 수 str있습니다. 또는 모든 인코딩을 잊어 버리고 파일을 바이너리로 작성하십시오. open(..., mode='wb')(참고 b) bytes. 도움이 되나요?
— 히로의 주인공

아니, 그것은 그것을 고치지 않습니다. 내가 가지고"b'Due to the storms this weekend, we have rescheduled the Blumenfield Bike Ride for Feb 26. Hope to see you there.\xe2\x80\xa6'"
— 스탠 Shunpike에게

cp1252로 인코딩한다고 어떻게 알 수 있습니까? 나는 또한 .encode("utf-8").decode("utf-8")아무것도 할 것이라고 생각하지 않았지만 여기 사람들은 그것이 정답이라고 생각하는 것 같았고 내가 볼 수있는 한 멀지 않았습니다.
— Stan Shunpike

나는 당신의 추적 에서이 경로를 발견했습니다 : C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py. 당신은 아마도 그것이 어떻게 / 어디에서 사용되는지 알아 내야 할 것입니다. 아, 그리고 당신은 사용하고 있습니다 csv.writer; 이 경우 str실제로 not bytes. 에서 물건을 얻고 requests있습니까? 웹 리소스에서 가져온 인코딩은와 다를 수 있습니다 utf-8.
— 히로의 주인공

19

인쇄하는 객체가 문자열이 아니라 바이트 리터럴 로서의 바이트 객체라는 것을 알려주는 것 입니다. 사람들은 이것을 불완전한 방식으로 설명하므로 여기에 내 의견이 있습니다.

바이트 리터럴을 입력하고 (문자 그대로 바이트 객체를 사용하지 않고 예를 들어 b ''를 입력하여 바이트 객체를 정의) utf-8로 인코딩 된 문자열 객체 로 변환 하여 바이트 객체 를 생성하는 것을 고려하십시오 . (여기서 변환은 디코딩을 의미합니다. )

byte_object= b"test" # byte object by literally typing characters
print(byte_object) # Prints b'test'
print(byte_object.decode('utf8')) # Prints "test" without quotations

단순히 .decode(utf8)함수 를 적용하는 것을 볼 수 있습니다 .

Python의 바이트

https://docs.python.org/3.3/library/stdtypes.html#bytes

문자열 리터럴은 다음 어휘 정의로 설명됩니다.

https://docs.python.org/3.3/reference/lexical_analysis.html#string-and-bytes-literals

stringliteral   ::=  [stringprefix](shortstring | longstring)
stringprefix    ::=  "r" | "u" | "R" | "U"
shortstring     ::=  "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring      ::=  "'''" longstringitem* "'''" | '"""' longstringitem* '"""'
shortstringitem ::=  shortstringchar | stringescapeseq
longstringitem  ::=  longstringchar | stringescapeseq
shortstringchar ::=  <any source character except "\" or newline or the quote>
longstringchar  ::=  <any source character except "\">
stringescapeseq ::=  "\" <any source character>

bytesliteral   ::=  bytesprefix(shortbytes | longbytes)
bytesprefix    ::=  "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"
shortbytes     ::=  "'" shortbytesitem* "'" | '"' shortbytesitem* '"'
longbytes      ::=  "'''" longbytesitem* "'''" | '"""' longbytesitem* '"""'
shortbytesitem ::=  shortbyteschar | bytesescapeseq
longbytesitem  ::=  longbyteschar | bytesescapeseq
shortbyteschar ::=  <any ASCII character except "\" or newline or the quote>
longbyteschar  ::=  <any ASCII character except "\">
bytesescapeseq ::=  "\" <any ASCII character>

5

문자열로 변환하려면 디코딩해야합니다. python3의 바이트 리터럴에 대한 답변을 확인하십시오 .

In [1]: b'I posted a new photo to Facebook'.decode('utf-8')
Out[1]: 'I posted a new photo to Facebook'

1
이것의 문제는 encode("utf-8")내가 짹짹을 다운로드하려고 할 때 오류가 발생 한다는 것입니다. 그리고 여기에서 언급했듯이 stackoverflow.com/q/41915383/4422095 제거하면 해결되지 않았습니다. 내가 제안한대로 디코딩을 사용하더라도 여전히 오류가 발생합니다. 게시물에 게시하겠습니다.
— Stan Shunpike

끝난. 그것을 수행하려면 트위터 OAuth 코드가 필요하기 때문에 정확히 동일하지 않습니다. 그러나 내가 준 예제를 수행하면 동일한 문제가 발생합니다. u가 제안한 방법으로 해결되지 않습니다. utf-8을 실행 취소합니다. 그러나 작업이 UTF-8 인코딩없이 트윗의 문자 처리하지 않습니다하지 않기 때문에 그
— 스탠 Shunpike

코스의 올바른 인코딩을 사용해야합니다. utf-8예였습니다.
— salmanwahed

4

**** python에서 디코딩 된 문자열 인 b ''문자를 제거하는 방법 ****

import base64
a='cm9vdA=='
b=base64.b64decode(a).decode('utf-8')
print(b)

2

django 2.0이있는 python 3.6에서 바이트 리터럴에 대한 디코딩이 예상대로 작동하지 않습니다. 예, 인쇄하면 올바른 결과를 얻지 만 올바르게 인쇄하더라도 b'value '는 여전히 있습니다.

이것이 바로 메신저 인코딩입니다.

uid': urlsafe_base64_encode(force_bytes(user.pk)),

이것이 바로 메신저 디코딩입니다.

uid = force_text(urlsafe_base64_decode(uidb64))

이것은 django 2.0이 말하는 것입니다.

urlsafe_base64_encode(s)[source]

URL에서 사용하기 위해 base64로 바이트 문자열을 인코딩하고 후행 등호를 제거합니다.

urlsafe_base64_decode(s)[source]

base64로 인코딩 된 문자열을 디코딩하여 제거되었을 수있는 후행 등호를 다시 추가합니다.


이것은 내 account_activation_email_test.html 파일입니다.

{% autoescape off %}
Hi {{ user.username }},

Please click on the link below to confirm your registration:

http://{{ domain }}{% url 'accounts:activate' uidb64=uid token=token %}
{% endautoescape %}

이것은 내 콘솔 응답입니다.

콘텐츠 유형 : 텍스트 / 일반; charset = "utf-8"MIME- 버전 : 1.0 Content-Transfer-Encoding : 7bit 제목 : MySite 계정 활성화 보낸 사람 : webmaster @ localhost받는 사람 : testuser@yahoo.com 날짜 : 2018 년 4 월 20 일 금요일 06:26:46- 0000 메시지 ID : <152420560682.16725.4597194169307598579@Dash-U>

안녕하세요 testuser 님,

등록을 확인하려면 아래 링크를 클릭하십시오.

http://127.0.0.1:8000/activate/b'MjU'/4vi-fasdtRf2db2989413ba/

보시다시피 uid = b'MjU'

예상 uid = MjU


콘솔에서 테스트 :

$ python
Python 3.6.4 (default, Apr  7 2018, 00:45:33) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
>>> from django.utils.encoding import force_bytes, force_text
>>> var1=urlsafe_base64_encode(force_bytes(3))
>>> print(var1)
b'Mw'
>>> print(var1.decode())
Mw
>>> 

조사 후 파이썬 3과 관련된 것 같습니다. 내 해결 방법은 매우 간단했습니다.

'uid': user.pk,

활성화 기능에서 uidb64로 수신합니다.

user = User.objects.get(pk=uidb64)

그리고 짜잔 :

Content-Transfer-Encoding: 7bit
Subject: Activate Your MySite Account
From: webmaster@localhost
To: testuser@yahoo.com
Date: Fri, 20 Apr 2018 20:44:46 -0000
Message-ID: <152425708646.11228.13738465662759110946@Dash-U>


Hi testuser,

Please click on the link below to confirm your registration:

http://127.0.0.1:8000/activate/45/4vi-3895fbb6b74016ad1882/

이제 잘 작동합니다. :)


문제는 디코드가 아니라 디코드처럼 바이트 리터럴을 문자열로 제거 할 수없는 템플릿의 자동 이스케이프 기능이라고 생각합니다.
— Fernando D Jaime

1

utf-8을 사용하여 출력 만 인코딩하여 완료했습니다. 다음은 코드 예제입니다.

new_tweets = api.GetUserTimeline(screen_name = user,count=200)
result = new_tweets[0]
try: text = result.text
except: text = ''

with open(file_name, 'a', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerows(text)

즉 : api에서 데이터를 수집 할 때 인코딩하지 말고 출력 (인쇄 또는 쓰기) 만 인코딩하십시오.


0

다른 사람들이 여기에서 제안한 것처럼 즉시 다시 디코딩하고 싶지 않다고 가정하면 문자열로 구문 분석 한 다음 선행 'b및 후행을 제거 할 수 있습니다 '.

>>> x = "Hi there 😄" 
>>> x = "Hi there 😄".encode("utf-8") 
>>> x
b"Hi there \xef\xbf\xbd"
>>> str(x)[2:-1]
"Hi there \\xef\\xbf\\xbd"   

-2

질문이 매우 오래되었지만 같은 문제에 직면 한 사람에게 도움이 될 것이라고 생각합니다. 여기 텍스트는 아래와 같은 문자열입니다.

text= "b'I posted a new photo to Facebook'"

따라서 b는 바이트가 아니기 때문에 인코딩하여 제거 할 수 없습니다. 나는 그것을 제거하기 위해 다음을 수행했습니다.

cleaned_text = text.split("b'")[1]

줄 것이다 "I posted a new photo to Facebook"


3
아니요, "I posted a new photo to Facebook'". 어쨌든 이것은 질문의 내용이 아닙니다.
— tripleee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.