Làm cách nào để loại bỏ tiền tố b trong một chuỗi trong python?


88

Một loạt các tweet tôi đang nhập gặp sự cố này khi họ đọc

b'I posted a new photo to Facebook'

Tôi thu thập bchỉ ra rằng nó là một byte. Nhưng điều này được chứng minh là có vấn đề vì trong các tệp CSV mà tôi cuối cùng viết, bnó không biến mất và đang làm gián đoạn mã trong tương lai.

Có cách nào đơn giản để xóa btiền tố này khỏi các dòng văn bản của tôi không?

Xin lưu ý rằng dường như tôi cần phải mã hóa văn bản bằng utf-8 hoặc tweepy gặp sự cố khi kéo chúng khỏi web.


Đây là nội dung liên kết tôi đang phân tích:

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

new_tweets = 'content in the link'

Mã thử

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

lỗi

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>

bạn có thể hiển thị ít nhất một phần của những dòng văn bản đó không?
RomanPerekhrest

@RomanPerekhrest Tôi xin lỗi, bạn muốn gì hơn? Mã hoặc đầu ra?
Stan Shunpike

Luôn chỉ định mã hóa khi mở tệp.
MKesper

Câu trả lời:


136

bạn cần phải giải mã các bytesbạn muốn có một chuỗi:

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

Tôi đã cập nhật câu hỏi. Tôi không nghĩ rằng phương pháp này hiệu quả. Nếu có, bạn có thể giải thích tại sao không?
Stan Shunpike

4
.encode("utf-8").decode("utf-8")hoàn toàn không có gì (nếu nó hoạt động ở tất cả) ... bạn đang ở trên python 3, phải không? py3 có sự phân biệt rõ ràng giữa bytesstr. một cái gì đó trong mã của bạn dường như sử dụng cp1252mã hóa ... bạn có thể thử mở tệp của mình bằng open(..., mode='w', encoding='utf-8')và chỉ ghi strvào tệp; hoặc bạn quên tất cả mã hóa và ghi tệp ở dạng nhị phân: open(..., mode='wb')(lưu ý b) và chỉ ghi bytes. cái đó có giúp ích không?
nhân vật chính hiro

Không, điều đó không khắc phục được. Tôi nhận được"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'"
Stan Shunpike

Làm thế nào bạn có thể biết nó mã hóa là cp1252? Tôi cũng không nghĩ .encode("utf-8").decode("utf-8")sẽ làm gì cả, nhưng những người ở đây dường như nghĩ rằng đó là câu trả lời đúng, điều mà tôi có thể thấy là không.
Stan Shunpike

tôi phát hiện con đường này trong bạn traceback: C:\Users\Stan Shunpike\Anaconda3\lib\encodings\cp1252.py. bạn có thể nên cố gắng tìm hiểu cách / nơi mà nó được sử dụng. ồ, và bạn đang sử dụng csv.writer; trong trường hợp đó bạn cần phải viết strthực sự là không bytes. bạn đang nhận được những thứ từ requests? mã hóa bạn nhận được từ tài nguyên web có thể khác utf-8.
nhân vật chính hiro

19

Nó chỉ cho bạn biết rằng đối tượng bạn đang in không phải là một chuỗi, mà là một đối tượng byte dưới dạng ký tự byte . Mọi người giải thích điều này theo những cách không đầy đủ, vì vậy đây là ý kiến ​​của tôi.

Xem xét việc tạo một đối tượng byte bằng cách nhập ký tự byte (theo nghĩa đen là xác định đối tượng byte mà không thực sự sử dụng đối tượng byte, ví dụ bằng cách nhập b '') và chuyển đổi nó thành đối tượng chuỗi được mã hóa bằng utf-8. (Lưu ý rằng chuyển đổi ở đây có nghĩa là giải mã )

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

Bạn thấy rằng chúng tôi chỉ đơn giản là áp dụng .decode(utf8)chức năng.

Byte trong Python

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

Các ký tự chuỗi được mô tả bằng các định nghĩa từ vựng sau:

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

Bạn cần giải mã nó để chuyển nó thành chuỗi. Kiểm tra câu trả lời ở đây về byte theo nghĩa đen trong python3 .

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

1
vấn đề với điều này là, khi tôi cố gắng tải xuống các tweet mà không encode("utf-8")gặp lỗi. Và, như tôi đã đề cập ở đây, việc xóa stackoverflow.com/q/41915383/4422095 không giải quyết được nó. Ngay cả khi tôi sử dụng giải mã như bạn đề xuất, tôi vẫn gặp lỗi. Tôi sẽ đăng điều đó trong bài viết.
Stan Shunpike

làm xong. nó không hoàn toàn giống nhau vì bạn cần mã OAuth trên twitter để làm điều đó. nhưng nếu bạn chỉ làm ví dụ tôi đã đưa ra, bạn sẽ nhận được vấn đề tương tự. nó không được giải quyết bằng phương pháp u gợi ý. nó chỉ hoàn tác utf-8. nhưng điều đó không làm việc vì nó sẽ không xử lý các nhân vật trong tweets mà không utf-8 encoding
Stan Shunpike

Tất nhiên, bạn phải sử dụng mã hóa chính xác. utf-8là một ví dụ.
chào đón

4

**** Cách xóa ký tự b '' được giải mã chuỗi trong python ****

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

2

Trên python 3.6 với django 2.0, giải mã trên một ký tự byte không hoạt động như mong đợi. Vâng, tôi nhận được kết quả đúng khi tôi in nó, nhưng b'value 'vẫn ở đó ngay cả khi bạn in nó đúng.

Đây là những gì tôi mã hóa

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

Đây là những gì tôi đang giải mã:

uid = force_text(urlsafe_base64_decode(uidb64))

Đây là những gì django 2.0 nói:

urlsafe_base64_encode(s)[source]

Mã hóa bytestring trong base64 để sử dụng trong URL, loại bỏ bất kỳ dấu bằng nào ở cuối.

urlsafe_base64_decode(s)[source]

Giải mã một chuỗi được mã hóa base64, thêm lại bất kỳ dấu bằng nào ở cuối có thể đã bị loại bỏ.


Đây là tệp account_activation_email_test.html của tôi

{% 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 %}

Đây là phản hồi trên bảng điều khiển của tôi:

Nội dung-Loại: văn bản / đơn giản; charset = "utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Chủ đề: Kích hoạt tài khoản MySite của bạn Từ: webmaster @ localhost Tới: testuser@yahoo.com Ngày: Thứ sáu, 20 tháng 4 năm 2018 06:26:46 - 0000 ID tin nhắn: <152420560682.16725.4597194169307598579@Dash-U>

Xin chào người thử nghiệm,

Vui lòng nhấp vào liên kết dưới đây để xác nhận đăng ký của bạn:

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

bạn có thể thấy uid = b'MjU'

hy vọng uid = MjU


kiểm tra trong bảng điều khiển:

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

Sau khi điều tra, có vẻ như nó liên quan đến python 3. Cách giải quyết của tôi khá đơn giản:

'uid': user.pk,

tôi nhận được nó dưới dạng uidb64 trên chức năng kích hoạt của tôi:

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

và Voila:

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/

bây giờ nó hoạt động tốt. :)


Tôi tin rằng vấn đề không phải là giải mã mà thay vào đó là tự động tắt trong khuôn mẫu không thể tách ký tự byte thành một chuỗi giống như giải mã.
Fernando D Jaime

1

Tôi đã hoàn thành nó bằng cách chỉ mã hóa đầu ra bằng utf-8. Đây là ví dụ mã

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)

nghĩa là: không mã hóa khi thu thập dữ liệu từ api, chỉ mã hóa đầu ra (in hoặc ghi).


0

Giả sử bạn không muốn giải mã nó ngay lập tức như những người khác đang đề xuất ở đây, bạn có thể phân tích cú pháp nó thành một chuỗi và sau đó chỉ cần tách phần đầu 'bvà cuối '.

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

Mặc dù câu hỏi rất cũ, nhưng tôi nghĩ nó có thể hữu ích cho những ai đang đối mặt với cùng một vấn đề. Đây là một chuỗi như sau:

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

Vì vậy, bạn không thể loại bỏ b bằng cách mã hóa nó vì nó không phải là một byte. Tôi đã làm như sau để loại bỏ nó.

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

cái nào sẽ cho "I posted a new photo to Facebook"


3
Không, điều đó sẽ cho "I posted a new photo to Facebook'". Dù sao thì đây không phải là câu hỏi.
tripleee
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.