Я написал программу на Python для сбора данных с веб-сайта https://www.kijijiautos.ca/ cars/gmc/canyon/#ml=%3A&ms=9900%3B13&od=up&p=5000%3A&sb=p&yc=2024%3A2024. Я хочу использовать кнопку «Установить местоположение», чтобы ввести свой почтовый индекс (канадская особенность). Я пытаюсь использовать команды Chromedriver для эмуляции того, что я делаю вручную. Вручную я бы нажал кнопку «Установить местоположение», после чего появилось новое маленькое окно. Затем я вводил свой почтовый индекс и нажимал клавишу Enter, чтобы включить его. Затем я нажимаю на поле «Радиус» и выбираю опцию «1000». Затем я щелкнул флажок «Ограничить радиус провинцией», чтобы включить его. Затем я щелкнул поле «Результаты nnn», и данные были введены, окно исчезло, и веб-страница обновила результаты моего поиска.
Я пытаюсь подражать это в моем программировании, но я не вижу, чтобы мои данные вообще обновляли веб-страницу. Когда я сбрасываю данные элемента до и после обновлений, данные никогда не меняются. Это подтверждается тем фактом, что он не работает с надписью «Вы не можете выбрать отключенную опцию» для поля «Радиус», поскольку оно отключено до тех пор, пока данные не будут успешно введены в поле «Почтовый индекс».
Понятия не имею, что я делаю не так. Любой вклад будет очень признателен. Обратите внимание, что моя программа сохраняет журнал выполнения веб-драйвера, поэтому я могу видеть там любые ошибки — ни одна из них не отображается так, как я вижу.
Программный код:
Код: Выделить всё
# type: ignore
print('\nStarting program ...')
# Bring in basic libraries
import os
import time
# File names to be created
fnames = {
'web': 'logging-web.txt', # Webdriver console messages
}
# Check if the output files are in use - remove file if it exists and is not open
for fn in fnames:
if os.path.isfile(fnames[fn]):
try:
os.remove(fnames[fn])
except Exception as err:
print(f"\nERROR: {err} - ABORTING ...",flush=True)
exit(False)
# Bring in additional libraries
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Set up ChromeDriver options
chrome_options = Options()
chrome_options.add_argument('--remote-debugging-pipe')
chrome_options.add_argument('--incognito')
chrome_options.add_argument('--headless=new')
chrome_options.add_argument('--accept-all-cookies')
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--ignore-ssl-errors')
chrome_options.add_argument('--disable-infobars')
chrome_options.add_argument('--disable-notifications')
# DEBUG chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# DEBUG chrome_options.add_argument('--enable-popup-blocking')
chrome_options.add_argument('--log-level=3')
chrome_options.page_load_strategy = 'normal' # 'eager' does not always get all of the data on a page
chrome_options.add_experimental_option('excludeSwitches',['enable-logging','enable-automation'])
chrome_options.add_experimental_option('prefs',{'profile.managed_default_content_settings.images':2}) # Don't render images
# Set up ChromeDriver logging
wservice = webdriver.ChromeService(service_args=['--append-log','--readable-timestamp'],log_output=f"{fnames['web']}")
# Start the webdriver
driver = webdriver.Chrome(options=chrome_options,service=wservice)
driver.maximize_window()
driver.set_script_timeout(30)
winhancurr = driver.current_window_handle
url = 'https://www.kijijiautos.ca/cars/gmc/canyon/#ml=%3A&ms=9900%3B13&od=up&p=5000%3A&sb=p&yc=2024%3A2024'
print(f"\nGetting webpage {url} ...")
print(f"\nINFO: original window handle={driver.current_window_handle}")
driver.get(url)
WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.TAG_NAME,'body')))
# Find "Set location" button and click on it. Note that there are 2 identical fields and only the 2nd one works.
# Also note that clicking this button opens another window on top of the current webpage.
elem = WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="root"]/div[3]/div/section[5]/div/div/div[1]/div/div[1]/div/button')))
print(f"\nINFO: elem.before={elem.get_attribute("outerHTML")}")
elem.click()
print(f"\nINFO: elem.after={driver.find_element(By.XPATH,'//*[@id="root"]/div[3]/div/section[5]/div/div/div[1]/div/div[1]/div/button').get_attribute("outerHTML")}")
# Find new window and move to it
for winhan in driver.window_handles:
print(f"\nINFO: window handles={winhan}")
if winhan != winhancurr:
driver.switch_to.window(winhan)
print(f"\nINFO: new window handle={driver.current_window_handle}")
break
if driver.current_window_handle == winhancurr:
print(f"\nERROR: No new window created ...")
# Put postalcode data into field and end data input
elem2 = WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.ID,'LocationAutosuggest')))
print(f"\nINFO: elem2.before={driver.find_element(By.ID,'LocationAutosuggest').get_attribute("outerHTML")}")
elem2.send_keys('T1J 4C8')
elem2.send_keys(Keys.ENTER)
print(f"\nINFO: elem2.after={driver.find_element(By.ID,'LocationAutosuggest').get_attribute("outerHTML")}")
# Find "Radius" field and enter data
elem3 = WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.ID,'rd')))
print(f"\nINFO: elem3.before={elem3.get_attribute("outerHTML")}")
drop = Select(elem3)
drop.select_by_value('1000')
print(f"\nINFO: elem3.after={elem3.get_attribute("outerHTML")}")
# Click on "Limit radius to province" checkbox
elem4 = WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.NAME,'limitedToProvince')))
print(f"\nINFO: elem4={elem4.get_attribute("outerHTML")}")
elem4.click()
# Apply all changes
elem5 = WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.LINK_TEXT,'Apply')))
print(f"\nINFO: elem5={elem5.get_attribute("outerHTML")}")
elem5.click()
# Switch back to original window
driver.switch_to.window(winhancurr)
# End the driver
driver.quit()
# End of main
Код: Выделить всё
Starting program ...
Getting webpage https://www.kijijiautos.ca/cars/gmc/canyon/#ml=%3A&ms=9900%3B13&od=up&p=5000%3A&sb=p&yc=2024%3A2024 ...
INFO: original window handle=5DCA8B95024DB03D50D0A6302BA77DE3
INFO: elem.before=Set location
INFO: elem.after=Set location
INFO: window handles=5DCA8B95024DB03D50D0A6302BA77DE3
ERROR: No new window created ...
INFO: elem2.before=
INFO: elem2.after=
INFO: elem3.before=+ 5 km+ 10 km+ 15 km+ 25 km+ 50 km+ 100 km+ 150 km+ 250 km+ 500 km+ 750 km+ 1,000 km
Traceback (most recent call last):
File "C:\Users\david.DESKTOP-IH066BB\Documents\Software\CarSearch\testx.py", line 95, in
drop.select_by_value('1000')
~~~~~~~~~~~~~~~~~~~~^^^^^^^^
File "C:\Users\david.DESKTOP-IH066BB\AppData\Local\Programs\Python\Python313\Lib\site-packages\selenium\webdriver\support\select.py", line 79, in select_by_value
self._set_selected(opt)
~~~~~~~~~~~~~~~~~~^^^^^
File "C:\Users\david.DESKTOP-IH066BB\AppData\Local\Programs\Python\Python313\Lib\site-packages\selenium\webdriver\support\select.py", line 213, in _set_selected
raise NotImplementedError("You may not select a disabled option")
NotImplementedError: You may not select a disabled option
Подробнее здесь: https://stackoverflow.com/questions/792 ... y-my-input