Convert svg from Highcharts data to data points

I'm going to clear the data from this mma data site and parsing several tall charts tables, I click the link with selenium and then switch to the graph. I go to this site and click on +420 on Artyom Lobov's row for the Pinnacle column. This creates a popup graph. Then I switch to the active item. I would like to capture a graph drawn in tall charts in response to a click.

I am using selenium like this:

actions = ActionChains(driver)
actions.move_to_element(driver.find_element_by_id(pin_id))
actions.click()
actions.perform()
time.sleep(3)
driver.switch_to_active_element()

      

I was able to click the link and get the chart, but I am a bit lost on how high-performance charts work.
I am trying to parse highcharts-series-group here and get the values ​​in the chart.

I believe the data can be found by:

soup = bs4.BeautifulSoup(open(driver.page_source), "lxml")
data = soup.find_all('g', {"class":"highcharts-series-group"})[-1].find_all("path")

      

However, this provides the following , and it is unclear how the chart is generated from the data. As noted in the comments, this is similar to svg.

During validation, the data looks like <g class="highcharts-series"

and <g class="highcharts-series-tracker

, but its fuzzy graphical charts depict it against this data.

How do graph charts display a graph from saved data? Is there a clean way to get data from the highcharts-series group as shown?

+3


source to share


2 answers


I couldn't figure out how to convert the SVG data to whatever is displayed on the graph you specified, but wrote the following Selenium Python script:

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get('https://www.bestfightodds.com/events/ufc-fight-night-108-swanson-vs-lobov-1258')
actions = webdriver.ActionChains(driver)
actions.move_to_element(driver.find_element_by_id('oID1013467091'))
actions.click()
actions.perform()
time.sleep(3)
driver.switch_to_active_element()
chart_number = driver.find_element_by_id('chart-area').get_attribute('data-highcharts-chart')
chart_data = driver.execute_script('return Highcharts.charts[' + chart_number + '].series[0].options.data')
for point in chart_data:
    e = driver.execute_script('return oneDecToML('+ str(point.get('y')) + ')')
    print(point.get('x'), e)

      



Here we are using the Highcharts API and some js from page sources that transform the server response for this chart to what we see on the chart.

+3


source


When I use a CSS selector "g.highcharts-axis-labels tspan"

it returns all fighter names, and when I use "g.highcharts-data-labels tspan"

it it returns all percentages for the line movement.

So, you should be able to use something like

labels = driver.find_elements_by_css_selector("g.highcharts-axis-labels tspan")
data = driver.find_elements_by_css_selector("g.highcharts-data-labels tspan")
for i in range(0, len(labels) - 1)
    print("Fighter: " + labels[i] + " (" + data[i] + ")")

      




An alternative is to use the command recommended by Pawel Fus,

Highcharts.charts[0].series[0].options.data

      

You should be able to accomplish this with JSE and it returns an array of arrays. Then you can analyze this and get the data you want. This is for you...

0


source







All Articles