1

I have this code:

from selenium import webdriver

# Set url and path
url = 'https://osu.ppy.sh/beatmapsets?m=0'
driver = webdriver.Chrome(executable_path=r"C:\Users\Gabri\anaconda3\chromedriver.exe")
driver.get(url)

# Select the item that i want
try:
    dif = driver.find_element_by_css_selector('div.beatmapset-panel__beatmap-dot')
    dif.text
    print(dif)
except:
    print('not found')

I'm trying to select this map difficulty 'expert in purple ' --> https://i.stack.imgur.com/O7PVG.jpg but i can't continue with my code cuz the output is "<selenium.webdriver.remote.webelement.WebElement (session="3cdaf38d0673d0aebe49733d629eae5c", element="60d6241b-80f7-42c8-bf38-9fd2c8574b08")>" and i expected that would be a string like "expert" or "--bg:var(--diff-expert);" How i can translate or convert ? I did try to select with '[class*="beatmapset-panel__beatmap-dot"' and the output is same. Someone can help me?

vitaliis
  • 4,082
  • 5
  • 18
  • 40

2 Answers2

1

You need to change your code as following to print the element text:

from selenium import webdriver

# Set url and path
url = 'https://osu.ppy.sh/beatmapsets?m=0'
driver = webdriver.Chrome(executable_path=r"C:\Users\Gabri\anaconda3\chromedriver.exe")
driver.get(url)

# Select the item that i want
try:
    dif = driver.find_element_by_css_selector('div.beatmapset-panel__beatmap-dot')    
    print(dif.text)
except:
    print('not found')
Prophet
  • 32,350
  • 22
  • 54
  • 79
  • Sure, you have to add some wait or delay to make the page load and only after that apply `dif = driver.find_element_by_css_selector('div.beatmapset-panel__beatmap-dot')` otherwise the element is still not exists or just appeared but still not fully rendered! – Prophet May 19 '21 at 18:02
  • 1
    @JD2775 You are right! maybe he is looking for some other element? I see 67 elements located by `div.beatmapset-panel__beatmap-dot` there – Prophet May 19 '21 at 18:18
  • Almost worked, but i still have an unreadable output https://imgur.com/a/h2m8w7F ,any other idea? haha –  May 19 '21 at 18:20
  • @Prophet sorry, I deleted my reply not realizing you would respond :) I added a new answer – JD2775 May 19 '21 at 18:22
  • @JD2775 It's OK. I'm just not sure about what he actually trying to get. In case he is looking for a title as you suggest.. Well, maybe it's you the prophet, not me :) – Prophet May 19 '21 at 18:25
  • 1
    @Prophet I just re-read the OP. He is looking for the purple bar. It looks like a hover action and then switch to it and get the text somehow. Its more complex then I thought intially. Deleted my answer – JD2775 May 19 '21 at 18:28
  • @JD2775 i saw your answer and it help me cuz your resolution is same thing that i will do later, i will make a code to search all maps with difficulty 'expert',filter and put in a list for me. I'm so thankful to you for this <33 –  May 19 '21 at 18:50
  • This does not answer the question. The answer is much more complicated. – vitaliis May 19 '21 at 20:18
  • @vitaliis maybe you are right, I do not argue. I answered according to what I could understand from the question and the web page – Prophet May 19 '21 at 20:36
0

You need to hover to an element, then wait for data to appear and get its text:

Here is the snippet for the first game from the list. To get all games you will need another loop.

I am using ActionChains to hover on element. Finding locators for this site was not easy even for me.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains


driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
driver.get("https://osu.ppy.sh/beatmapsets?m=0")
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".beatmapsets__items-row:nth-of-type(1)>.beatmapsets__item:nth-of-type(1)")))
games = driver.find_element_by_css_selector(".beatmapsets__items-row:nth-of-type(1) .beatmapsets__item:nth-of-type(1) .beatmapset-panel__info-row--extra")
actions = ActionChains(driver)
actions.move_to_element(games).perform()
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".beatmaps-popup__group")))
levels = driver.find_elements_by_css_selector(".beatmaps-popup__group .beatmaps-popup-item__col.beatmaps-popup-item__col--name.u-ellipsis-overflow")
for level in levels:
    print(level.text)

Output:

Hinsvar's Hard
Zelqurre's Insane
Amamir's Shining Stars

For iteration through a list of levels use this css selector:

.beatmapsets__items-row:nth-of-type(1) .beatmapsets__item:nth-of-type(1) .beatmapset-panel__info-row--extra

And iterate this locator:

.beatmapsets__items-row:nth-of-type(1) .beatmapsets__item:nth-of-type(1) .beatmapset-panel__info-row--extra,

.beatmapsets__items-row:nth-of-type(2) .beatmapsets__item:nth-of-type(1) .beatmapset-panel__info-row--extra

Update: To get scores use:

scores= driver.find_elements_by_css_selector(".beatmaps-popup__group .beatmaps-popup-item__col.beatmaps-popup-item__col--difficulty")
for score in scores:
    print(score.text)

The output will be:

2.58
3.46
4.55
4.90
5.97

Also, check this answer on how to put results in one list: Trouble retrieving elements and looping pages using next page button

And finally read here about css selectors: https://www.w3schools.com/cssref/css_selectors.asp

I usually prefer using them because they are shorter.

vitaliis
  • 4,082
  • 5
  • 18
  • 40
  • I'm so thankful bro, it worked! I also did a loop to show one by one maps, but i have only one more problem =( i can't show the number's beside, cuz only description that your code print is insufficient to filter all maps correctly , i need show these numbers --> https://imgur.com/a/FOJs74a you can help me one more time plz ? =,) –  May 20 '21 at 18:13
  • By the way, you have no idea how much your answer helped me, i learnd sooo much with your code ^-^ –  May 20 '21 at 18:16