Chcę zeskrobać wszystkie dane strony zaimplementowanej przez nieskończone przewijanie. Działa następujący kod Pythona.
for i in range(100):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
Oznacza to, że za każdym razem, gdy przewijam w dół, muszę czekać 5 sekund, co generalnie wystarcza, aby strona zakończyła ładowanie nowo wygenerowanej zawartości. Ale to może nie być efektywne czasowo. Strona może zakończyć ładowanie nowej zawartości w ciągu 5 sekund. Jak mogę sprawdzić, czy strona zakończyła ładowanie nowej zawartości za każdym razem, gdy przewijam w dół? Jeśli uda mi się to wykryć, mogę ponownie przewinąć w dół, aby zobaczyć więcej treści po zakończeniu ładowania strony. Jest to bardziej efektywne czasowo.
python
selenium
execute-script
apogeum
źródło
źródło
Odpowiedzi:
webdriver
Będzie czekać na załadowanie strony domyślnie poprzez.get()
metody.Ponieważ możesz szukać konkretnego elementu, jak powiedział @ user227215, powinieneś
WebDriverWait
poczekać na element znajdujący się na twojej stronie:Użyłem go do sprawdzania alertów. Możesz użyć innych metod typu, aby znaleźć lokalizator.
EDYCJA 1:
Powinienem wspomnieć, że
webdriver
domyślnie będzie czekać na załadowanie strony. Nie czeka na załadowanie wewnątrz ramek ani na żądania AJAX. Oznacza to, że kiedy używasz.get('url')
, Twoja przeglądarka będzie czekać, aż strona zostanie całkowicie załadowana, a następnie przejdzie do następnego polecenia w kodzie. Ale kiedy wysyłasz żądanie Ajax,webdriver
nie czekaj i Twoim obowiązkiem jest odczekanie odpowiedniej ilości czasu na załadowanie strony lub jej części; więc istnieje moduł o nazwieexpected_conditions
.źródło
browser.find_element_by_id('IdOfMyElement')
powodujeNoSuchElementException
podniesienie a. Dokumentacja mówi przekazać krotki, który wygląda tak:(By.ID, 'IdOfMyElement')
. Zobacz moją odpowiedźclick()
), Odczytać tekst itp. Miałem błędne wrażenie, że spowodowało oczekiwanie, po którym wciąż trzeba było znaleźć element. Jeśli zaczekasz, a później element find, selen zostanie błędnie znaleziony, ponieważ próbuje znaleźć element, podczas gdy stare oczekiwanie nadal jest przetwarzane (mam nadzieję, że ma to sens). Podsumowując, nie musisz znajdować elementu po użyciu WebDriverWait - jest to już obiekt.Próba przekazania
find_element_by_id
do konstruktora forpresence_of_element_located
(jak pokazano w zaakceptowanej odpowiedzi ) spowodowanaNoSuchElementException
została podniesiona. Musiałem użyć składni w Fragles ' komentarzu :Jest to zgodne z przykładem w dokumentacji . Oto link do dokumentacji By .
źródło
EC.presence_of_element_located((By.XPATH, "//*[@title='Check All Q1']"))
By
obiekcie.Znajdź poniżej 3 metody:
readyState
Sprawdzanie strony readyState (niewiarygodne):
id
Porównanie nowych identyfikatorów stron ze starymi:
staleness_of
Za pomocą
staleness_of
metody:Więcej szczegółów znajdziesz na blogu Harry'ego .
źródło
self.driver.execute_script('return document.readyState;')
nie jest wiarygodne? Wygląda na to, że działa idealnie w moim przypadku użycia, który czeka na załadowanie pliku statycznego w nowej karcie (która jest otwierana za pomocą JavaScript w innej karcie zamiast .get ()).Jak wspomniano w odpowiedzi Davida Cullena , zawsze widziałem zalecenia, aby użyć linii takiej jak poniższa:
Trudno mi było znaleźć gdzieś wszystkie możliwe lokalizatory, których można użyć z
By
, więc pomyślałem, że warto podać listę tutaj. Według Web Scraping with Python autorstwa Ryana Mitchella:źródło
Z selenium / webdriver / support / wait.py
źródło
Na marginesie, zamiast przewijać w dół 100 razy, możesz sprawdzić, czy nie ma już żadnych modyfikacji w DOM (mamy w przypadku, gdy dół strony jest leniwie ładowany AJAX)
źródło
Próbowałeś
driver.implicitly_wait
. Jest to podobne do ustawienia dla sterownika, więc wywołujesz je tylko raz w sesji i zasadniczo mówi kierowcy, aby czekał przez określony czas, aż każde polecenie zostanie wykonane.Więc jeśli ustawisz czas oczekiwania na 10 sekund, wykona polecenie tak szybko, jak to możliwe, czekając 10 sekund, zanim się podda. Używałem tego w podobnych scenariuszach przewijania w dół, więc nie rozumiem, dlaczego nie zadziałaby w twoim przypadku. Mam nadzieję, że to jest pomocne.
Aby móc poprawić tę odpowiedź, muszę dodać nowy tekst. Pamiętaj, aby użyć małej litery „w” w
implicitly_wait
.źródło
Co powiesz na umieszczenie WebDriverWait w pętli While i przechwytywanie wyjątków.
źródło
Tutaj zrobiłem to za pomocą dość prostej formy:
źródło
Możesz to zrobić bardzo prosto za pomocą tej funkcji:
a jeśli chcesz coś zrobić po zakończeniu ładowania strony, możesz użyć:
źródło