выберите два конкретных класса с помощью find_all в Beautifulsoup - PullRequest
0 голосов
/ 17 мая 2018

Я хочу использовать BeautifulSoup, чтобы очистить некоторые данные с сайта.Данные находятся в таблице, в которой разные строки таблицы представлены как 4 разных класса.

<table class="timeteam">
    <tbody>
        <tr class="even"></tr>
        <tr class="even smallrow"></tr>
        <tr class="odd"></tr>
        <tr class="odd smallrow"></tr>
    </tbody>
</table>

Данные в строках 'even' и 'odd' принадлежат друг другу.Поэтому я хочу получить эти две строки (и другие строки) в конце в кадре данных.

С помощью find_all ('tr', класс _ = ['even', 'odd']) я такжеполучить другие ряды (с маленькой стрелкой).Поэтому я попробовал функцию перекомпиляции.Но все тот же результат.

Что мне нужно изменить в моем коде, чтобы выбрать только строки с классами 'even' и 'odd'?

Вот мой код:

import requests
import re
import pandas as pd
from bs4 import BeautifulSoup as bs

page = request.get('https://regatta.time-team.nl/hollandia/2017/results/003.php')
soup = bs(page.content, 'html.parser')

tables = soup.find_all('table', class_='timeteam')

player_data_even = []
player_data_smallrow = []
for i in range(len(tables)):    
    for tr in tables[i].find_all('tr', class_ = re.compile(r"^(even|odd)$")):      
        player_row_even = []
        for td in tr.find_all('td'):    
            player_row_even.append(td.get_text())    
        player_data_even.append(player_row_even)
    for tr in tables[i].find_all('tr', class_=['even smallrow', 'odd smallrow']):
        player_row_smallrow = []
        for td in tr.find_all('td'):
            player_row_smallrow.append(td.get_text())
        player_data_smallrow.append(player_row_smallrow)

players_even = pd.DataFrame(player_data_even)
players_smallrow = pd.DataFrame(player_data_smallrow)

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Хорошо, похоже, ваша проблема решена. Вы можете иметь все данные последовательно сейчас. Дайте ему шанс:

from bs4 import BeautifulSoup
import requests

res = requests.get("https://regatta.time-team.nl/hollandia/2017/results/003.php")
soup = BeautifulSoup(res.text,"lxml")

for table in soup.find(class_="timeteam").find_all("tr",class_=['even','odd']):
    if "smallrow" not in table.get('class'):  #this is the fix
        data = [item.get_text(strip=True) for item in table]
        print(data)

Вывод вы можете получить как:

['1.', 'PHO', 'Phocas 1 (p2)', '', '--', '', '--', '', '--', '', '06:39,86', '(1)', 'KF']
['2.', 'PAM', 'Pampus (p4)', '', '--', '', '--', '', '--', '', '06:45,21', '(2)', 'KF']
['3.', 'SKO', 'Skøll 1', '', '--', '', '--', '', '--', '', '06:46,23', '(3)', 'KF']
['4.', 'NJO', 'Njord (p1)', '', '--', '', '--', '', '--', '', '06:49,44', '(4)', 'KF']
['5.', 'GYA', 'Gyas (SB)', '', '--', '', '--', '', '--', '', '06:50,04', '(5)', 'KF']
['6.', 'PRO', 'Proteus 1 (p7)', '', '--', '', '--', '', '--', '', '06:50,24', '(6)', 'KF']
0 голосов
/ 17 мая 2018

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

from bs4 import BeautifulSoup as soup
content = """
  <table class="timeteam">
   <tbody>
    <tr class="even">yes</tr>
    <tr class="even smallrow">no</tr>
    <tr class="odd">yes</tr>
    <tr class="odd smallrow">no</tr>
   </tbody>
</table>
"""
s = [i.text for i in soup(content, 'html.parser').find_all('tr') if len(i['class']) == 1]

Выход:

['yes', 'yes']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...