Użycie modułu Beautiful Soup Python do zastąpienia tagów zwykłym tekstem

ja używamPiękna Zupa wyodrębnić „treść” ze stron internetowych. Wiem, że niektórzy ludzie o to pytalipytanie wcześniej i wszyscy wskazywali na piękną zupę i tak zacząłem z tym.

Udało mi się uzyskać większość treści, ale napotykam na pewne wyzwania z tagami, które są częścią treści. (Zaczynam od podstawowej strategii: jeśli w węźle jest więcej niż x znaków, to jest to treść). Weźmy poniższy kod HTML jako przykład:

<div id="abc">
    some long text goes <a href="/"> here </a> and hopefully it 
    will get picked up by the parser as content
</div>

results = soup.findAll(text=lambda(x): len(x) > 20)

Kiedy używam powyższego kodu, aby uzyskać długi tekst, pęka (zidentyfikowany tekst zacznie się od „i miejmy nadzieję ...”) w tagach. Próbowałem więc zastąpić tag zwykłym tekstem w następujący sposób:

anchors = soup.findAll('a')

for a in anchors:
  a.replaceWith('plain text')

Powyższe nie działa, ponieważ Beautiful Soup wstawia ciąg znaków jako ciąg nawigacyjny, co powoduje ten sam problem, gdy używam findAll z len (x)> 20. Mogę użyć wyrażeń regularnych, aby najpierw przeanalizować HTML jako zwykły tekst, usunąć wszystkie niechciane znaczniki, a następnie zadzwoń do Pięknej Zupy. Ale chciałbym uniknąć dwukrotnego przetwarzania tej samej treści - próbuję przeanalizować te strony, aby móc wyświetlić fragment treści dla danego linku (bardzo podobny do Facebook Share) - i jeśli wszystko jest zrobione z Beautiful Soup, Przypuszczam, że będzie szybciej.

Więc moje pytanie: czy istnieje sposób na „wyczyszczenie tagów” ​​i zastąpienie ich „zwykłym tekstem” za pomocą Pięknej Zupy. Jeśli nie, jaki będzie najlepszy sposób, aby to zrobić?

Dziękujemy za sugestie!

Aktualizacja: Kod Alexa działał bardzo dobrze dla przykładowego przykładu. Próbowałem także różnych przypadków krawędzi i wszystkie działały dobrze (z modyfikacją poniżej). Więc dałem mu szansę na prawdziwą stronę internetową i wpadłem na problemy, które mnie łamały.

import urllib
from BeautifulSoup import BeautifulSoup

page = urllib.urlopen('http://www.engadget.com/2010/01/12/kingston-ssdnow-v-dips-to-30gb-size-lower-price/')

anchors = soup.findAll('a')
i = 0
for a in anchors:
    print str(i) + ":" + str(a)
    for a in anchors:
        if (a.string is None): a.string = ''
        if (a.previousSibling is None and a.nextSibling is None):
            a.previousSibling = a.string
        elif (a.previousSibling is None and a.nextSibling is not None):
            a.nextSibling.replaceWith(a.string + a.nextSibling)
        elif (a.previousSibling is not None and a.nextSibling is None):
            a.previousSibling.replaceWith(a.previousSibling + a.string)
        else:
            a.previousSibling.replaceWith(a.previousSibling + a.string + a.nextSibling)
            a.nextSibling.extract()
    i = i+1

Po uruchomieniu powyższego kodu pojawia się następujący błąd:

0:<a href="http://www.switched.com/category/ces-2010">Stay up to date with 
Switched's CES 2010 coverage</a>
Traceback (most recent call last):
  File "parselink.py", line 44, in <module>
  a.previousSibling.replaceWith(a.previousSibling + a.string + a.nextSibling)
 TypeError: unsupported operand type(s) for +: 'Tag' and 'NavigableString'

Kiedy patrzę na kod HTML, „Bądź na bieżąco ...” nie ma żadnego poprzedniego rodzeństwa (nie wiedziałem, jak poprzedni brat działał, dopóki nie zobaczyłem kodu Alexa i na podstawie moich testów wygląda na to, że szuka „tekstu” przed tagiem). Tak więc, jeśli nie ma poprzedniego rodzeństwa, jestem zaskoczony, że nie przechodzi on przez logikę if.previousSibling jest None i a; nextSibling jest None.

Czy mógłbyś mi powiedzieć, co robię źle?

-ekognium

questionAnswers(2)

yourAnswerToTheQuestion