Kısa versiyon!
import re, cgi
tag_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
# Remove well-formed tags, fixing mistakes by legitimate users
no_tags = tag_re.sub('', user_input)
# Clean up anything else by escaping
ready_for_web = cgi.escape(no_tags)
Normal ifade kaynağı: MarkupSafe . Sürümleri HTML varlıklarını da ele alırken, bu hızlı olanı kullanmaz.
Neden etiketleri soyup bırakamıyorum?
İnsanları etrafta yüzmeye <i>italicizing</i>
bırakmadan şeylerden uzak tutmak bir şeydir i
. Ancak keyfi girdi almak ve tamamen zararsız hale getirmek başka bir şeydir. Bu sayfadaki tekniklerin çoğu, kapatılmamış yorumlar ( <!--
) ve etiketlerin ( blah <<<><blah
) bir parçası olmayan açılı ayraçlar gibi şeyleri olduğu gibi bırakacaktır . HTMLParser sürümü, kapatılmamış bir yorumun içindeyse, etiketleri tam olarak bırakabilir.
Şablonunuz ne olacak {{ firstname }} {{ lastname }}
? firstname = '<a'
ve lastname = 'href="http://evil.com/">'
bu sayfadaki her etiket çıkarıcı tarafından izin verilecektir (@Medeiros! hariç), çünkü kendi başlarına tam etiketler değildir. Normal HTML etiketlerini çıkarmak yeterli değildir.
strip_tags
Bu sorunun en iyi cevabının geliştirilmiş (bir sonraki başlığa bakınız) versiyonu olan Django's , aşağıdaki uyarıyı verir:
Sonuçta elde edilen dizginin HTML açısından güvenli olduğu konusunda kesinlikle HİÇBİR garanti verilmez. Bu nedenle, ASLA bir strip_tags
çağrının sonucunu önce kaçmadan güvenli bir şekilde işaretlemeyin , örneğin escape()
.
Onların tavsiyelerine uyun!
Etiketleri HTMLParser ile şeritlemek için, etiketi birden çok kez çalıştırmanız gerekir.
Bu sorunun en iyi cevabını atlatmak kolaydır.
Şu dizeye bakın ( kaynak ve tartışma ):
<img<!-- --> src=x onerror=alert(1);//><!-- -->
HTMLParser bunu ilk gördüğünde, bunun <img...>
bir etiket olduğunu söyleyemez . Bozuk görünüyor, bu yüzden HTMLParser ondan kurtulmuyor. Sadece <!-- comments -->
sizi çıkarır,
<img src=x onerror=alert(1);//>
Bu sorun Mart 2014'te Django projesine açıklandı. Eski strip_tags
soruları bu sorunun en büyük cevabı ile aynıydı. Yeni sürümleri temelde tekrar çalıştırıp dizeyi değiştirmeyene kadar bir döngüde çalıştırır:
# _strip_once runs HTMLParser once, pulling out just the text of all the nodes.
def strip_tags(value):
"""Returns the given HTML with all tags stripped."""
# Note: in typical case this loop executes _strip_once once. Loop condition
# is redundant, but helps to reduce number of executions of _strip_once.
while '<' in value and '>' in value:
new_value = _strip_once(value)
if len(new_value) >= len(value):
# _strip_once was not able to detect more tags
break
value = new_value
return value
Tabii ki, her zaman sonuçtan kaçarsanız bunların hiçbiri bir sorun değildir strip_tags()
.
Güncelleme 19 Mart 2015 : Django sürümlerinde 1.4.20, 1.6.11, 1.7.7 ve 1.8c1'den önce bir hata oluştu. Bu sürümler strip_tags () işlevine sonsuz bir döngü girebilir. Sabit sürüm yukarıda üretilmiştir. Daha fazla ayrıntı burada .
Kopyalamak veya kullanmak için iyi şeyler
Örnek kodum HTML varlıklarını işlemez - Django ve MarkupSafe paket sürümleri çalışır.
Örnek kodum, siteler arası komut dosyası önleme için mükemmel MarkupSafe kitaplığından alınmıştır. Kullanışlı ve hızlı (yerel Python sürümüne C hızları ile). Bu dahildir? Google App Engine ve kullandığı jinja2 (2.7 ve üstü) , Mako, elektrik direği ve daha fazlası. Django 1.7 Django şablonları ile kolayca çalışır.
Django'nun strip_tags ve son sürümdeki diğer html yardımcı programları iyidir, ancak MarkupSafe'den daha az uygun buluyorum. Oldukça bağımsızdırlar, ihtiyacınız olanı bu dosyadan kopyalayabilirsiniz .
Hemen hemen tüm etiketleri soymanız gerekiyorsa , Bleach kitaplığı iyidir. "Kullanıcılarım bir şeyleri italik yapabilir, ancak iframe yapamazlar" gibi kuralların uygulanmasını sağlayabilirsiniz.
Etiket soyucunuzun özelliklerini anlayın! Üzerinde fuzz testleri yap! İşte bu cevap için araştırma yapmak için kullandığım kod .
sheepish note - Sorunun kendisi konsola yazdırmakla ilgili, ancak bu "string'ten python strip html" için en iyi Google sonucudur, bu yüzden bu cevap web hakkında% 99'dur.
&
). Bunları 1) etiketlerle birlikte kaldırabilirsiniz (genellikle istenmeyen ve düz metne eşdeğer oldukları için gereksiz), 2) bunları değiştirmeden bırakın (soyulmuş metin HTML içeriğine geri dönüyorsa uygun bir çözüm) veya 3 ) bunları düz metin olarak çözün (soyulmuş metin bir veritabanına veya HTML olmayan başka bir içeriğe gidiyorsa veya web çerçeveniz sizin için metinden HTML çıkışını otomatik olarak gerçekleştiriyorsa).