get_race_victory_table
Retrieve the all-time victory table for a cycling race, displaying the most successful riders, their number of victories, and the years they won. Use the race ID to access historical achievements.
Instructions
Get the all-time victory table for a cycling race. This tool provides a historical summary of the most successful riders in a specific race, showing the number of victories for each rider throughout the race's history.
Note: If you don't know the race's ID, use the search_race tool first to find it by name.
Example usage:
- Get victory table for Tour de France (ID: 17)
- Get victory table for Paris-Roubaix (ID: 30)
Returns a formatted string with:
- Race name
- List of riders with the most victories
- Number of victories for each rider
- Years of victories where available
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| race_id | Yes |
Implementation Reference
- The primary handler method that retrieves the RaceVictoryTable endpoint for the race's all-time victory table.def victory_table(self): """ Get race all-time victory table. Returns ------- RaceVictoryTable """ return self._get_endpoint(endpoint=RaceVictoryTable, k='W')
- The endpoint handler class responsible for parsing the HTML response into a victory table DataFrame.class RaceVictoryTable(RaceEndpoint): """ Race victory table response. Extends RaceEndpoint. Attributes ---------- table : pd.DataFrame Victory table for race. """ def _parse_soup(self): super()._parse_soup() self._get_victory_table() def _get_victory_table(self): victory_table = self.soup.find('table', {'class': 'tablesorter'}) self.table = parse_table(victory_table)
- Helper method within RaceVictoryTable that locates the victory table in the HTML soup and parses it.def _get_victory_table(self): victory_table = self.soup.find('table', {'class': 'tablesorter'}) self.table = parse_table(victory_table)
- Core helper function that converts the raw HTML table element into a structured pandas DataFrame, extracting additional metadata from links and images.def parse_table(table): """ Convert HTML table from bs4 to pandas DataFrame. Return None if no data. """ # TODO for rider results, format dates nicely with hidden column we are throwing away import pandas as pd import io # Check early if table contains "No data" text if table and "No data" in table.get_text(): return None # Load pandas DataFrame from raw text only html = str(table) out_df = pd.read_html(io.StringIO(html), decimal=',')[0] if out_df.iat[0, 0] == 'No data': # No data return None # Convert decimal points to thousands separator # NOTE: Cannot use thousands='.' in pd.read_html because will ruin other columns (e.g. CAT for races) thousands_cols = ['Points'] for col in thousands_cols: if col in out_df: out_df[col] = out_df[col].astype(str).str.replace('.', '', regex=False).astype(int) # Parse soup to add information hidden in tags/links headers = [th.text for th in table.find_all('th')] trs = [tr for tr in table.find_all('tr') if tr.th is None] if 'Race.1' in out_df: out_df = out_df.rename(columns={'Race': 'Race_Country', 'Race.1': 'Race'}) headers.insert(headers.index('Race'), 'Race_Country') soup_df = pd.DataFrame([tr.find_all('td') for tr in trs], columns=headers) # Add information hidden in tags for col, series in soup_df.items(): if col in ('Rider', 'Winner', 'Second', 'Third'): out_df[col + '_ID'] = series.apply(lambda td: rider_link_to_id(td.a)) try: out_df[col + '_Country'] = series.apply(lambda td: img_to_country_code(td.img)) except TypeError: pass elif col == 'Team': out_df['Team_ID'] = series.apply(lambda td: team_link_to_id(td.a) if td.a else None) out_df['Team_Country'] = series.apply(lambda td: img_to_country_code(td.img) if td.img else None) elif col == 'Race': out_df['Race_ID'] = series.apply(lambda td: get_url_parameters(td.a['href'])['r'] if td.a else None) elif col == 'Race_Country': out_df['Race_Country'] = series.apply(lambda td: img_to_country_code(td.img) if td.img else None) elif col == '': try: out_df['Icon'] = series.apply(lambda td: get_img_name(td.img) if td.img else None) except AttributeError: pass out_df = out_df.replace({'-': None}).dropna(how='all', axis=1) # TODO Remove Unnamed columns return out_df