Just in addition to @αԋɱҽԃ αмєяιcαη precise answer for list
– Instead of working with lists, that often causes mismatches of length, if elements are not available as expected, I would always recommend to use more structured constructs like dictionaries
and extract all related data in one go:
{
e.get_text(strip=True):e.find_next_sibling(text=True)
for e in soup.select('p strong')
}
Example
from bs4 import BeautifulSoup
html = '''
<p><strong>W Ognisku</strong><br>W londyńskim Ognisku Polskim odbyło się spotkanie z brytyjskim historykiem<br><br><strong>10 lat polskiej szkoły sobotniej Copernicus </strong><br>W Wielkiej Brytanii <br><br><strong>IV Bieg Pamięci Dywizjonu 303 w Londynie</strong><br>Już po raz czwarty w dzielnicy<br><br><strong>81 Liebermana</strong><br>21 majowym przeciwstawił się rządom Piłsudskiego. <br><strong><br>Londynem</strong><br>Był setki pełnymi garściami.</p>
'''
soup = BeautifulSoup(html)
{
e.get_text(strip=True):e.find_next_sibling(text=True)
for e in soup.select('p strong')
}
Output
{'W Ognisku': 'W londyńskim Ognisku Polskim odbyło się spotkanie z brytyjskim historykiem',
'10 lat polskiej szkoły sobotniej Copernicus': 'W Wielkiej Brytanii ',
'IV Bieg Pamięci Dywizjonu 303 w Londynie': 'Już po raz czwarty w dzielnicy',
'81 Liebermana': '21 majowym przeciwstawił się rządom Piłsudskiego. ',
'Londynem': 'Był setki pełnymi garściami.'}
EDIT
To get lists
/ tuples
from dict
:
headings, texts = zip(*{
e.get_text(strip=True):e.find_next_sibling(text=True)
for e in soup.select('p strong')
}.items())
To get lists
only:
headings = [e.get_text(strip=True) for e in soup.select('p strong')]
texts = [e.find_next_sibling(text=True) for e in soup.select('p strong')]
from bs4 import BeautifulSoup
html = """<html>
<body>
<p>
<strong>
W Ognisku
</strong>
<br/>
W londyńskim Ognisku Polskim odbyło się spotkanie z brytyjskim historykiem
<br/>
<br/>
<strong>
10 lat polskiej szkoły sobotniej Copernicus
</strong>
<br/>
W Wielkiej Brytanii
<br/>
<br/>
<strong>
IV Bieg Pamięci Dywizjonu 303 w Londynie
</strong>
<br/>
Już po raz czwarty w dzielnicy
<br/>
<br/>
<strong>
81 Liebermana
</strong>
<br/>
21 majowym przeciwstawił się rządom Piłsudskiego.
<br/>
<strong>
<br/>
Londynem
</strong>
<br/>
Był setki pełnymi garściami.
</p>
</body>
</html>"""
soup = BeautifulSoup(html, 'lxml')
goal = [x.next_element.strip() for x in soup.select('p strong + br')]
print(goal)
Output:
['W londyńskim Ognisku Polskim odbyło się spotkanie z brytyjskim historykiem', 'W Wielkiej
Brytanii', 'Już po raz czwarty w dzielnicy', '21 majowym przeciwstawił się rządom Piłsudskiego.', 'Był setki pełnymi garściami.']
I am trying to store headings and paragraphs into different arrays, i can’t manage with text between <br>
.
Here’s my HTML code and python
below:
<p><strong>W Ognisku</strong><br>W londyńskim Ognisku Polskim odbyło się spotkanie z brytyjskim historykiem<br><br><strong>10 lat polskiej szkoły sobotniej Copernicus </strong><br>W Wielkiej Brytanii <br><br><strong>IV Bieg Pamięci Dywizjonu 303 w Londynie</strong><br>Już po raz czwarty w dzielnicy<br><br><strong>81 Liebermana</strong><br>21 majowym przeciwstawił się rządom Piłsudskiego. <br><strong><br>Londynem</strong><br>Był setki pełnymi garściami.</p>
and soup:
from bs4 import BeautifulSoup
with open('/Users/milek/Desktop/index.html', 'r') as f:
contents = f.read()
soup = BeautifulSoup(contents, 'lxml')
headings = []
txt = []
for strong_tag in soup.find_all('strong'):
headings.append(strong_tag.text)
print(headings)
I retrieved headings with full success but I have pretty hard time storing the rest – paragraphs.
@HedgeHog
Here’s the code in selenium which relies on this stored data which im trying to achieve. Headings are
#++++++++++++++++++++++ ADD VIDEO ++++++++++++++++++++++
def addVideo(titles):
add_button = browser.find_element(By.CLASS_NAME, 'object-adder')
add_button.click()
chooseVIDEO = browser.find_element(By.CSS_SELECTOR, "a[value*='2']")
chooseVIDEO.click()
sleep(3)
# -------------- ADD HEADING --------------
title = browser.find_element(By.NAME, 'title')
title.send_keys(THIS IS THE PLACE FOR EACH HEADING)
sleep(4)
# -------------- NO RESTRICTIONS ------------
zone_restriction = browser.find_element(By.NAME, 'zoneRestriction')
zone_restriction.click()
sleep(4)
typewrite('b')
typewrite('e')
press('enter')
sleep(2)
# -------------- NO ADDS ---------------
noAdv = browser.find_element(By.NAME, 'adsEnabled')
noAdv.click()
# ------------- SAVE -----------
sleep(3)
saveGoObj = browser.find_element(By.ID, 'saveButton')
saveGoObj.click()
#++++++++++++++++++++++ ADD PARAGRAPH +++++++++++++++++++++++
def addTXT(paras):
add_button = browser.find_element(By.CLASS_NAME, 'object-adder')
add_button.click()
chooseParagraph = browser.find_element(By.CSS_SELECTOR, "a[value*='33']")
chooseParagraph.click()
sleep(3)
# -------------- ADD TITLE --------------
title = browser.find_element(By.NAME, 'title')
title.send_keys('txt')
# -------------- ADD PARAGRAPH -------------
textPara = browser.find_element(By.XPATH, "//textarea[@name='text']")
textPara.send_keys(THIS IS THE PLACE FOR EACH PARAGRAPH)
sleep(6)
# ------------- SAVE -----------
saveGoObj = browser.find_element(By.ID, 'saveButton')
saveGoObj.click()
sleep(6)
Your edit is a bit confusing and question looses focus in my opinion – It would be predestined for
I don’t know if its the way to go.. but at the beginning my script had a loop and i was stroring all of this data in array(list? sorry im js guy, thats my first day in python) and simply it adds each heading and paragraph in ascending order from 0 to …. depends on headings or paragraph array length
above i edited my whole post, i pasted two of my functions in selenium.. i call them as many times as I have headers in the list
could i ask you to convert this dictionary into two lists? headings and txt? i need exactly what you did but in the different form, two lists instead of this dictionary