Quero raspar todos os dados de uma página implementada por uma rolagem infinita. O seguinte código python funciona.
for i in range(100):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
Isso significa que toda vez que eu rolar para baixo, preciso esperar 5 segundos, o que geralmente é suficiente para que a página termine de carregar o conteúdo recém-gerado. Mas, isso pode não ser eficiente em termos de tempo. A página pode terminar de carregar o novo conteúdo em 5 segundos. Como posso detectar se a página terminou de carregar o novo conteúdo toda vez que rolar para baixo? Se eu conseguir detectar isso, posso rolar para baixo novamente para ver mais conteúdos quando souber que a página terminou de carregar. Isso é mais eficiente em termos de tempo.
python
selenium
execute-script
apogne
fonte
fonte
Respostas:
Ele
webdriver
aguardará o carregamento de uma página por padrão, através do.get()
métodoComo você pode estar procurando por algum elemento específico como @ user227215 disse, você deve
WebDriverWait
aguardar um elemento localizado em sua página:Eu o usei para verificar alertas. Você pode usar qualquer outro método de tipo para encontrar o localizador.
EDIT 1:
Devo mencionar que o
webdriver
irá esperar por uma página para carregar por padrão. Ele não espera para carregar dentro de quadros ou solicitações de ajax. Isso significa que, quando você usa.get('url')
, o navegador aguarda o carregamento completo da página e passa para o próximo comando no código. Mas quando você está postando uma solicitação ajax,webdriver
não espera e é de sua responsabilidade aguardar um período de tempo apropriado para carregar a página ou parte dela; para que haja um módulo chamadoexpected_conditions
.fonte
browser.find_element_by_id('IdOfMyElement')
faz com queNoSuchElementException
a seja levantada. A documentação diz que passar uma tupla que se parece com isso:(By.ID, 'IdOfMyElement')
. Veja minha respostaclick()
), ler texto de etc. Fiquei com a impressão errada de que ela simplesmente causou uma espera, após o qual você ainda precisava encontrar o elemento. Se você fizer uma espera, depois um elemento find, o selênio cometerá um erro porque tenta encontrar o elemento enquanto a espera antiga ainda está sendo processada (espero que faça sentido). Resumindo, você não precisa encontrar o elemento depois de usar o WebDriverWait - ele já é um objeto.Tentando passar
find_element_by_id
para o construtor parapresence_of_element_located
(como mostrado na resposta aceita ) causadoNoSuchElementException
a ser levantada. Eu tive que usar a sintaxe no comentário dos fragles :Isso corresponde ao exemplo na documentação . Aqui está um link para a documentação de Por .
fonte
EC.presence_of_element_located((By.XPATH, "//*[@title='Check All Q1']"))
By
objeto.Encontre abaixo três métodos:
readyState
Página de verificação readyState (não confiável):
id
Comparando novos IDs de página com os antigos:
staleness_of
Usando o
staleness_of
método:Para mais detalhes, consulte o blog de Harry .
fonte
self.driver.execute_script('return document.readyState;')
não é confiável? Parece funcionar perfeitamente no meu caso de uso, que aguarda o carregamento de um arquivo estático em uma nova guia (que é aberta via javascript em outra guia, em vez de .get ()).Como mencionado na resposta de David Cullen , sempre vi recomendações para usar uma linha como a seguinte:
Foi difícil para mim encontrar em algum lugar todos os possíveis localizadores que podem ser usados com o
By
, então achei que seria útil fornecer a lista aqui. De acordo com Web Scraping with Python, de Ryan Mitchell:fonte
De selenium / webdriver / support / wait.py
fonte
Em uma nota lateral, em vez de rolar para baixo 100 vezes, você pode verificar se não há mais modificações no DOM (no caso da parte inferior da página estar com o carregamento lento do AJAX)
fonte
Você já tentou
driver.implicitly_wait
? É como uma configuração para o driver, então você a chama apenas uma vez na sessão e basicamente diz ao driver que aguarde o tempo determinado até que cada comando possa ser executado.Portanto, se você definir um tempo de espera de 10 segundos, ele executará o comando o mais rápido possível, aguardando 10 segundos antes de desistir. Eu usei isso em cenários de rolagem para baixo semelhantes, então não vejo por que não funcionaria no seu caso. Espero que isso seja útil.
Para poder corrigir esta resposta, tenho que adicionar um novo texto. Certifique-se de usar uma letra minúscula 'w'
implicitly_wait
.fonte
Que tal colocar o WebDriverWait no loop While e capturar as exceções.
fonte
Aqui eu fiz isso usando um formulário bastante simples:
fonte
Você pode fazer isso de maneira muito simples com esta função:
e quando você quiser fazer algo depois que o carregamento da página estiver concluído, você pode usar:
fonte