Ciąg Pythona jest drukowany jako [u'String ']


142

Z pewnością będzie to łatwe, ale naprawdę mnie to niepokoi.

Mam skrypt, który czyta stronę internetową i analizuje ją za pomocą Beautiful Soup . Z zupy wyciągam wszystkie linki, moim ostatecznym celem jest wydrukowanie linku.contents.

Cały tekst, który analizuję, to ASCII. Wiem, że Python traktuje ciągi znaków jako Unicode i jestem pewien, że jest to bardzo przydatne, po prostu bezużyteczne w moim małym skrypcie.

Za każdym razem, gdy idę wydrukować zmienną zawierającą „String”, [u'String']pojawia się na ekranie. Czy istnieje prosty sposób na przywrócenie tego z powrotem do samego ascii, czy powinienem napisać wyrażenie regularne, aby je usunąć?


możliwy duplikat znacznie wyraźniej sformułowanego pytania (i odpowiedzi): stackoverflow.com/q/2464959/1390788
Terrabits

Odpowiedzi:


118

[u'ABC']byłaby jednoelementową listą ciągów znaków Unicode. Beautiful Soup zawsze tworzy Unicode . Musisz więc przekonwertować listę na pojedynczy ciąg znaków Unicode, a następnie przekonwertować go na ASCII.

Nie wiem dokładnie, skąd masz listy jednoelementowe; składnikiem zawartości byłaby lista ciągów i tagów, co najwyraźniej nie jest tym, co masz. Zakładając, że naprawdę zawsze otrzymujesz listę z jednym elementem i że twój test to tak naprawdę tylko ASCII, użyjesz tego:

 soup[0].encode("ascii")

Jednak sprawdź dokładnie, czy Twoje dane to naprawdę ASCII. To jest dość rzadkie. O wiele bardziej prawdopodobne jest, że jest to latin-1 lub utf-8.

 soup[0].encode("latin-1")


 soup[0].encode("utf-8")

Albo zapytasz Beautiful Soup, jakie było oryginalne kodowanie i odzyskaj je w tym kodowaniu:

 soup[0].encode(soup.originalEncoding)

6
W rzeczywistości nie musisz wykonywać kodowania, ponieważ OP widzi tylko łańcuch repr, ponieważ w ten sposób widzisz cokolwiek, gdy drukujesz listę. zupa [0] wystarczy, aby wyświetlić str zamiast repr, pokazując zawartość ciągu, a nie cytat i modyfikator unicode.
ironfroggy

2
W większości przypadków nie powinieneś kodować tekstu reprezentowanego jako Unicode do bajtów: powinieneś drukować Unicode bezpośrednio w Pythonie:print(', '.join([u'ABC' , u'...']))
jfs

26

Prawdopodobnie masz listę zawierającą jeden ciąg znaków Unicode. To reprjest to [u'String'].

Możesz przekonwertować to na listę ciągów bajtów, używając dowolnej odmiany z poniższych:

# Functional style.
print map(lambda x: x.encode('ascii'), my_list)

# List comprehension.
print [x.encode('ascii') for x in my_list]

# Interesting if my_list may be a tuple or a string.
print type(my_list)(x.encode('ascii') for x in my_list)

# What do I care about the brackets anyway?
print ', '.join(repr(x.encode('ascii')) for x in my_list)

# That's actually not a good way of doing it.
print ' '.join(repr(x).lstrip('u')[1:-1] for x in my_list)

1
Prosimy o unikanie takich okropności jak repr(x).lstrip('u')[1:-1]. print ", ".join(my_list)Zamiast tego użyj czegoś takiego jak :, aby sformatować listę ciągów Unicode.
jfs

1
W komentarzu jest napisane: „To właściwie nie jest dobry sposób na zrobienie tego”. Jest tu tylko dla lolz!
ddaa

9
import json, ast
r = {u'name': u'A', u'primary_key': 1}
ast.literal_eval(json.dumps(r)) 

wydrukuje

{'name': 'A', 'primary_key': 1}

1
ta metoda wygląda dla mnie całkiem słodko, dlaczego nie ma głosów? jakikolwiek wpływ na wydajność, o który powinniśmy się martwić?
jrich523

8

W przypadku uzyskiwania dostępu / drukowania list pojedynczych elementów (np. Sekwencyjnych lub filtrowanych):

my_list = [u'String'] # sample element
my_list = [str(my_list[0])]

1
robisz rozumienie listy:my_list = [str(my_list[x]) for x in range(len(my_list))]
gevang

4

przekaż dane wyjściowe do funkcji str (), co usunie konwersję wyjścia Unicode. również drukując wynik, usunie z niego tagi u ''.


4

[u'String'] jest tekstową reprezentacją listy zawierającej ciąg znaków Unicode w Pythonie 2.

Jeśli uruchomisz, print(some_list)jest to równoważne z
print'[%s]' % ', '.join(map(repr, some_list))np. Utworzeniem reprezentacji tekstowej obiektu Pythona z typem list, repr()funkcja jest wywoływana dla każdego elementu.

Nie należy mylić obiekt Pythona i jego reprezentację tekstową - repr('a') != 'a'a nawet reprezentacji tekstowy różni reprezentacji tekst: repr(repr('a')) != repr('a').

repr(obj)zwraca ciąg zawierający drukowalną reprezentację obiektu. Jego celem jest niedwuznaczna reprezentacja obiektu, który może być przydatny do debugowania w REPL. Często eval(repr(obj)) == obj.

Aby uniknąć wywoływania repr(), możesz wydrukować elementy listy bezpośrednio (jeśli wszystkie są łańcuchami Unicode), np .: print ",".join(some_list)—wypisuje listę ciągów oddzielonych przecinkami:String

Nie koduj ciągu znaków Unicode do bajtów przy użyciu zakodowanego na stałe kodowania znaków, zamiast tego drukuj bezpośrednio Unicode . W przeciwnym razie kod może się nie powieść, ponieważ kodowanie nie może reprezentować wszystkich znaków, np. Jeśli spróbujesz użyć 'ascii'kodowania ze znakami spoza ASCII. Albo kod po cichu tworzy mojibake (uszkodzone dane są przekazywane dalej w potoku), jeśli środowisko używa kodowania, które jest niezgodne z kodowaniem zakodowanym na stałe.


3

Użyj dirlub typena 'string', aby dowiedzieć się, co to jest. Podejrzewam, że jest to jeden z obiektów tagów BeautifulSoup, który drukuje jak ciąg, ale tak naprawdę nim nie jest. W przeciwnym razie znajduje się wewnątrz listy i musisz konwertować każdy ciąg oddzielnie.

W każdym razie, dlaczego sprzeciwiasz się używaniu Unicode? Z jakiegoś konkretnego powodu?


Patrzę na BeautifulSoup od kilku dni. Nie mogłem dowiedzieć się, jak gnuchu może dostać u ['string'], a nie [u'String ']. Jego komentarz do Andrew Jaffe wydaje się potwierdzać, że jest to lista.
batbrat

3

Naprawdę masz na myśli u'String'?

W każdym razie, czy nie możesz po prostu zrobić str(string)ciągu znaków zamiast łańcucha znaków Unicode? (Powinno to wyglądać inaczej dla Pythona 3, dla którego wszystkie ciągi znaków są w formacie Unicode).


Powinienem był być jaśniejszy. Używam str (), ale nadal otrzymuję dane wyjściowe jak poniżej podczas drukowania. [u'ABC '] [u'DEF'] [u'GHI '] [u'JKL'] Dane są usuwane jako tekst ze strony internetowej, a następnie wstawiane do bazy danych (Google Appstore), a następnie pobierane i drukowane.
gnuchu

-1

encode("latin-1") pomogło mi w moim przypadku:

facultyname[0].encode("latin-1")

-1

Może nie rozumiem, dlaczego nie możesz po prostu pobrać elementu.text i przekonwertować go przed użyciem? na przykład (nie wiem, dlaczego miałbyś to zrobić, ale ...) znajdź wszystkie elementy etykiety na stronie internetowej i iteruj między nimi, aż znajdziesz jeden o nazwie MyText

        avail = []
        avail = driver.find_elements_by_class_name("label");
        for i in avail:
                if  i.text == "MyText":

Przekonwertuj ciąg z i i zrób wszystko, co chcesz ... może brakuje mi czegoś w oryginalnej wiadomości? czy to było to, czego szukałeś?


Brakuje Ci części, w której pytanie dotyczy tego, jak wykonać „Konwersję ciągu z i”.
Nathan Tuggy

ahhh, dzięki wszystkim komentarzom, myślałem, że problem polegał na uzyskaniu wartości do konwersji
Steven

ale żeby być uczciwym i.text jest rzeczywistą wartością ciągu, nie ma potrzeby "wyciągania go z tablicy", jak sugerowali niektórzy, jeśli na przykład element etykiety ma wartość tekstową [u'String '] i.text będzie String
Steven
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.