Python dizesindeki HTML objeleri çözülsün mü?


266

Güzel Çorba 3 ile bazı HTML ayrıştırıyorum, ama Güzel Çorba 3 benim için otomatik olarak kod çözme değil HTML varlıkları içerir:

>>> from BeautifulSoup import BeautifulSoup

>>> soup = BeautifulSoup("<p>&pound;682m</p>")
>>> text = soup.find("p").string

>>> print text
&pound;682m

Nasıl HTML varlıkları deşifre edebilir textalmak "£682m"yerine "&pound;682m".


Yanıtlar:


521

Python 3.4+

Kullanım html.unescape():

import html
print(html.unescape('&pound;682m'))

FYI html.parser.HTMLParser.unescapekullanımdan kaldırıldı ve yanlışlıkla bırakılmasına rağmen 3.5'te kaldırılması gerekiyordu . Yakında dilden kaldırılacak.


Python 2.6-3.3

HTMLParser.unescape()Standart kitaplıktan kullanabilirsiniz :

>>> try:
...     # Python 2.6-2.7 
...     from HTMLParser import HTMLParser
... except ImportError:
...     # Python 3
...     from html.parser import HTMLParser
... 
>>> h = HTMLParser()
>>> print(h.unescape('&pound;682m'))
£682m

sixİçe aktarmayı basitleştirmek için uyumluluk kitaplığını da kullanabilirsiniz :

>>> from six.moves.html_parser import HTMLParser
>>> h = HTMLParser()
>>> print(h.unescape('&pound;682m'))
£682m

9
bu yöntemin "& # 8217;" Google uygulama motorunda, python2.6'da yerel olarak çalışmasına rağmen. Hala en azından
kodları

Belgelenmemiş bir API nasıl kullanımdan kaldırılabilir? Cevabı düzenledi.
Markus Unterwaditzer

@MarkusUnterwaditzer belgesiz bir yöntemin itiraz edilememesi için hiçbir neden yoktur. Bu, kullanımdan kaldırma uyarıları atar - cevaba yapılan düzenlememe bakın.
Mark Amery

Sadece modülden ziyade unescape, tüm HTMLParsermodülün lehine reddedilmesi daha mantıklı görünecektir html.parser.
Tom Russell

Python 2 için dikkat çekmeye değer: Özel karakterler, Latin-1 (ISO-8859-1) kodlayan meslektaşlarıyla değiştirilir. Örneğin, gerekli olabilir h.unescape(s).encode("utf-8"). Dokümanlar: "" "Burada verilen tanım, XHTML 1.0 tarafından tanımlanan ve Latin-1 karakter setinde (ISO-8859-1)" ""
anonim korkak

65

Güzel Çorba varlık dönüşüm yönetir. Güzel Çorba 3'te, yapıcıya convertEntitiesargümanı belirtmeniz gerekir BeautifulSoup( arşivlenen dokümanların 'Varlık Dönüşümü' bölümüne bakın). Güzel Çorba 4'te varlıklar otomatik olarak çözülür.

Güzel çorba 3

>>> from BeautifulSoup import BeautifulSoup
>>> BeautifulSoup("<p>&pound;682m</p>", 
...               convertEntities=BeautifulSoup.HTML_ENTITIES)
<p682m</p>

Güzel çorba 4

>>> from bs4 import BeautifulSoup
>>> BeautifulSoup("<p>&pound;682m</p>")
<html><body><p682m</p></body></html>

+1. Bunu dokümanlarda nasıl kaçırdığımı bilmiyorum: bilgi için teşekkürler. Luc'un cevabını kabul edeceğim çünkü onun soruda belirttiğim standart lib'i (benim için önemli değil) ve muhtemelen diğer insanlara daha genel bir kullanımı var.
jkp

5
BeautifulSoup4HTMLParserçoğunlukla kullanır . Bkz kaynağı
scharfmn

4
Orijinal dizenin parçası olmayan tüm gereksiz HTML olmadan Güzel Çorba 4'te dönüşümü nasıl elde ederiz? (yani <html> ve <body>)
Praxiteles

@Praxiteles: BeautifulSoup ('& pound; 682m', "html.parser") stackoverflow.com/a/14822344/4376342
Soitje

13

W3lib.html kitaplığından replace_entities'i kullanabilirsiniz

In [202]: from w3lib.html import replace_entities

In [203]: replace_entities("&pound;682m")
Out[203]: u'\xa3682m'

In [204]: print replace_entities("&pound;682m")
£682m

2

Güzel Çorba 4, çıktınıza bir biçimlendirici ayarlamanızı sağlar

İçeri girerseniz formatter=None, Güzel Çorba çıktıdaki dizeleri hiç değiştirmez. Bu en hızlı seçenektir, ancak bu örneklerde olduğu gibi Güzel Çorbanın geçersiz HTML / XML oluşturmasına neden olabilir:

print(soup.prettify(formatter=None))
# <html>
#  <body>
#   <p>
#    Il a dit <<Sacré bleu!>>
#   </p>
#  </body>
# </html>

link_soup = BeautifulSoup('<a href="http://example.com/?foo=val1&bar=val2">A link</a>')
print(link_soup.a.encode(formatter=None))
# <a href="http://example.com/?foo=val1&bar=val2">A link</a>

Bu soruya cevap vermiyor. (Ayrıca, dokümanların burada HTML'nin son biti hakkında ne söylediğini bilmiyorum.)
Mark Amery

<< Sacré bleu! >>, kaçış <ve> olduğu ve çevresindeki html'yi kıracağı için geçersiz kısımdır. Bu benden geç bir yazı olduğunu biliyorum, ama kimse arıyor ve merak olur ...
GMasucci

0

Benzer bir kodlama sorunum vardı. Normalize () yöntemini kullandım. Veri çerçevemi başka bir dizindeki bir .html dosyasına verirken pandas .to_html () yöntemini kullanarak bir Unicode hatası alıyordum. Sonunda bunu yaptım ve işe yaradı ...

    import unicodedata 

Dataframe nesnesi istediğiniz gibi olabilir, buna tablo diyelim ...

    table = pd.DataFrame(data,columns=['Name','Team','OVR / POT'])
    table.index+= 1

tablo verilerini kodlar, böylece şablonlar klasöründeki .html dosyasına dışa aktarabiliriz (bu istediğiniz konum olabilir :))

     #this is where the magic happens
     html_data=unicodedata.normalize('NFKD',table.to_html()).encode('ascii','ignore')

normalize edilmiş dizeyi html dosyasına aktar

    file = open("templates/home.html","w") 

    file.write(html_data) 

    file.close() 

Referans: unicodedata belgeleri


-4

Bu muhtemelen burada alakalı değil. Ancak bu html girişlerini tüm bir belgeden kaldırmak için, şöyle bir şey yapabilirsiniz: (Belge = sayfa varsayalım ve lütfen özensiz kodu affedin, ancak nasıl daha iyi hale getireceğiniz konusunda fikirleriniz varsa, tüm kulaklarım - bu).

import re
import HTMLParser

regexp = "&.+?;" 
list_of_html = re.findall(regexp, page) #finds all html entites in page
for e in list_of_html:
    h = HTMLParser.HTMLParser()
    unescaped = h.unescape(e) #finds the unescaped value of the html entity
    page = page.replace(e, unescaped) #replaces html entity with unescaped value

7
Hayır! HTML öğelerini kendiniz eşleştirmeniz ve üzerlerinde döngü oluşturmanıza gerek yoktur; .unescape()bunu sizin için yapar . Siz ve Rob'un, kabul edilen cevap .unescape()dizede varlıkları bulabileceğini açıkça gösterdiğinde, kendi varlık eşleşmesini yuvarlayan bu aşırı karmaşık çözümleri neden yayınladığınızı anlamıyorum .
Mark Amery
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.