Python 硒元素不可交互异常-如何克服?

Python 硒元素不可交互异常-如何克服?,python,python-3.x,selenium,selenium-webdriver,Python,Python 3.x,Selenium,Selenium Webdriver,我正在使用Selenium和Python从网站上获取产品的价格。 当我运行应用程序时,chromewebdriver会打开,当它打开网站上弹出的通知/消息,上面写着“接受Cookies”时,我会以编程方式接受它,但我的程序很快就会停止执行。其目的是接受cookies->输入产品名称(以编程方式完成)->显示产品后->在我的终端上显示产品价格。这是我的代码 def scrape_currys(product_name): website_address = 'https://www.cur

我正在使用Selenium和Python从网站上获取产品的价格。 当我运行应用程序时,chromewebdriver会打开,当它打开网站上弹出的通知/消息,上面写着“接受Cookies”时,我会以编程方式接受它,但我的程序很快就会停止执行。其目的是接受cookies->输入产品名称(以编程方式完成)->显示产品后->在我的终端上显示产品价格。这是我的代码

def scrape_currys(product_name):
    website_address = 'https://www.currys.co.uk/gbuk/index.html'
    options = webdriver.ChromeOptions()
    options.add_argument('start-maximized')
    options.add_argument("window-size=1200x600")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)

    browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)

    browser.get(website_address)
    time.sleep(2)

    # browser.implicitly_wait(30)
    browser.find_element_by_id('onetrust-accept-btn-handler').click()
    browser.find_element_by_name('search-field').send_keys(product_name)
    browser.find_elements_by_class_name('Button__StyledButton-bvTPUF hfufmD Button-jyKNMA GZkwS')[0].submit()
    page_source = browser.page_source
    print(page_source)
    soup = BeautifulSoup(page_source, 'lxml')
    product_price_list = soup.find_all('div', class_='ProductCardstyles__PriceText-gm8lcq-14 lhwdnp')
    return product_price_list[0].text


if __name__ == '__main__':
    product_name_list = ['Canon EF 24-105mm f/4L IS II USM Lens']
    for product in product_name_list:
        scrape_currys(product)
该错误进一步显示为
selenium.common.exceptions.elementnotinteractitableexception:Message:element notinteractitable
这是完整的堆栈跟踪

Traceback (most recent call last):
  File "scrapeCurrys.py", line 34, in <module>
    scrape_currys(product)
  File "scrapeCurrys.py", line 22, in scrape_currys
    browser.find_element_by_name('search-field').send_keys(product_name)
  File "/home/mayureshk/PycharmProjects/Selenium-Scraper/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 479, in send_keys
    'value': keys_to_typing(value)})
  File "/home/mayureshk/PycharmProjects/Selenium-Scraper/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/home/mayureshk/PycharmProjects/Selenium-Scraper/venv/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/home/mayureshk/PycharmProjects/Selenium-Scraper/venv/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
  (Session info: chrome=74.0.3729.108)
  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Linux 5.0.0-1034-oem-osp1 x86_64)

回溯(最近一次呼叫最后一次):
文件“scrapeCurrys.py”,第34行,在
刮削咖喱(产品)
文件“scrapeCurrys.py”,第22行,在scrape_currys中
浏览器。按名称(“搜索字段”)查找元素。发送密钥(产品名称)
文件“/home/mayureshk/PycharmProjects/Selenium Scraper/venv/lib/python3.7/site packages/Selenium/webdriver/remote/webelement.py”,第479行,在发送键中
“值”:键到键入(值)})
文件“/home/mayureshk/PycharmProjects/Selenium Scraper/venv/lib/python3.7/site packages/Selenium/webdriver/remote/webelement.py”,第633行,在
返回self.\u parent.execute(命令,参数)
文件“/home/mayureshk/PycharmProjects/Selenium Scraper/venv/lib/python3.7/site packages/Selenium/webdriver/remote/webdriver.py”,执行中第321行
self.error\u handler.check\u响应(响应)
文件“/home/mayureshk/PycharmProjects/Selenium Scraper/venv/lib/python3.7/site packages/Selenium/webdriver/remote/errorhandler.py”,第242行,在check_响应中
引发异常类(消息、屏幕、堆栈跟踪)
selenium.common.exceptions.ElementNotInteractiableException:消息:元素不可交互
(会话信息:chrome=74.0.3729.108)
(驱动程序信息:chromedriver=74.0.3729.6(255758ECCF3D24491B8A1317AA76E1CE10D57E9参考/分支头/3729{29}),平台=Linux 5.0.0-1034-oem-osp1 x8664)

关于同一个问题,我在这里已经讨论了几个答案,但是没有一个尝试这么长时间是成功的。我什么都试过了。我希望得到一个答案,因为这里的大多数人都很有知识。提前谢谢

当您遇到与查找元素相关的错误时,必须尝试其他元素定位器。这将有助于:

from selenium.webdriver.common.keys import Keys

def scrape_currys(product_name):
    website_address = 'https://www.currys.co.uk/gbuk/index.html'
    options = webdriver.ChromeOptions()
    options.add_argument('start-maximized')
    options.add_argument("window-size=1200x600")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)

    browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)

    browser.get(website_address)
    time.sleep(2)

    # browser.implicitly_wait(30)
    browser.find_element_by_id('onetrust-accept-btn-handler').click()
    browser.find_element_by_xpath('//*[@id="header"]/div[1]/form/div/div/input').send_keys(product_name + Keys.ENTER)
    time.sleep(2)
    page_source = browser.page_source
    print(page_source)
    soup = BeautifulSoup(page_source, 'lxml')
    product_price_list = soup.find_all('div', class_='ProductCardstyles__PriceText-gm8lcq-14 lhwdnp')
    return product_price_list[0].text


if __name__ == '__main__':
    product_name_list = ['Canon EF 24-105mm f/4L IS II USM Lens']
    for product in product_name_list:
        scrape_currys(product)

当出现与查找元素相关的错误时,必须尝试其他元素定位器。这将有助于:

from selenium.webdriver.common.keys import Keys

def scrape_currys(product_name):
    website_address = 'https://www.currys.co.uk/gbuk/index.html'
    options = webdriver.ChromeOptions()
    options.add_argument('start-maximized')
    options.add_argument("window-size=1200x600")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)

    browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)

    browser.get(website_address)
    time.sleep(2)

    # browser.implicitly_wait(30)
    browser.find_element_by_id('onetrust-accept-btn-handler').click()
    browser.find_element_by_xpath('//*[@id="header"]/div[1]/form/div/div/input').send_keys(product_name + Keys.ENTER)
    time.sleep(2)
    page_source = browser.page_source
    print(page_source)
    soup = BeautifulSoup(page_source, 'lxml')
    product_price_list = soup.find_all('div', class_='ProductCardstyles__PriceText-gm8lcq-14 lhwdnp')
    return product_price_list[0].text


if __name__ == '__main__':
    product_name_list = ['Canon EF 24-105mm f/4L IS II USM Lens']
    for product in product_name_list:
        scrape_currys(product)

让我解释一下你做错了什么。第一个问题在
浏览器行中。按名称(“搜索字段”)查找元素。发送密钥(产品名称)
。如果您检查html代码,您将看到有两个名为“search field”的输入,第一个是隐藏的,这就是您获得
ElementNotInteractiableException
的原因:

您可以通过获取所有元素并选择第二个元素来轻松解决此问题,只需切换到
浏览器。按名称(“搜索字段”)查找元素[1]。发送密钥(产品名称)

当您进行此修复时,您将在尝试使用按钮提交搜索时发现类似的问题。您可以使用
浏览器。通过xpath('//按钮[@type=“submit”]')[1]查找元素。单击()

要获得价格,您不需要使用BeautifulSoup,因为您已经在浏览器对象中获得了所需的所有信息。只需使用
product\u price\u list=browser获取它们。通过xpath('//strong[@class=“price”]')查找元素。

下面是一个完整的解决方案示例:

def scrape_currys(product_name):
    website_address = 'https://www.currys.co.uk/gbuk/index.html'
    options = webdriver.ChromeOptions()
    options.add_argument('start-maximized')
    options.add_argument("window-size=1200x600")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)

    browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)

    browser.get(website_address)
    time.sleep(2)

    # browser.implicitly_wait(30)
    browser.find_element_by_id('onetrust-accept-btn-handler').click()
    browser.find_elements_by_name('search-field')[1].send_keys(product_name)
    browser.find_elements_by_xpath('//button[@type="submit"]')[1].click()
    
    product_price_list = browser.find_elements_by_xpath('//strong[@class="price"]')
    return [elem.text for elem in product_price_list]


if __name__ == '__main__':
    product_name_list = ['Canon EF 24-105mm f/4L IS II USM Lens']
    for product in product_name_list:
        price_list = scrape_currys(product)
        print(price_list_list)
输出:

['£2,329.00', '£409.00', '£1,629.00', '£1,249.00', '£1,149.00', '£649.00', '£959.00', '£599.00', '£329.00', '£589.00', '£2,049.00', '£419.00', '£1,349.00', '£669.00', '£639.00']

让我解释一下你做错了什么。第一个问题在
浏览器行中。按名称(“搜索字段”)查找元素。发送密钥(产品名称)
。如果您检查html代码,您将看到有两个名为“search field”的输入,第一个是隐藏的,这就是您获得
ElementNotInteractiableException
的原因:

您可以通过获取所有元素并选择第二个元素来轻松解决此问题,只需切换到
浏览器。按名称(“搜索字段”)查找元素[1]。发送密钥(产品名称)

当您进行此修复时,您将在尝试使用按钮提交搜索时发现类似的问题。您可以使用
浏览器。通过xpath('//按钮[@type=“submit”]')[1]查找元素。单击()

要获得价格,您不需要使用BeautifulSoup,因为您已经在浏览器对象中获得了所需的所有信息。只需使用
product\u price\u list=browser获取它们。通过xpath('//strong[@class=“price”]')查找元素。

下面是一个完整的解决方案示例:

def scrape_currys(product_name):
    website_address = 'https://www.currys.co.uk/gbuk/index.html'
    options = webdriver.ChromeOptions()
    options.add_argument('start-maximized')
    options.add_argument("window-size=1200x600")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)

    browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)

    browser.get(website_address)
    time.sleep(2)

    # browser.implicitly_wait(30)
    browser.find_element_by_id('onetrust-accept-btn-handler').click()
    browser.find_elements_by_name('search-field')[1].send_keys(product_name)
    browser.find_elements_by_xpath('//button[@type="submit"]')[1].click()
    
    product_price_list = browser.find_elements_by_xpath('//strong[@class="price"]')
    return [elem.text for elem in product_price_list]


if __name__ == '__main__':
    product_name_list = ['Canon EF 24-105mm f/4L IS II USM Lens']
    for product in product_name_list:
        price_list = scrape_currys(product)
        print(price_list_list)
输出:

['£2,329.00', '£409.00', '£1,629.00', '£1,249.00', '£1,149.00', '£649.00', '£959.00', '£599.00', '£329.00', '£589.00', '£2,049.00', '£419.00', '£1,349.00', '£669.00', '£639.00']

嗨,谢谢你的快速回复。我知道你在哪里做了一些修改,脚本运行良好,但是也打印了很多不需要的东西。我只想打印产品的价格,而不是所有的东西-它甚至打印html代码。嗨,谢谢你的快速回复。我知道你在哪里做了一些修改,脚本运行良好,但是也打印了很多不需要的东西。我只想打印产品的价格,而不是所有的东西——它甚至可以打印html代码。