How to select an element based on a polyline using Selenium and Python?

孤街醉人 提交于 2021-02-10 15:41:21

问题


I am trying to select and click on an element in Selenium, but it doesn't have the typical tags, and the xpath changes on reload. The symbol stays consistent though, and I want to be able to select the button using the symbol.

The HTML looks like this:

<svg x="0px" y="0px" viewBox="0 0 40 34" enable-background="new 0 0 40 34" focusable="false" style="fill: rgb(255, 255, 255); stroke-width: 0px; width: 100%; --darkreader-inline-fill:#e8e6e3;" data-darkreader-inline-fill="">
    <g fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" data-darkreader-inline-fill="" data-darkreader-inline-stroke="" style="--darkreader-inline-fill:none; --darkreader-inline-stroke:#e8e6e3;">
        <polyline points="18,11.7 9.6,11.7 9.6,25 30.1,25 30.1,17.1"></polyline>
        <polyline points="27.8,14 30.6,8.4 25,6.5"></polyline>

The polyline stays the same, and should let me select what I need, but I can't find how to select the polyline via Selenium.

I have tried selecting by xPath with something like this:

self.driver.find_element_by_xpath('//*[@id="content"]/section/div[1]/div[1]/a[1]').click()

The issue with that is the fact that this changes when the page reloads, so it isn't consistent.

I have found that what is consistant is the polyline, but I can't find a way to reference the polyline and click on it.

Is there a way to do this?

EDIT:

After looking into the page I am trying to grab, I could also grab the element by the data-handle.

<div class="w-css-reset" data-handle="shareButton" style="display: inline-block; vertical-align: top;">
<div class="w-vulcan-button-wrapper w-css-reset" style="display: inline-block; height: 20px; position: relative; vertical-align: top; width: 24px;">
<button tagname="button" class="w-vulcan-v2-button w-css-reset w-css-reset-tree w-css-reset-button-important" aria-expanded="false" aria-label="Close sharing menu" title="Close sharing menu" style="background-color: rgba(0, 0, 0, 0); box-shadow: none; cursor: pointer; height: 100%; position: relative; transition: background-color 150ms ease 0s; width: 100%; --darkreader-inline-bgcolor:rgba(0, 0, 0, 0); --darkreader-inline-boxshadow:none;" data-darkreader-inline-bgcolor="" data-darkreader-inline-boxshadow="">
<div class="w-vulcan-icon-wrapper" data-handle="shareButton" style="box-sizing: border-box; height: 100%; position: relative; transform: scale(1.001); transition: transform 200ms ease 0s;">
<svg x="0px" y="0px" viewBox="0 0 40 34" enable-background="new 0 0 40 34" focusable="false" style="fill: rgb(255, 255, 255); stroke-width: 0px; width: 100%; --darkreader-inline-fill:#e8e6e3;" data-darkreader-inline-fill="">
<g fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" data-darkreader-inline-fill="" data-darkreader-inline-stroke="" style="--darkreader-inline-fill:none; --darkreader-inline-stroke:#e8e6e3;">
<polyline points="18,11.7 9.6,11.7 9.6,25 30.1,25 30.1,17.1"></polyline><polyline points="27.8,14 30.6,8.4 25,6.5">
</polyline><path d="M30.3,8.7c-6.7,1.9-10.9,5.9-10.9,11.6"></path></g></svg></div>
</button>
<div class="w-anchor w-css-reset" style="height: 0px; left: 0px; position: absolute; top: 0px; width: 100%;">
<div class="w-dialog w-css-reset" style="background: rgba(0, 0, 0, 0.7); bottom: 0px; color: rgb(255, 255, 255); display: none; left: 0px; line-height: 34px; max-height: 97.6px; opacity: 0; overflow: hidden auto; position: absolute; transition: opacity 120ms ease 40ms, transform 120ms ease 40ms; transform: scaleY(0.6); transform-origin: center bottom; --darkreader-inline-bgimage: initial; --darkreader-inline-bgcolor:rgba(0, 0, 0, 0.7); --darkreader-inline-color:#e8e6e3; width: 72px;" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">
<div class="w-css-reset" style="opacity: 0; transition: opacity 100ms ease 0ms;">
<div class="w-css-reset" data-handle="shareButton__dialog" style="box-sizing: border-box; display: inline-block; height: 100%; vertical-align: bottom; width: 100%;"><ul class="w-css-reset w-css-reset-tree"><li style="width: 100%;">
<button class="w-css-reset-button-important w-vulcan-v2-button" style="box-shadow: none; cursor: pointer; display: flex; align-items: center; font-size: 14px; font-family: WistiaPlayerInter, Helvetica, sans-serif; line-height: 34px; height: 34px; width: 100%; --darkreader-inline-boxshadow:none; --darkreader-inline-bgimage: initial; --darkreader-inline-bgcolor:rgba(0, 0, 0, 0.3);" data-darkreader-inline-boxshadow=""><div style="width: 15px; margin-left: 1em; margin-right: 1em; display: inline-block;"><svg viewBox="0 0 19.4 15.4" style="position: static; vertical-align: middle; display: inline;"><g fill="none" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" strokeMiterlimit="10" data-darkreader-inline-fill="" data-darkreader-inline-stroke="" style="--darkreader-inline-fill:none; --darkreader-inline-stroke:#e8e6e3;"><polyline points="0.8,6.2 0.8,14.7 18.6,14.7 18.6,6.2  "></polyline><polyline points="13.5,7.3 9.7,11.1 5.9,7.3  "></polyline><line x1="9.7" y1="11.1" x2="9.7" y2="0.8"></line></g></svg></div><span>Download</span></button></li></ul></div><div class="w-css-reset" tabindex="0" style="clip: rect(0px, 0px, 0px, 0px); height: 1px; position: absolute; top: 0px; width: 1px;"></div></div></div></div></div></div>

回答1:


As you are able to grab the element by the data-handle attribute, so you don't have to reach till the <polyline> tag. Instead, to click on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='Close sharing menu'][aria-label='Close sharing menu'] > div[data-handle='shareButton']"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@title='Close sharing menu' and @aria-label='Close sharing menu']/div[@data-handle='shareButton']"))).click()
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    


来源:https://stackoverflow.com/questions/63236399/how-to-select-an-element-based-on-a-polyline-using-selenium-and-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!