Pythonで文字列のbプレフィックスを削除するにはどうすればよいですか?


90

私がインポートしているツイートの多くは、彼らが読んだところでこの問題を抱えています

b'I posted a new photo to Facebook'

bはそれがバイトであることを示すものを集めます。しかし、これは問題があることが証明されています。なぜなら、私が書いたCSVファイルでbは、が消えず、将来のコードに干渉するからです。

bテキストの行からこのプレフィックスを削除する簡単な方法はありますか?

テキストをutf-8でエンコードする必要があるようです。そうしないと、tweepyでテキストをWebから取得できません。


私が分析しているリンクの内容は次のとおりです。

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 2017年

@RomanPerekhrest申し訳ありませんが、もっと何が欲しいですか?コードまたは出力?
スタン・シャンパイク2017年

ファイルを開くときは、常にエンコーディングを指定してください。
MKesper 2017年

回答:


146

あなたがする必要が解読bytesあなたのは、文字列をしたいです:

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

質問を更新しました。この方法はうまくいかないと思います。もしそうなら、その理由を詳しく説明していただけますか?
スタン・シャンパイク2017年

4
.encode("utf-8").decode("utf-8")まったく何もしません(それがまったく機能する場合)...あなたはPython 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'"
スタンシャンパイク2017年

cp1252としてエンコードされていることをどのように判断できますか?私も.encode("utf-8").decode("utf-8")何もしないと思いましたが、ここの人たちはそれが正解だと思っていたようで、私が見る限りではありません。
スタン・シャンパイク2017年

私はあなたのトレースバックでこのパスを見つけました:C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py。あなたはおそらくそれがどのように/どこで使われているのかを見つけようとするべきです。ああ、あなたはcsv.writer;を使用しています。その場合、あなたはstr確かにnotを書く必要がありますbytes。あなたは物事を手に入れていますrequestsか?Webリソースから取得するエンコーディングは、とは異なる場合があります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>

6

文字列に変換するには、デコードする必要があります。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それを削除してもそれは解決しませんでした。uが提案するようにデコードを使用しても、エラーが発生します。それを投稿します。
スタン・シャンパイク2017年

完了しました。それを行うにはTwitterのOAuthコードが必要なので、まったく同じではありません。しかし、私が与えた例を実行するだけで、同じ問題が発生します。uが提案した方法では解決されません。utf-8を元に戻すだけです。しかし、utf-8エンコードなしではツイート内の文字を処理しないため、これは機能しません
Stan Shunpike 2017年

もちろん、正しいエンコーディングを使用する必要があります。 utf-8例でした。
salmanwahed 2017年

5

**** Pythonで文字列がデコードされたb ''文字を削除する方法****

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

2

django2.0を使用するPython3.6では、バイトリテラルでのデコードが期待どおりに機能しません。ええ、印刷すると正しい結果が得られますが、正しく印刷してもb'value 'はまだそこにあります。

これはimエンコーディングです

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

これはimデコードです:

uid = force_text(urlsafe_base64_decode(uidb64))

これはdjango2.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-Version:1.0 Content-Transfer-Encoding:7bit Subject:Activate Your MySite Account From:webmaster @ localhost To:testuser@yahoo.com Date:Fri、20 Apr 2018 06:26:46- 0000メッセージID:<152420560682.16725.4597194169307598579 @ Dash-U>

こんにちはテストユーザー、

以下のリンクをクリックして、登録を確認してください。

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
>>> 

調査したところ、Python3に関連しているようです。私の回避策は非常に簡単でした。

'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/

今では正常に動作します。:)


問題はデコードではなく、デコードと同じようにバイトリテラルを文字列にストリップできないテンプレートの自動エスケープオフであると私は信じています。
フェルナンドDハイメ

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'"。とにかく、これは質問の内容ではありません。
トリプリー2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.