BeautifulSoup .text method returns text without separators (\n, \r etc)
Asked Answered
I

3

21

I've tryed to parse song lyrics from biggest russian lyrics site http://amalgama-lab.com and save lyrics (translated and original) into audio list from my Vkontakte account(sadly, amalgama doesn't have any API)

import urllib
from BeautifulSoup import BeautifulSoup
import vkontakte
vk = vkontakte.API(token=<SECRET_TOKEN>)
audios = vk.getAudios(count='2')
#{u'artist': u'The Beatles', u'url': u'http://cs4519.vkontakte.ru/u4665445/audio/4241af71a888.mp3', u'title': u'Yesterday', u'lyrics_id': u'2365986', u'duration': 130, u'aid': 166194990, u'owner_id': 173505924}
url = 'http://amalgama.mobi/songs/'
for i in audios:
    print i['artist']
    if i['artist'].startswith('The '):
        url += i['artist'][4:5] + '/' + i['artist'][4:].replace(' ', '_') + '/'     +i['title'].replace(' ', '_') + '.html'
    else:
        url += i['artist'][:1] + '/' + i['artist'].replace(' ', '_') + '/' +i['title'].replace(' ', '_') + '.html'
    url = url.lower()
    page = urllib.urlopen(url)
    soup = BeautifulSoup(page.read(), fromEncoding="utf-8")
    texts = soup.findAll('ol', )
    if len(texts) != 0:
        en = texts[0].text #this!
        ru = texts[1].text #this!
        vk.get('audio.edit', aid=i['aid'], oid = i['owner_id'], artist=i['artist'], title = i['title'], text = ru, no_search = 0)

but .text method returns string without any separators:

"Yesterday, all my troubles seemed so far awayNow it look as though they're here to stayOh, I believe in yesterdaySuddenly, I'm not half the man I used to beThere's a shadow hanging over meOh, yesterday came suddenly[Chorus:]Why she had to go I don't know, she wouldn't sayI said something wrong, now I long for yesterdayYesterday, love was such an easy game to playNow I need a place to hide awayOh, I believe in"

It's main problem. Next, what better way to save lyrics such this way:

Lyrics line 1 (Original)

Lyrics line 1 (Translated)

Lyrics line 2 (Original)

Lyrics line 2 (Translated)

Lyrics line 3 (Original)

Lyrics line 3 (Translated)

...

? I get only messy code. Thanks

Ilyssa answered 25/8, 2012 at 17:31 Comment(4)
Please provide a link to the actual page you are parsing.Anglocatholic
Example: amalgama.mobi/songs/b/beatles/yesterday.htmlWamble
Note that there are no newlines in the songtext, only <br/> tags, which the OP is stripping out..Wamble
I know:) What better way to convert html > text? OFC, I can replace <br/> with '\n', and remove all other tags by myself, but it would look ..dirtlyIlyssa
M
33

Try the separator parameter of the get_text method:

from bs4 import BeautifulSoup
html = '''<p> Hi. This is a simple example.<br>Yet poweful one. <p>'''
soup = Beautifulsoup(html)
soup.get_text()  
# Output: u' Hi. This is a simple example.Yet poweful one. '
soup.get_text(separator=' ')  
# Output: u' Hi. This is a simple example. Yet poweful one. '
Megargee answered 2/11, 2016 at 15:14 Comment(1)
Thanks, it does the trick. I use it to get the text of a webpage, then I use re.sub(r"(\n( ?))+", "\n", my_text) to remove multiple carriage returns, and re.sub(r" +", " ", my_text) to remove multiple spaces.Agosto
U
7

I suggest you look into the .strings generator found in BeautifulSoup 4.

Unlade answered 26/8, 2012 at 3:18 Comment(1)
In addition, you may pay attention to stripped_strings. If you want to iterate the generator, you could try this for string in soup.stripped_strings: for instance.Ehtelehud
B
0

You can do this:

soup = BeautifulSoup(html)
ols = soup.findAll('ol') # for the two languages

for ol in ols: 
    ps = ol.findAll('p')
    for p in ps:
        for item in p.contents:
            if str(item)!='<br />':
                print str(item)
Bunting answered 25/8, 2012 at 18:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.