Как очистить таблицу сайта, где значения ячеек имеют одинаковое имя класса? - PullRequest
2 голосов
/ 05 мая 2019

Я пытаюсь очистить таблицу (футбольная команда) от Transfermarkt.com для проекта, но некоторые столбцы имеют одинаковое имя класса и не могут быть дифференцированы.

Столбец [2,10] имеет уникальные классы и отлично работает.Я изо всех сил пытаюсь найти способ получить остальное.

from bs4 import BeautifulSoup
import pandas as pd

headers = {'User-Agent':
           'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

page = "https://www.transfermarkt.com/hertha-bsc-u17/kader/verein/21066/saison_id/2018/plus/1"
pageTree = requests.get(page, headers=headers)
pageSoup = BeautifulSoup(pageTree.content, 'html.parser')

Players = pageSoup.find_all("a", {"class": "spielprofil_tooltip"})
Values = pageSoup.find_all("td", {"class": "zentriert"})

PlayersList = []
ValuesList = []

for i in range(0, 25):
    PlayersList.append(Players[i].text)
    ValuesList.append(Values[i].text)

df = pd.DataFrame({"Players": PlayersList, "Values": ValuesList})

Я хотел бы очистить все столбцы в строках этой таблицы.

Ответы [ 2 ]

1 голос
/ 05 мая 2019

Использование селекторов bs4, pandas и css.Это отделяет позицию, например, вратарь от имени.Это не включает рыночную стоимость, так как никакие значения не даны.Для любого данного игрока - он показывает все значения для национальности игрока "/" отдельно;дает все значения для перевода из "/" в отдельности.столбцы с одним и тем же классом можно дифференцировать как nth-of-type.

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

headers = {'User-Agent' : 'Mozilla/5.0'}
df_headers = ['position_number' , 'position_description' , 'name' , 'dob' , 'nationality' , 'height' , 'foot' , 'joined' , 'signed_from' , 'contract_until']
r = requests.get('https://www.transfermarkt.com/hertha-bsc-u17/kader/verein/21066/saison_id/2018/plus/1', headers = headers)
soup = bs(r.content, 'lxml')

position_number = [item.text for item in soup.select('.items .rn_nummer')]
position_description = [item.text for item in soup.select('.items td:not([class])')]
name = [item.text for item in soup.select('.hide-for-small .spielprofil_tooltip')]
dob = [item.text for item in soup.select('.zentriert:nth-of-type(3):not([id])')]
nationality = ['/'.join([i['title'] for i in item.select('[title]')]) for item in soup.select('.zentriert:nth-of-type(4):not([id])')]
height = [item.text for item in soup.select('.zentriert:nth-of-type(5):not([id])')]
foot = [item.text for item in soup.select('.zentriert:nth-of-type(6):not([id])')]
joined = [item.text for item in soup.select('.zentriert:nth-of-type(7):not([id])')]
signed_from = ['/'.join([item['title'].lstrip(': '), item['alt']])  for item in soup.select('.zentriert:nth-of-type(8):not([id]) [title]')]
contract_until = [item.text for item in soup.select('.zentriert:nth-of-type(9):not([id])')]

df = pd.DataFrame(list(zip(position_number, position_description, name, dob, nationality, height, foot, joined, signed_from, contract_until)), columns = df_headers)
print(df.head())

Пример df.head

image

1 голос
/ 05 мая 2019

Я бы получил все <tr> и затем использовал бы цикл for, чтобы получить все <td> в строке.И затем я могу использовать индекс для получения столбца и использовать различные методы для получения значения из столбца.

import requests
from bs4 import BeautifulSoup
import pandas as pd

data = {
    'name': [],
    'data of birth': [],
    'height': [],
    'foot': [],
    'joined': [],
    'contract until': [],
}

headers = {
  'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'
}

url = "https://www.transfermarkt.com/hertha-bsc-u17/kader/verein/21066/saison_id/2018/plus/1"
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, 'html.parser')

all_tr = soup.find_all('tr', {'class': ['odd', 'even']})
print('rows:', len(all_tr))

for row in all_tr:
    all_td = row.find_all('td', recursive=False)

    print('columns:', len(all_td))
    for column in all_td:
        print(' >', column.text)

    data['name'].append( all_td[1].text.split('.')[0][:-1] )
    data['data of birth'].append( all_td[2].text[:-5])
    data['height'].append( all_td[4].text )
    data['foot'].append( all_td[5].text )
    data['joined'].append( all_td[6].text )
    data['contract until'].append( all_td[8].text )


df = pd.DataFrame(data)
print(df.head())

Результат:

               name data of birth  height   foot       joined contract until
0   Kilian Schubert   Sep 9, 2002  1,80 m  right  Jul 1, 2018              -
1   Raphael Bartell  Jan 26, 2002  1,82 m      -  Jul 1, 2018              -
2  Till Aufderheide  Jun 15, 2002  1,79 m      -  Jul 1, 2018              -
3  Milan Kremenovic   Mar 8, 2002  1,91 m      -  Jul 1, 2018     30.06.2020
4      Adnan Alagic   Jul 4, 2002  1,86 m  right  Jul 1, 2018     30.06.2021
...