#python #selenium #xpath
#python #селен #xpath
Вопрос:
Я пытаюсь использовать python selenium для выбора пользователей на веб-странице и открытия ссылки на их профиль. Ниже приведен повторяющийся HTML-код для каждого пользователя на веб-странице:
<div class="w-50-ns w-100 ph1">
<div class="w-100 br1 pointer bg-animate hover-bg-dark-primary bg-near-black" onclick="openLink(event, '/users/0000')">
<div class="pv2 pr3 pl2 mb2 br1">
<div class="flex items-center pa1">
<div class="flex-auto mw-100">
<div class="flex items-center">
<div class="flex-none flex items-center">
<a class="relative overflow-hidden dib mr3-ns mr2 link" data-tippy-theme="lighter small" href="/users/0000" aria-expanded="false">
<img class="db ipp br1 object-cover" src="https://" width="70" height="70">
</a>
</div>
<div class="relative flex-auto mw-100 mw-none-ns" style="max-height: 58px; top: -1px;">
<div class="lh-copy truncate silver">
<a class="link span f5 fw7 secondary" href="/users/0000">UserName</a>
amp;nbsp;
<span class="f6 fw7 silver">AgeSex Category</span>
</div>
<div class="f6 lh-copy fw4 silver nowrap truncate">Los Angeles, California</div>
<div class="relative pd1 f6 fw4 lh-copy mid-gray nowrap truncate">
<a class="link gray hover-silver" href="/users/0000/pictures"># pics</a>
amp;nbsp;·amp;nbsp;
<a class="link gray hover-silver" href="/users/0000/posts"># posts</a>
</div>
</div>
</div>
</div>
<div class="flex">
<div class="tr">
</div>
</div>
</div>
</div>
</div>
</div>
Это основная часть, на которую я смотрю. Я пытаюсь проверить, соответствует ли возрастной диапазон, т.Е. 19F или 20M, выбранному диапазону и полу, и если это так, нажмите на ссылку профиля пользователя над ней
<div class="lh-copy truncate silver">
<a class="link span f5 fw7 secondary" href="/users/0000">UserName</a>
amp;nbsp;
<span class="f6 fw7 silver">AgeSex Category</span>
</div>
Я пытался:
self.driver.find_elements_by_xpath("//span[contains(., '18F') or contains(., '20M')])/preceding-sibling::class[ @name = 'link span f5 fw7 secondary']").click()
self.driver.find_elements_by_xpath("//span[contains(text(), '18F') or contains(text(), '20M')])/preceding-sibling::class[ @name = 'link span f5 fw7 secondary']").click()
Но я получаю сообщение об ошибке:
actions.move_to_element(element, 0, 0).perform()
TypeError: move_to_element() takes 2 positional arguments but 4 were given
Я новичок в этом, поэтому понятия не имею, иду ли я вообще в правильном направлении, и любая помощь будет принята с благодарностью. Спасибо.
Ответ №1:
Итак, я поиграл с ним сегодня и нашел, как открыть URL-адрес одного AgeSex:
self.driver.find_element_by_xpath("//span[contains (.,'23F')]").click();
Я решил пойти другим путем и вместо нажатия на элемент составить список всех URL-адресов.
self.driver.find_element(By.XPATH,"//span[contains (.,'30F')]/preceding-sibling::a[1]").get_attribute('href')
Однако приведенное выше — это только один возрастной параметр, поэтому я должен записать его для каждого параметра. Если бы он не существовал, это выдало бы ошибку, поэтому я написал блок try и except для каждого из них:
try:
if self.driver.find_element(By.XPATH, "//span[contains (.,'27F')]").is_displayed():
user27 = self.driver.find_element(By.XPATH,"//span[contains (.,'27F')]/preceding-sibling::a[1]").get_attribute('href')
if user27 not in urls:
urls.append(user27)
except:
pass
Если атрибут существует, он добавляет ссылку href в список.
Я чувствую, что должен быть намного лучший способ написать это. Способ, который более эффективен и не требует 10-15 блоков try и except
Ответ №2:
Я мог бы выполнить щелчок, используя следующую команду:
driver.find_element_by_xpath("//span[contains(., '18F') or contains(., '20M')]/preceding-sibling::a[@class = 'link span f5 fw7 secondary']").click()
Вот некоторые примечания:
- Для предшествующего родственного синтаксис предшествующего родственного::{XPath} —> предшествующий родственный::tagname[@attibute=’value’]
- Я рекомендую вам использовать
find_element_by xpath
(единственное число) вместоfind_elements_by_xpath
(множественное число), потому что последний возвращает список, который не имеетclick()
функции. Если вы хотите щелкнуть более одного элемента, используйтеfind_elements_by_xpath
, чтобы составить их список, а затем выполнить итерацию по ним, чтобы щелкнуть предыдущий родственный элемент каждого из них.
Например:
elems = driver.find_elements_by_xpath("//span[contains(., '18F') or contains(., '20M')]")
for elem in elems:
elem.find_element_by_xpath("./preceding-sibling::a[@class = 'link span f5 fw7 secondary']").click()