Получение данных из тегов td с помощью Python и BeautifulSoup

Я новичок в Python и работаю над некоторыми задачами с данными, с которыми я знаком, чтобы изучить основы. Я пытаюсь просмотреть таблицу, чтобы собрать контактную информацию, но у меня возникают проблемы с получением данных в списке tds.

HTML-код выглядит следующим образом:

<table class = "table table-striped" data-drupal-selector = "edit-directory" id = "edit-directory--zJwP9mT4moQ">
   <thead>
   <tr>
       <th>Name</th>
       <th>Job Title</th>
       <th>Campus/Department</th>
       <th>Contact</th>
   </tr>
   </thead>
   <tbody>
   <tr class = "odd">
       <td>LAST, FIRST</td>
       <td>T-HS SCI- GEN'L</td>
       <td><span tabindex = "0">SCHOOL</span></td>
       <td><a href = "mailto:[email protected]" class = "email"><span aria-hidden = "true">Email</span><span class = "sr-only">[email protected]</span></a><br>555-555-5555</td>
   </tr>
</table>

У меня есть этот код, чтобы получить таблицу

data = urllib.parse.urlencode(params).encode("utf-8")
    req = urllib.request.Request(url)
    with urllib.request.urlopen(req,data=data) as f:
        soup = bs(f, 'html.parser')

table = soup.find("table")

for row in table.findAll("tr"):
        #print (row)
        cells = row.findAll("td")
        print(cells) 

Я получаю что-то вроде этого:

[<td>LAST,FIRST </td>, <td>TEMP PROF</td>, <td><span tabindex = "0">SCHOOL</span></td>, <td><a class = "email" href = "mailto:[email protected]"><span aria-hidden = "true">Email</span><span class = "sr-only">[email protected]</span></a><br/>555-555-5555</td>]

[<td><a href = "https://teachersite.com" target = "_blank">LAST, FIRST</a></td>, <td>T-ENGLISH</td>, <td><span tabindex = "0">SCHOOL</span></td>, <td><a class = "email" href = "mailto:[email protected]"><span aria-hidden = "true">Email</span><span class = "sr-only">[email protected]/span></a><br/>555-555-5555</td>]

Но если я попытаюсь получить данные в списке:

print (cells[1]) 

Пишет, что индекс вне допустимого диапазона

То, что я пытаюсь получить, выглядит примерно так:

last = 'LAST'
first = 'FIRST'
email = '[email protected]'
title = 'TEMP PROF'
phone = '555-555-5555'

Было бы полезно, если бы вы могли предоставить способ воспроизвести это.

juanpa.arrivillaga 09.07.2019 01:10

Есть ли заголовки столбцов для таблицы html? Если это так, вы можете использовать их для присвоения значений.

jottbe 09.07.2019 01:49

Добавил больше информации - надеюсь, это то, что вам нужно.

Nicole C. Baratta 09.07.2019 02:01
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
3
125
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Похоже, вы хотите удалить текст из каждого элемента:

for row in table.findAll('tr'):
    cols = row.findAll('td')
    cols = [element.text.strip() for element in cols]
    for col in cols:
        print(col)

Чтобы найти имя и фамилию, вы можете разделить первый элемент запятой и пробелом с помощью: .split(', '). Надеюсь, это укажет вам правильное направление!

Я думаю, что это вернет объединенные строки. Например. как '[email protected]', но вы можете избежать этого, используя что-то вроде ' '.join(td.strings) в своем понимании списка вместо текста. Не уверен, что у BeautifulSoup есть более удобный способ сделать это.

jottbe 09.07.2019 01:48

Вы можете перебрать tds для каждого tr и получить необходимые данные:

from bs4 import BeautifulSoup as soup
def scrape_td(d):
  n, t, _, c = d.find_all('td')
  return {**dict(zip(['last', 'first'], n.text.split(', '))), 'title':t.text, 'email':c.contents[0]['href'][7:], 'phone':c.contents[-1]}

results = list(map(scrape_td, soup(html, 'html.parser').find('table', {'id':'edit-directory--zJwP9mT4moQ'}).find_all('tr')[1:]))

Выход:

[{'last': 'LAST', 'first': 'FIRST', 'title': "T-HS SCI- GEN'L", 'email': '[email protected]', 'phone': '555-555-5555'}]

Другие вопросы по теме