Как извлечь текст из нескольких текстовых узлов в элементе, используя Selenium и BeautifulSoup - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть элемент, найденный через BeautifulSoup, который (HTML) выглядит так:

  <div class="ListingData">
    <span id="l_Contract" class="contract">Vendita Residenziale</span><br />
    New York<br />
    Appartamento<br />
    <strong>Prezzo:</strong>
    &euro; 100.000/200.000
    - <strong>Metri quadri:</strong>
    130/170
    </div>

И мне нужно попасть в одну переменную Vendita Residenziale , в другую Нью-Йорк , в другую Appartamento , в другую 100.000 / 200.000 (не сильный тег) и в последнем 130/170 .

Я могу извлечь текст тега span, выполнив:

x = ele.find('span', attrs = {'class': 'contract'}).get_text()

но я изо всех сил пытаюсь получить другую информацию, я пытался:

y = ele.find('div', attrs = {'class':'ListingData'}).get_text().replace("\n","").strip()

но это дает мне все содержимое div, и это нормально, но мне нужно получить отдельные строки информации, такие как "result [1]" для Нью-Йорка, "result [2]" для Appartamento и так далее. Есть ли способ?

Ответы [ 5 ]

0 голосов
/ 13 апреля 2019

Selenium самостоятельно может извлечь все необходимые тексты, и вы можете использовать следующее решение:

element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "div[@class='ListingData']")))
text_Vendita_Residenziale = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "div[@class='ListingData']/span[@class='contract' and contains(@id='Contract')]")))
text_NewYork = driver.execute_script('return arguments[0].childNodes[3].textContent;', element).strip()
text_Appartamento = driver.execute_script('return arguments[0].childNodes[5].textContent;', element).strip()
text_100_200 = driver.execute_script('return arguments[0].childNodes[8].textContent;', element).strip()
text_130_170 = driver.execute_script('return arguments[0].lastChild.textContent;', element).strip()
0 голосов
/ 13 апреля 2019

здесь на самом деле не проблема bs4, другие нужные вам данные не находятся внутри тегов span, извлеките ваши данные на основе строковых наблюдений

sp=sp.find('div',id='onesiwant')
for div in sp:
    all=div.text.strip()
    #now you can split('\n') 
     html=str(div)
     get the stuff out of span
        now split by '<br>' tags

ваш вопрос о том, как использовать bs4 для получения данных изтекст между тегами или разделенный \ n, поэтому bs4 здесь не нужен, просто манипулирование строками

0 голосов
/ 13 апреля 2019

Поскольку весь текст, который вы хотите, находится в теге <div>, кажется, самый простой способ - получить текст <div> и разбить текст на новых строках '\n' на список result:

result = [e.strip() for e in ele.div.text.strip().split('\n')]

>>> result
[u'Vendita Residenziale', u'New York', u'Appartamento', u'Prezzo:', u'\u20ac 100.000/200.000', u'- Metri quadri:', u'130/170']

, который затем можно индексировать по желанию:

for n, res in enumerate(result):
    print(f'result[{n}] = {res}')

result[0] = Vendita Residenziale
result[1] = New York
result[2] = Appartamento
result[3] = Prezzo:
result[4] = € 100.000/200.000
result[5] = - Metri quadri:
result[6] = 130/170
0 голосов
/ 13 апреля 2019

Вы можете использовать навигационную строку и .contents

from bs4 import BeautifulSoup, NavigableString

html = '''
<div class="ListingData">
    <span id="l_Contract" class="contract">Vendita Residenziale</span><br />
    New York<br />
    Appartamento<br />
    <strong>Prezzo:</strong>
    &euro; 100.000/200.000
    - <strong>Metri quadri:</strong>
    130/170
    </div>
'''

soup = bs(html, 'lxml')
item1 = soup.select_one('#l_Contract').text
items = soup.select_one('.ListingData').contents
results = []
for item in items:
    if isinstance(item, NavigableString) and item.strip():
        results.append(item.strip())

item2 = results[0]
item3 = results[1]
item4 = results[2]

print(item1, ',', item2, ',', item3, ',', item4)
0 голосов
/ 13 апреля 2019

Я использовал смесь BeautifulSoup4 и Regular Expression, вы можете играть с regex .

a=bs4.BeautifulSoup(txt,'html.parser')
a.findAll(id="l_Contract")[0].text # Vendita Residenziale
p=re.compile("<br />").split(txt)
p[1] # "New York"
p[2] # "Appartamento"
re.compile("&euro;\s+([0-9.]+\/[0-9.]+)\s+-\s+<strong>").search(txt).group(1) #100.000/200.000

Другим способом было бы просто сделать это

a.findAll(class_="ListingData")[0].text
#Output
'\nVendita Residenziale\n    New York\n    Appartamento\nPrezzo:\n    € 100.000/200.000\n    - Metri quadri:\n    130/170\n    '

Что легче разобрать.

...