Python / Selenium - поиск xpath, который увеличивает каждую нагрузку - PullRequest
0 голосов
/ 07 марта 2020

Я занимаюсь Python / Selenium и столкнулся с небольшой проблемой. У меня есть эта программа, которая запускается и ищет xpath, заканчивает тем, что записывает некоторые данные в текстовое поле, сохраняет и закрывает. Xpath выглядит так:

//*[@id="app-mount"]/div/div/section/div/div/div[2]/div/div[28]/div[2]/div[1]/div/div[1]/div[2]

Проблема в том, что когда моя программа записывает данные и закрывается (в основном, добавляя что-то на веб-страницу), xpath выглядит следующим образом:

//*[@id="app-mount"]/div/div/section/div/div/div[2]/div/div[29]/div[2]/div[1]/div/div[1]/div[2]

Так что в принципе, div [28] превращается в div [29] по логическим причинам. Следующим запуском будет 30, и так далее.

Итак, мой оригинальный код ниже ищет xpath, который я только что нашел из элемента inspect

click_textbox = driver.find_element_by_xpath('//*[@id="app-mount"]/div/div/section/div/div/div[2]/div/div[28]/div[2]/div[1]/div/div[1]/div[2]').click()

Это явно не будет работать над следующей загрузкой, когда число увеличилось.

Есть ли способ в Selenium игнорировать исходное 28 или любое другое число и просто найти элемент, который совпадает с любым числом?

То, что я думал, что сделаю это Я бы написал текстовый файл с текущим номером 28, прочитал этот файл при загрузке и сохранил номер в переменной, которую затем мог бы передать в путь. Увеличивайте и повторно сохраняйте файл в конце программы.

Теоретически это звучит так, как будто это сработает, если я не беспокоюсь об одном. Если бы я должен был вручную изменить эту страницу, число в этом div было бы +1 или +, сколько бы я ни добавил данных. Таким образом, моя программа затем прочитала бы текстовый файл с неправильным начальным номером.

Еще одним соображением было написать al oop с некоторым большим числом и просто l oop, чтобы увидеть, существует ли путь со многими попытками - это звучит дико неэффективно.

Последнее соображение заключалось в поиске по классам, но из того, что я вижу, нет элементов, которые я могу найти, это stati c. Все динамично c.

Есть ли способ обойти это, я просто не рассматриваю?

Спасибо, ребята!

Редактировать: Соответствующий HTML

<div class="sc-fYiAbW jysCvP">
   <div class="sc-gHboQg grynts sc-bbmXgH kAFgNQ">
      <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
         <g fill="none" fill-rule="evenodd">
            <polygon fill="#f04747" fill-rule="nonzero" points="14.25 4.808 13.193 3.75 9 7.942 4.808 3.75 3.75 4.808 7.942 9 3.75 13.193 4.808 14.25 9 10.057 13.193 14.25 14.25 13.193 10.057 9"></polygon>
            <polygon points="0 0 18 0 18 18 0 18"></polygon>
         </g>
      </svg>
   </div>
   <div>
      <div class="sc-VJcYb QcOss sc-gGBfsJ cHDGOG">
         <div class="sc-jnlKLf gGiTQ">
            <div class="sc-fYxtnH fjJbC">
               <div class="sc-iELTvK jxwSnG" style="display: inline-block;">
                  <input value="" style="box-sizing: content-box; width: 2px;">
                  <div style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-size: 14px; font-family: &quot;Open Sans&quot;, Helvetica, arial, sans-serif; font-weight: 400; font-style: normal; letter-spacing: normal; text-transform: none;"></div>
               </div>
               <div class="sc-kafWEX sc-feJyhm fIPufP">Search</div>
            </div>
            <div class="sc-cIShpX gYoApc"><img src="/assets/028b613c85837c6a55c1fe1867f2df21.svg" alt="select value"></div>
         </div>
      </div>
      <div class="sc-gPWkxV cHvPXE">
         <div class="sc-eMigcr gllDew">
            <div class="sc-fONwsr glHYVA">Message</div>
            <div class="sc-ipXKqB hTYHjb sc-iQNlJl cczJYS">
               <div class="sc-bsbRJL iWfNVE">
                  <textarea class="sc-hZSUBg kSbYur">message</textarea>
                  <div class="sc-cMhqgX gMMQSz">67 / 2000</div>
                  <div class="sc-iuJeZd wmsrp">
                     <div class="sc-esOvli hqAiNF"></div>
                  </div>
               </div>
            </div>
         </div>
         <div class="sc-fzsDOv bDdDc">
            <div class="sc-fONwsr glHYVA">Post in channel</div>
            <div class="sc-giadOv cGVZZm sc-gGBfsJ cHDGOG">
               <div class="sc-jnlKLf gGiTQ">
                  <div class="sc-fYxtnH fjJbC">
                     <div class="sc-iELTvK jxwSnG" style="display: inline-block;">
                        <input value="" style="box-sizing: content-box; width: 2px;">
                        <div style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-size: 14px; font-family: &quot;Open Sans&quot;, Helvetica, arial, sans-serif; font-weight: 400; font-style: normal; letter-spacing: normal; text-transform: none;"></div>
                     </div>
                     <div class="sc-kafWEX sc-feJyhm fIPufP"></div>
                  </div>
                  <div class="sc-cIShpX gYoApc"><img src="" alt="select value"></div>
               </div>
            </div>
         </div>
      </div>
   </div>
   <div class="sc-fOKMvo xwGrl"><button class="sc-dUjcNx cGRmQH sc-kgoBCf jZvXPW" color="#ffffff">Cancel</button><button class="sc-kgoBCf htfypm" color="#5ac0de" disabled="">Save</button></div>
</div>

В поле ввода, в котором мой код вставляет данные:

<div class="sc-iELTvK jxwSnG" style="display: inline-block;">
   <input value="" style="box-sizing: content-box; width: 2px;">
   <div style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-size: 14px; font-family: &quot;Open Sans&quot;, Helvetica, arial, sans-serif; font-weight: 400; font-style: normal; letter-spacing: normal; text-transform: none;"></div>
</div>

1 Ответ

0 голосов
/ 07 марта 2020

Есть пара INPUT, которые соответствуют HTML, поэтому я покажу вам, как получить оба учебных пособия для пары.

Первый находится прямо перед ярлыком "Поиск". Там не так много уникального, что я могу видеть в DOM выше, что INPUT, но метка «Поиск» находится сразу после него, поэтому мы будем использовать это, чтобы найти INPUT # 1.

При создании локатора это будет несколько сложно, я строю это поэтапно.

  1. Найдите свой якорь. В этом случае якорь является DIV, который содержит «Поиск». Поскольку мы размещаем элемент по содержащемуся тексту, нам нужно использовать XPath.

    //div[text()='Search']
    
  2. Теперь, когда мы нашли привязку, нам нужно найти нужный элемент. относительно этого якоря. Есть много способов сделать это, но я покажу вам пару.

    Одним из способов является использование оси preceding. Он находит элементы, которые идут перед элементом в DOM.

    //div[text()='Search']//preceding::input
    

    Другой способ - найти элемент, который является родительским для якоря и нужного элемента, а затем пройти вниз по DOM, чтобы найти элемент. Вы хотите.

    Это находит DIV, который является родителем

    //div[./div[text()='Search']]
    ^ find a DIV
         ^ that has a descendant DIV that contains the text "Search"
    

    , тогда оттуда мы просто идем вниз по DOM к желаемому INPUT

    //div[./div[text()='Search']]//input
    

Второй INPUT находится после метки "Post in channel". Мы можем использовать аналогичный подход к # 1 выше, но вместо этого использовать ось following. (ПРИМЕЧАНИЕ: following идет вниз по DOM, preceding идет вверх.)

//div[text()='Post in channel']//following::input

XPath может быть довольно сложным, но очень мощным. Большинство инструкций скажет вам использовать ID, затем CSS селекторы, а затем, наконец, XPath для вещей, которые CSS селекторы не могут сделать, например, поиск по содержанию текста или обход DOM (оба мы сделали здесь).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...