Я программирую бота, который автоматически извлекает обувь из 'https://www.nike.com.br'. У меня есть URL страницы оформления заказа, и процесс оформления заказа выглядит следующим образом:
- Решить CAPTCHA
- Выбрать размер обуви
- Перейти к способу оплаты
- Оформить заказ
Я позаботился о CAPTCHA, используя Chrome Профиль по умолчанию в Chrome Driver. После того, как CAPTCHA решена, размеры обуви отображаются на странице динамически. Источник веб-страницы содержит JSON объектов, в которых хранится вся информация о доступных размерах обуви, поэтому я анализирую ее из источника документа и использую ее для случайного выбора одного из доступных размеров обуви.
Вот код
'''==================================== SECTION - I ===================================='''
default_profile = r'--user-data-dir=C:\Users\{}\AppData\Local\Google\Chrome\User Data'.format(getpass.getuser())
options = webdriver.ChromeOptions()
options.add_argument(default_profile) # Adding Default Chrome Profile
#options.add_argument("--disable-extensions")
#options.add_argument("--disable-gpu")
#options.add_argument("--headless")
driver = webdriver.Chrome(executable_path='WebDrivers/chromedriver.exe', options=options)
driver.get('https://www.nike.com.br/Snkrs/Produto/MX-720-818/153-169-211-209098')
html_source = driver.page_source
'''==================================== SECTION - II ===================================='''
# Getting past CAPTCHA
WebDriverWait(driver, 10).until(
EC.frame_to_be_available_and_switch_to_it(
( By.CSS_SELECTOR,
r"iframe[name^='a-'][src^='https://www.google.com/recaptcha/api2/anchor?']"
)
))
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
( By.XPATH,
r'/html/body/div[2]/div[3]/div[1]/div/div/span'
)
)).click()
'''==================================== SECTION - III ===================================='''
# PARSING JSON Object FROM DOCUMENT BODY ( PRETTY UGLY HACKS DOWN HERE [ WORKING FINE THOUGH! ] )
script_index = html_source.index('<main role="main" class="container-fluid" id="produto">')
JSON_start_index = html_source[script_index::].index('{') + script_index, html_source[script_index::].index('{')
JSON_end_index = html_source[JSON_start_index[0]::].index('</script>') + script_index + JSON_start_index[1]
availability_JSON_str = html_source[JSON_start_index[0]:JSON_end_index:1].strip()
shoe_size_objects = json.loads(availability_JSON_str)
# APPENDING AVAILABLE SHOES TO A LIST
available_shoes = []
for shoe_size in shoe_size_objects: # Iterating each shoe size object
if shoe_size_objects[shoe_size]['TemEstoque'] == '1': # Shoe Size is available (TemEstoque is attribute name)
available_shoes.append(shoe_size)
selected_size = random.choice(available_shoes) # Selecting one of available shoe size randomly
'''==================================== SECTION - IV ===================================='''
def get_size_ID(): # UTILITY FUNCTION [ Works Fine, Ignore ]
global shoe_size_objects
global selected_size
for size in shoe_size_objects:
if shoe_size_objects[size]['Tamanho'] == str(selected_size):
return 'tamanho__id{}'.format(selected_size)
size_elem = None
'''==================================== PROBLEMATIC CODE ===================================='''
WebDriverWait(driver, 5).until(
EC.frame_to_be_available_and_switch_to_it(
( By.CSS_SELECTOR,
"iframe[name^='a-'][src^='https://www.google.com/recaptcha/api2/anchor?']"
)
))
size_elem = WebDriverWait(driver, 5).until(
EC.visibility_of_element_located(
( By.ID,
get_size_ID()
)
))
driver.execute_script("arguments[0].click();", size_elem)
#ActionChains(driver).move_to_element(size_elem).click(size_elem).perform()
ДЕТАЛИ:
Вы должны заметить, что я использую профиль по умолчанию chrome, то есть тот, где сохраняются учетные данные моей кредитной карты и синхронизированные пароли / автоматический вход в систему , Вот как я планирую решить CAPTCHA и заполнить учетные данные (через автозаполнение, которое, как мы надеемся, будет активировано при необходимости). После того, как капча решена, размеры обуви отображаются динамически, имея общий вид:
[ul] / [li] / [input type = 'radio'] / [label]
Я получаю ElementNotInteractable исключение при нацеливании на метку, поэтому я нацеливаюсь на элемент ввода по его идентификатору.
ПРОБЛЕМА:
Итак, я просмотрел большинство важных вопросов здесь, в StackOverflow, и обнаружил, что мне нужен код, указанный в разделе iv для выбора размера (.click () не работает). Тем не менее, это не работает. Это всегда истекает и не может найти элемент ввода. Я пытался получить доступ к нему по ID, классу, XPATH, имени, но ни один не работал.
Однако, однажды, только один раз, он работал правильно и выбрал размер, я не знаю, как и почему, но он работал, и теперь снова это не работает.
Я пробовал разные способы доступа к нему, например
- wait.until (E C .visibility_of_element_located ((By.ID/XPATH,'id ')))
wait.until (E C .presence_of_element_located ((By.ID/XPATH, 'id'])))
wait.until (E C .element_to_be_clickable ((By.ID/XPATH, 'id'))
но без помощи, все, что я получаю, это исключение тайм-аута.
Любая помощь будет высоко оценена .:)