There's a chess website I found (https://www.chess.com/play/computer), it's very confusing to work with on Selenium. The problem I'm encountering is that most squares are not actually treated as an element, it's only treated as an element if there's a piece on it or it's highlighted. This makes it very, very hard to work within Selenium as I cannot highlight a square without clicking it and to click it with Selenium I need the element.
Perhaps I could use a coordinates system as suggested here: Selenium click trouble (Python) but their code was not functional as the post was five years old.
The board itself is a view box and each square that is an element has "square-" followed by a two-digit number in its class where the first digit is the numbers on the board and the second digit is the letters on the board converted to a digit. In the image I provided the exact class it has is "highlight square-45"
You can use a Javascript snippet via driver.execute_script
to get the coordinates for each square on the board:
from selenium import webdriver
d = webdriver.Chrome('/path/to/chromedriver')
d.get('https://www.chess.com/play/computer')
board = d.execute_script('''
function coords(elem){
var n = elem.getBoundingClientRect()
return {top:n.top, left:n.left, width:n.width, height:n.height}
}
var pieces = []
for (var i = 1; i < 9; i++){
if (i > 6 || i < 3){
pieces.push(Array.from((new Array(8)).keys()).map(function(x){
var square = document.querySelector(`.piece.square-${x+1}${i}`)
return {...coords(square), piece:square.getAttribute('class').split(' ')[1]}
}));
}
else{
pieces.push(Array.from((new Array(8)).keys()).map(function(x){
var arr = pieces[pieces.length-1]
return {left:arr[x].left, top:arr[x].top - arr[x].height,
width:arr[x].width, height:arr[x].height, piece:null}
}));
}
}
return pieces
''')[::-1]
Output:
[[{'height': 62, 'left': 187, 'piece': 'br', 'top': 66, 'width': 62}, {'height': 62, 'left': 249, 'piece': 'bn', 'top': 66, 'width': 62}, {'height': 62, 'left': 311, 'piece': 'bb', 'top': 66, 'width': 62}, {'height': 62, 'left': 373, 'piece': 'bq', 'top': 66, 'width': 62}, {'height': 62, 'left': 435, 'piece': 'bk', 'top': 66, 'width': 62}, {'height': 62, 'left': 497, 'piece': 'bb', 'top': 66, 'width': 62}, {'height': 62, 'left': 559, 'piece': 'bn', 'top': 66, 'width': 62}, {'height': 62, 'left': 621, 'piece': 'br', 'top': 66, 'width': 62}], [{'height': 62, 'left': 187, 'piece': 'bp', 'top': 128, 'width': 62}, {'height': 62, 'left': 249, 'piece': 'bp', 'top': 128, 'width': 62}, {'height': 62, 'left': 311, 'piece': 'bp', 'top': 128, 'width': 62}, {'height': 62, 'left': 373, 'piece': 'bp', 'top': 128, 'width': 62}, {'height': 62, 'left': 435, 'piece': 'bp', 'top': 128, 'width': 62}, {'height': 62, 'left': 497, 'piece': 'bp', 'top': 128, 'width': 62}, {'height': 62, 'left': 559, 'piece': 'bp', 'top': 128, 'width': 62}, {'height': 62, 'left': 621, 'piece': 'bp', 'top': 128, 'width': 62}], [{'height': 62, 'left': 187, 'piece': None, 'top': 190, 'width': 62}, {'height': 62, 'left': 249, 'piece': None, 'top': 190, 'width': 62}, {'height': 62, 'left': 311, 'piece': None, 'top': 190, 'width': 62}, {'height': 62, 'left': 373, 'piece': None, 'top': 190, 'width': 62}, {'height': 62, 'left': 435, 'piece': None, 'top': 190, 'width': 62}, {'height': 62, 'left': 497, 'piece': None, 'top': 190, 'width': 62}, {'height': 62, 'left': 559, 'piece': None, 'top': 190, 'width': 62}, {'height': 62, 'left': 621, 'piece': None, 'top': 190, 'width': 62}], [{'height': 62, 'left': 187, 'piece': None, 'top': 252, 'width': 62}, {'height': 62, 'left': 249, 'piece': None, 'top': 252, 'width': 62}, {'height': 62, 'left': 311, 'piece': None, 'top': 252, 'width': 62}, {'height': 62, 'left': 373, 'piece': None, 'top': 252, 'width': 62}, {'height': 62, 'left': 435, 'piece': None, 'top': 252, 'width': 62}, {'height': 62, 'left': 497, 'piece': None, 'top': 252, 'width': 62}, {'height': 62, 'left': 559, 'piece': None, 'top': 252, 'width': 62}, {'height': 62, 'left': 621, 'piece': None, 'top': 252, 'width': 62}], [{'height': 62, 'left': 187, 'piece': None, 'top': 314, 'width': 62}, {'height': 62, 'left': 249, 'piece': None, 'top': 314, 'width': 62}, {'height': 62, 'left': 311, 'piece': None, 'top': 314, 'width': 62}, {'height': 62, 'left': 373, 'piece': None, 'top': 314, 'width': 62}, {'height': 62, 'left': 435, 'piece': None, 'top': 314, 'width': 62}, {'height': 62, 'left': 497, 'piece': None, 'top': 314, 'width': 62}, {'height': 62, 'left': 559, 'piece': None, 'top': 314, 'width': 62}, {'height': 62, 'left': 621, 'piece': None, 'top': 314, 'width': 62}], [{'height': 62, 'left': 187, 'piece': None, 'top': 376, 'width': 62}, {'height': 62, 'left': 249, 'piece': None, 'top': 376, 'width': 62}, {'height': 62, 'left': 311, 'piece': None, 'top': 376, 'width': 62}, {'height': 62, 'left': 373, 'piece': None, 'top': 376, 'width': 62}, {'height': 62, 'left': 435, 'piece': None, 'top': 376, 'width': 62}, {'height': 62, 'left': 497, 'piece': None, 'top': 376, 'width': 62}, {'height': 62, 'left': 559, 'piece': None, 'top': 376, 'width': 62}, {'height': 62, 'left': 621, 'piece': None, 'top': 376, 'width': 62}], [{'height': 62, 'left': 187, 'piece': 'wp', 'top': 438, 'width': 62}, {'height': 62, 'left': 249, 'piece': 'wp', 'top': 438, 'width': 62}, {'height': 62, 'left': 311, 'piece': 'wp', 'top': 438, 'width': 62}, {'height': 62, 'left': 373, 'piece': 'wp', 'top': 438, 'width': 62}, {'height': 62, 'left': 435, 'piece': 'wp', 'top': 438, 'width': 62}, {'height': 62, 'left': 497, 'piece': 'wp', 'top': 438, 'width': 62}, {'height': 62, 'left': 559, 'piece': 'wp', 'top': 438, 'width': 62}, {'height': 62, 'left': 621, 'piece': 'wp', 'top': 438, 'width': 62}], [{'height': 62, 'left': 187, 'piece': 'wr', 'top': 500, 'width': 62}, {'height': 62, 'left': 249, 'piece': 'wn', 'top': 500, 'width': 62}, {'height': 62, 'left': 311, 'piece': 'wb', 'top': 500, 'width': 62}, {'height': 62, 'left': 373, 'piece': 'wq', 'top': 500, 'width': 62}, {'height': 62, 'left': 435, 'piece': 'wk', 'top': 500, 'width': 62}, {'height': 62, 'left': 497, 'piece': 'wb', 'top': 500, 'width': 62}, {'height': 62, 'left': 559, 'piece': 'wn', 'top': 500, 'width': 62}, {'height': 62, 'left': 621, 'piece': 'wr', 'top': 500, 'width': 62}]]
Edit: clicking a square:
from selenium.webdriver.common.action_chains import ActionChains
def click_square(square):
elem = d.execute_script('''return document.querySelector('body')''')
ac = ActionChains(d)
ac.move_to_element(elem).move_by_offset(square['left']+int(square['width']/2), square['top']+int(square['width']/2)).click().perform()
click_square(board[0][0])