Skip to content
This repository has been archived by the owner on Jun 22, 2022. It is now read-only.

Commit

Permalink
Merge pull request #16 from JLpython-py/leaders/InternationalLeaderbo…
Browse files Browse the repository at this point in the history
…ards

Leaders/international leaderboards
  • Loading branch information
JacobLee23 authored Mar 25, 2021
2 parents 548b7f9 + fe9aa92 commit 190cf47
Show file tree
Hide file tree
Showing 4 changed files with 355 additions and 50 deletions.
186 changes: 183 additions & 3 deletions FanGraphs/leaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,10 +993,190 @@ def export(self, path=""):
os.rename(download_path, path)


class InternationalLeaderboards:
class InternationalLeaderboards(ScrapingUtilities):
"""
Parses the FanGraphs KBO Leaderboards page
.. py:attribute:: address
The base URL address for the FanGraphs KBO Leaderboards page.
:type: str
:value: https://www.fangraphs.com/leaders/international
"""
__selections = leaders_sel.intl.selections
__dropdowns = leaders_sel.intl.dropdowns
__checkboxes = leaders_sel.intl.checkboxes
__waitfor = leaders_sel.intl.waitfor

address = "https://www.fangraphs.com/leaders/international"

def __init__(self, browser="chromium"):
"""
:param browser: The name of the browser to use (Chromium, Firefox, WebKit)
"""
super().__init__(browser, self.address)
self.reset(waitfor=self.__waitfor)

@classmethod
def list_queries(cls):
"""
Lists the possible filter queries which can be used to modify search results.
:return: Filter queries which can be used to modify search results
:rtype: list
"""
queries = []
queries.extend(cls.__selections)
queries.extend(cls.__dropdowns)
queries.extend(cls.__checkboxes)
return queries

def list_options(self, query: str):
"""
Retrieves the option which a filter query is currently set to.
:param query: The filter query being retrieved of its current option
:return: The option which the filter query is currently set to
:rtype: str
:raises FanGraphs.exceptions.InvalidFilterQuery: Invalid argument ``query``
"""
query = query.lower()
if query in self.__selections:
elems = [
self.soup.select(s)[0]
for s in self.__selections[query]
]
options = [e.getText() for e in elems]
elif query in self.__dropdowns:
elems = self.soup.select(
f"{self.__dropdowns[query]} > div > a"
)
options = [e.getText() for e in elems]
elif query in self.__checkboxes:
options = ["True", "False"]
else:
raise FanGraphs.exceptions.InvalidFilterQuery(query)
return options

def current_option(self, query: str):
"""
:param query:
:return:
"""
query = query.lower()
option = ""
if query in self.__selections:
for sel in self.__selections[query]:
elem = self.soup.select(sel)[0]
if "active" in elem.get("class"):
option = elem.getText()
break
elif query in self.__dropdowns:
elem = self.soup.select(
f"{self.__dropdowns[query]} > div > span"
)[0]
option = elem.getText()
elif query in self.__checkboxes:
elem = self.soup.select(
self.__selections["stat"][0]
)
option = "True" if ",to" in elem[0].get("href") else "False"
else:
raise FanGraphs.exceptions.InvalidFilterQuery(query)
return option

def configure(self, query: str, option: str):
"""
Configures a filter query to a specified option.
def __init__(self):
pass
:param query: The filter query to be configured
:param option: The option to set the filter query to
:raises FanGraphs.exceptions.InvalidFilterQuery: Invalid argument ``query``
"""
query = query.lower()
self._close_ad()
if query in self.__selections:
self.__configure_selection(query, option)
elif query in self.__dropdowns:
self.__configure_dropdown(query, option)
elif query in self.__checkboxes:
self.__configure_checkbox(query, option)
else:
raise FanGraphs.exceptions.InvalidFilterQuery(query)
self._refresh_parser(waitfor=self.__waitfor)

def __configure_selection(self, query: str, option: str):
"""
Configures a selection-class filter query to an option.
:param query: The selection-class filter query to be configured
:param option: The option to set the filter query to
:raises FanGraphs.exceptions.InvalidFilterOption: Invalid argument ``option``
"""
options = self.list_options(query)
try:
index = options.index(option)
except ValueError as err:
raise FanGraphs.exceptions.InvalidFilterOption from err
self.page.click(
self.__selections[query][index]
)

def __configure_dropdown(self, query: str, option: str):
"""
Configures a dropdown-class filter query to an option.
:param query: The dropdown-class filter query to be configured
:param option: The option to set the filter query to
:raises FanGraphs.exceptions.InvalidFilterOption: Invalid argument ``option``
"""
options = self.list_options(query)
try:
index = options.index(option)
except ValueError as err:
raise FanGraphs.exceptions.InvalidFilterOption from err
self.page.click(self.__dropdowns[query])
elem = self.page.query_selector_all(
f"{self.__dropdowns[query]} > div > a"
)[index]
elem.click()

def __configure_checkbox(self, query: str, option: str):
"""
Configures a checkbox-class filter query to an option.
:param query: The checkbox-class filter query to be configured
:param option: The option to set the filter query to
:raises FanGraphs.exceptions.InvalidFilterOption: Invalid argument ``option``
"""
options = self.list_options(query)
if option not in options:
raise FanGraphs.exceptions.InvalidFilterOption
if option == self.current_option(query):
return
self.page.click(self.__checkboxes[query])

def export(self, path=""):
"""
Uses the **Export Data** button on the webpage to export the current leaderboard.
The data will be exported as a CSV file and the file will be saved to *out/*.
The file will be saved to the filepath ``path``, if specified.
Otherwise, the file will be saved to the filepath *./out/%d.%m.%y %H.%M.%S.csv*
:param path: The path to save the exported data to
"""
self._close_ad()
if not path or os.path.splitext(path)[1] != ".csv":
path = "out/{}.csv".format(
datetime.datetime.now().strftime("%d.%m.%y %H.%M.%S")
)
with self.page.expect_download() as down_info:
self.page.click(".data-export")
download = down_info.value
download_path = download.path()
os.rename(download_path, path)


class WARLeaderboards(ScrapingUtilities):
Expand Down
1 change: 1 addition & 0 deletions FanGraphs/selectors/leaders_sel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from . import season_stat_grid as ssg
from . import game_span_leaderboards as gsl
from . import war_leaderboards as war
from . import international_leaderboards as intl
26 changes: 26 additions & 0 deletions FanGraphs/selectors/leaders_sel/international_leaderboards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#! python3
# FanGraphs/selectors/leaders_sel/international_leaderboards.py

selections = {
"stat": [
".controls-stats > .fgButton:nth-child(1)",
".controls-stats > .fgButton:nth-child(2)"
],
"type": [
".controls-board-view > .fgButton:nth-child(1)",
".controls-board-view > .fgButton:nth-child(2)"
]
}
dropdowns = {
"position": ".controls-stats:nth-child(1) > div:nth-child(3) > .fg-selection-box__selection",
"min": ".controls-stats:nth-child(1) > div:nth-child(4) > .fg-selection-box__selection",
"single_season": ".controls-stats:nth-child(2) > div:nth-child(1) > .fg-selection-box__selection",
"season1": ".controls-stats:nth-child(2) > div:nth-child(2) > .fg-selection-box__selection",
"season2": ".controls-stats:nth-child(2) > div:nth-child(3) > .fg-selection-box__selection",
"league": ".controls-stats:nth-child(3) > div:nth-child(1) > .fg-selection-box__selection",
"team": ".controls-stats:nth-child(3) > div:nth-child(2) > .fg-selection-box__selection",
}
checkboxes = {
"split_seasons": ".controls-stats > .fg-checkbox"
}
waitfor = ".fg-data-grid.table-type"
Loading

0 comments on commit 190cf47

Please sign in to comment.