python selen kliknij przycisk

88

Jestem całkiem nowy w Pythonie selen i próbuję kliknąć przycisk, który ma następującą strukturę html:

<div class="b_div">

    <div class="button c_button s_button" onclick="submitForm('mTF')">
        <input class="very_small" type="button"></input>
        <div class="s_image"></div>
        <span>
           Search
        </span>
    </div>

    <div class="button c_button s_button" onclick="submitForm('rMTF')" style="margin-bottom: 30px;">
        <input class="v_small" type="button"></input>
        <span>
              Reset
        </span>
   </div>

</div>

Chciałbym móc klikać oba powyższe przyciski Searchi Reset(oczywiście indywidualnie).

Próbowałem kilku rzeczy, na przykład:

driver.find_element_by_css_selector('.button .c_button .s_button').click()

lub,

driver.find_element_by_name('s_image').click()

lub,

driver.find_element_by_class_name('s_image').click()

ale wydaje mi się, że zawsze kończy się NoSuchElementExceptionna przykład:

selenium.common.exceptions.NoSuchElementException: Message: u'Unable to locate element: {"method":"name","selector":"s_image"}' ;

Zastanawiam się, czy mogę w jakiś sposób użyć atrybutów onclick HTML, aby uzyskać kliknięcie selenu?

Wszelkie myśli, które mogą skierować mnie we właściwym kierunku, byłyby świetne. Dzięki.

AJW
źródło

Odpowiedzi:

17

W przypadku Pythona użyj rozszerzenia

from selenium.webdriver import ActionChains

i

ActionChains(browser).click(element).perform()
AshishGalagali
źródło
Co to jest element?
rosefun
106

Usuń spację między klasami w selektorze css:

driver.find_element_by_css_selector('.button .c_button .s_button').click()
#                                           ^         ^

=>

driver.find_element_by_css_selector('.button.c_button.s_button').click()
falsetru
źródło
1
Wypróbowałem to, co zasugerowałeś. Otrzymuję ten sam NoSuchElementExceptionbłąd!
AJW
2
@AJW, spróbuj print(driver.page_source)i sprawdź, czy html faktycznie zawiera element.
falsetru
Dzięki. Zrobiłem print(driver.page_source)i stwierdziłem, że został nazwany inaczej. Dziwne. Klika teraz, kiedy usunąłem spacje i zmieniłem nazwę. W dalszej kolejności: jak widać, nawet przycisk resetowania i przycisk wyszukiwania mają to samo class: jak rozróżnić przyciski wyszukiwania i resetowania podczas klikania w tym przypadku?
AJW
1
@AJW, How aobut using xpath:driver.find_element_by_xpath('.//div[@class="button c_button s_button"][contains(., "Search")]')
falsetru
1
@MortezaLSC, jeśli masz na myśli, że jest to możliwe w systemie, w którym nie ma GUI, jest to możliwe. Używaj bezgłowych przeglądarek. Na przykład PhantomJS.
falsetru
31

Spróbuj tego:

pobierz firefox, dodaj wtyczki "firebug" i "firepath"; po ich zainstalowaniu wejdź na swoją stronę, uruchom firebuga i znajdź xpath elementu, jest on unikalny na stronie, więc nie możesz popełnić błędu.

Widzieć zdjęcie: instrukcja

browser.find_element_by_xpath('just copy and paste the Xpath').click()

Carlo 1585
źródło
5
Bardzo dziękuję za tak niesamowity lifehack. Zaoszczędziło to wiele godzin
Hero Guy
czy to nie działa na komputerze Mac bc zarówno firebug, jak i ścieżka ognia nie są wyświetlane jako dodatki
Bob
Czasami nie jest to problem z systemem operacyjnym, ale wersją Firefoksa, ostatnia wersja Firefoksa ma problem z FirePath, używam Firefoksa 55.0.3
Carlo 1585
2
Możesz znaleźć ten element w przeglądarce Firefox za pomocą: Narzędzia-> Projektant stron internetowych-> Inspektor; kliknij przycisk w GUI, w części inspektora, kliknij prawym przyciskiem myszy odpowiedni kod-> kopiuj i wybierz: Selektor CSS / Ścieżka CSS / Ścieżka X ...
Nir
4

Miałem ten sam problem używając Phantomjsa jako przeglądarki, więc rozwiązałem go w następujący sposób:

driver.find_element_by_css_selector('div.button.c_button.s_button').click()

Zasadniczo dodałem nazwę znacznika DIV do cytatu.

CosimoCD
źródło
3

otwórz stronę internetową https://adviserinfo.sec.gov/compilation i kliknij przycisk, aby pobrać plik, a nawet chcę zamknąć wyskakujące okienko, jeśli używa selenu w języku Python

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
from selenium.webdriver.chrome.options import Options 

#For Mac - If you use windows change the chromedriver location
chrome_path = '/usr/local/bin/chromedriver'
driver = webdriver.Chrome(chrome_path)

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--disable-popup-blocking")

driver.maximize_window()
driver.get("https://adviserinfo.sec.gov/compilation")

# driver.get("https://adviserinfo.sec.gov/")
# tabName = driver.find_element_by_link_text("Investment Adviser Data")
# tabName.click()

time.sleep(3)

# report1 = driver.find_element_by_xpath("//div[@class='compilation-container ng-scope layout-column flex']//div[1]//div[1]//div[1]//div[2]//button[1]")

report1 = driver.find_element_by_xpath("//button[@analytics-label='IAPD - SEC Investment Adviser Report (GZIP)']")

# print(report1)
report1.click()

time.sleep(5)

driver.close()
Rajiv Singh
źródło
2

Poniższy proces debugowania pomógł mi rozwiązać podobny problem.

with open("output_init.txt", "w") as text_file:
    text_file.write(driver.page_source.encode('ascii','ignore'))


xpath1 = "the xpath of the link you want to click on"
destination_page_link = driver.find_element_by_xpath(xpath1)
destination_page_link.click()


with open("output_dest.txt", "w") as text_file:
    text_file.write(driver.page_source.encode('ascii','ignore'))

Powinieneś wtedy mieć dwa pliki tekstowe z początkową stroną, na której byłeś („output_init.txt”) i stroną, na którą zostałeś przekierowany po kliknięciu przycisku („output_dest.txt”). Jeśli są takie same, to tak, twój kod nie działa. Jeśli tak nie jest, kod zadziałał, ale masz inny problem. Wydawało mi się, że problem polegał na tym, że niezbędny skrypt javascript, który przekształcił zawartość w celu utworzenia mojego zaczepu, nie został jeszcze wykonany.

Twoje opcje, jak ja to widzę:

  1. Poproś sterownik o wykonanie kodu javascript, a następnie wywołanie kodu elementu find. Poszukaj bardziej szczegółowych odpowiedzi na ten temat w przepełnieniu stosu, ponieważ nie stosowałem tego podejścia.
  2. Po prostu znajdź porównywalny punkt zaczepienia w „output_dest.txt”, który da ten sam wynik, co zrobiłem.
  3. Spróbuj trochę poczekać, zanim cokolwiek klikniesz:

xpath2 = "twoja ścieżka xpath, którą zamierzasz kliknąć"

WebDriverWait (sterownik, limit czasu = 5) .until (lambda x: x.find_element_by_xpath (xpath2))

Podejście xpath niekoniecznie jest lepsze, po prostu je wolę, możesz także użyć metody selektora.

Tanel
źródło