Получение первого (или определенного) td в BeautifulSoup без класса

#python #beautifulsoup

#python #beautifulsoup

Вопрос:

У меня есть одна из тех кошмарных таблиц, в которой для тегов tr и td не указан класс.

Пример страницы здесь: https://system.gotsport.com/org_event/events/1271/schedules?age=19amp;gender=m

(В приведенном ниже коде вы увидите, что я получаю несколько страниц, но это не проблема.)

Мне нужно имя команды (ничего больше) из каждой скобки. Вывод должен быть:

OCYS
FL Rush
Джексонвилл ФК
Атланта Юнайтед
SSA
Майами Раш Кендалл
Шотландия IMG
Тампа-Бэй Юнайтед
и т.д.

Я смог получить каждый td в указанных таблицах. Но каждая попытка использовать [0] для получения первого td из каждой строки выдает ошибку «индекс вне диапазона».

Код:

 import requests
import csv 
from bs4 import BeautifulSoup

batch_size = 2
urls = ['https://system.gotsport.com/org_event/events/1271/schedules?age=19amp;gender=m', 'https://system.gotsport.com/org_event/events/1271/schedules?age=17amp;gender=m']

# iterate through urls
for url in urls:
    response = requests.get(url)
    soup = BeautifulSoup(response.content, "html.parser")



# iterate through leagues and teams
    leagues = soup.find_all('table', class_='table table-bordered table-hover table-condensed')
    for league in leagues:
        row = ''
        rows = league.find_all('tr')
        for row in rows:
            team = row.find_all('td')
            teamName = team[0].text.strip()    
            print(teamName)
  

После пары часов работы я чувствую, что я всего в одном изменении синтаксиса от правильного понимания. Да?

Ответ №1:

Вы можете использовать селектор CSS nth-of-type(n) . Это работает для обеих ссылок:

 import requests
from bs4 import BeautifulSoup

url = "https://system.gotsport.com/org_event/events/1271/schedules?age=19amp;gender=m"
soup = BeautifulSoup(requests.get(url).content, "html.parser")

for tag in soup.select(".small-margin-bottom td:nth-of-type(1)"):
    print(tag.text.strip())
  

Вывод:

 OCYS
FL Rush
Jacksonville FC
Atlanta United
SSA
...
...
Real Salt Lake U19
Real Colorado
Empire United Soccer Academy
  

Комментарии:

1. ПРЕКРАСНО! Большое вам спасибо.

Ответ №2:

Каждая скобка соответствует одной «панели», и каждая панель имеет две строки, первая из которых содержит первую таблицу всех команд в таблицах совпадений.

 def main():

    import requests
    from bs4 import BeautifulSoup

    url = "https://system.gotsport.com/org_event/events/1271/schedules?age=19amp;gender=m"

    response = requests.get(url)
    response.raise_for_status()
    
    soup = BeautifulSoup(response.content, "html.parser")

    for panel in soup.find_all("div", {"class": "panel-body"}):
        for row in panel.find("tbody").find_all("tr"):
            print(row.find("td").text.strip())
    
    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())
  

Вывод:

 OCYS
FL Rush
Jacksonville FC
Atlanta United
SSA
Miami Rush Kendall SC
IMG
Tampa Bay United
Weston FC
Chargers SC
South Florida FA
Solar SC
RISE SC
...
  

Комментарии:

1. Спасибо — это сработало. В какой-то момент я немного изучу и выясню, как это работает. Я все еще новичок.

Ответ №3:

Я думаю, что проблема связана с заголовком таблицы, который содержит th элементы вместо td элементов. Это приводит к ошибке индекса диапазона, когда вы пытаетесь извлечь первый элемент из пустого списка. Попробуйте добавить проверку длины td :

 for row in rows:
    team = row.find_all('td')
    if(len(team) > 0):
        teamName = team[0].text.strip()    
        print(teamName)
  

Он должен напечатать вам имена команд.