Obter fonte HTML de WebElement no Selenium WebDriver usando Python


476

Estou usando as ligações Python para executar o Selenium WebDriver:

from selenium import webdriver
wd = webdriver.Firefox()

Eu sei que posso pegar um elemento da Web assim:

elem = wd.find_element_by_css_selector('#my-id')

E eu sei que posso obter a fonte da página inteira com ...

wd.page_source

Mas existe uma maneira de obter a "fonte do elemento"?

elem.source   # <-- returns the HTML as a string

Os documentos do selenium webdriver para Python são basicamente inexistentes e não vejo nada no código que pareça ativar essa funcionalidade.

Alguma idéia sobre a melhor maneira de acessar o HTML de um elemento (e seus filhos)?


8
Você também pode apenas analisar todo o wd.page_sourcecom BeautifulSoup
eLRuLL

Respostas:


748

Você pode ler o innerHTMLatributo para obter a origem do conteúdo do elemento ou outerHTMLa origem com o elemento atual.

Pitão:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

C #:

element.GetAttribute("innerHTML");

Rubi:

element.attribute("innerHTML")

JS:

element.getAttribute('innerHTML');

PHP:

$element->getAttribute('innerHTML');

Testado e trabalha com o ChromeDriver.


9
innerHTML não é um atributo DOM. Portanto, a resposta acima não funcionaria. innerHTML é um valor javascript javascript. O procedimento acima retornaria nulo. A resposta de nilesh é a resposta correta.
bibstha

6
Isso funciona muito bem para mim e é muito mais elegante do que a resposta aceita. Estou usando o Selenium 2.24.1.
Ryan Shillington

22
Embora innerHTML não seja um atributo DOM, ele é bem suportado por todos os principais navegadores ( quirksmode.org/dom/w3c_html.html ). Isso também funciona bem para mim.
CuongHuyTo

3
+1 Isso parece funcionar em ruby ​​também. Tenho a sensação de que o getAttributemétodo (ou equivalente em outros idiomas) apenas chama o método js cujo nome é arg. No entanto, a documentação não diz isso explicitamente, portanto a solução da nilesh deve ser um substituto.
Kelvin

23
Isso falha para HtmlUnitDriver. Trabalha para ChromeDriver, FirefoxDriver, InternetExplorerDriver(IE10) e PhantomJSDriver(eu não testei outras).
Acdcjunior

91

Não existe realmente uma maneira direta de obter o código fonte html de a webelement. Você terá que usar JS. Não tenho muita certeza sobre ligações python, mas você pode fazer isso facilmente em Java. Estou certo de que deve haver algo semelhante à JavascriptExecutorclasse em Python.

 WebElement element = driver.findElement(By.id("foo"));
 String contents = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", element); 

1
Isso é essencialmente o que acabei fazendo, embora com o equivalente em Python.
7897 Chris W.

8
Eu acho que a resposta abaixo, usando element.getAttribute ("innerHTML") é muito mais fácil de ler. Não entendo por que as pessoas estão votando contra.
Ryan Shillington

1
Não é necessário chamar o javascript. No Python, basta usar element.get_attribute ('innerHTML')
Anthon

6
@Anthon innerHTMLnão é um atributo DOM. Quando eu respondi a essa pergunta em 2011, ela não funcionou para mim, parece que agora alguns navegadores a suportam. Se funcionar para você, o uso innerHTMLé mais limpo. No entanto, não há garantia de que funcione em todos os navegadores.
Nilesh 30/04

2
Aparentemente, esta é a única maneira de obter innerHTML ao usar RemoteWebDriver
Illidan

73

Certamente, podemos obter todo o código-fonte HTML com este script abaixo no Selenium Python:

elem = driver.find_element_by_xpath("//*")
source_code = elem.get_attribute("outerHTML")

Se você deseja salvá-lo em um arquivo:

with open('c:/html_source_code.html', 'w') as f:
    f.write(source_code.encode('utf-8'))

Sugiro salvar em um arquivo porque o código-fonte é muito, muito longo.


2
Posso definir um atraso e obter a fonte mais recente? Existem conteúdos dinâmicos carregados usando javascript.
CodeGuru

Isso funciona mesmo que a página não esteja totalmente carregada? Além disso, existe alguma maneira de definir um atraso como o @FlyingAtom mencionado?
TheRookierLearner

13

No Ruby, usando o selenium-webdriver (2.32.1), existe um page_sourcemétodo que contém toda a fonte da página.


5

Usar o método de atributo é, de fato, mais fácil e mais direto.

Usando Ruby com as gemas Selenium e PageObject, para obter a classe associada a um determinado elemento, a linha seria element.attribute(Class).

O mesmo conceito se aplica se você deseja vincular outros atributos ao elemento. Por exemplo, se eu quisesse a String de um elemento element.attribute(String),.


4

Parece desatualizado, mas deixe estar aqui de qualquer maneira. A maneira correta de fazer isso no seu caso:

elem = wd.find_element_by_css_selector('#my-id')
html = wd.execute_script("return arguments[0].innerHTML;", elem)

ou

html = elem.get_attribute('innerHTML')

Ambos estão trabalhando para mim (selenium-server-standalone-2.35.0)


3

Java com Selenium 2.53.0

driver.getPageSource();

não é isso que a pergunta é feita
Corey Goldberg

Dependendo do driver da web, o getPageSourcemétodo pode não retornar a fonte da página real (por exemplo, com possíveis alterações de javascript). A fonte retornada pode ser a fonte bruta enviada pelo servidor. O documento do driver da web deve ser verificado para garantir esse ponto.
25717 Stephan

2

Espero que isso possa ajudar: http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html

Aqui está descrito o método Java:

java.lang.String    getText() 

Mas, infelizmente, não está disponível no Python. Assim, você pode traduzir os nomes dos métodos para Python a partir de Java e tentar outra lógica usando os métodos atuais sem obter toda a fonte da página ...

Por exemplo

 my_id = elem[0].get_attribute('my-id')

6
O Python, na verdade, tem um equivalente "gettext" (acho que é apenas o atributo "text"?), Mas isso na verdade apenas retorna o "texto simples" entre as tags HTML e não retorna a fonte HTML completa.
Chris W.

2
Isso retorna apenas o texto sem formatação (não o html) em Java também.
21711 Ryan Shillington

você deve fazer referência a ela como você disse elem [0] de outra forma ele não funciona
Hellow


1

InnerHTML retornará elemento dentro do elemento selecionado e outerHTML retornará dentro de HTML junto com o elemento que você selecionou

Exemplo: - Agora, suponha que seu elemento seja como abaixo

<tr id="myRow"><td>A</td><td>B</td></tr>

elemento innerHTML Saída

<td>A</td><td>B</td>

elemento outerHTML Saída

<tr id="myRow"><td>A</td><td>B</td></tr>

Exemplo ao vivo: -

http://www.java2s.com/Tutorials/JavascriptDemo/f/find_out_the_difference_between_innerhtml_and_outerhtml_in_javascript_example.htm

Abaixo, você encontrará a sintaxe necessária conforme a ligação diferente. Mude innerHTMLparaouterHTML conforme necessário.

Pitão:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

Se você deseja HTML de página inteira, use o código abaixo: -

driver.getPageSource();

0
WebElement element = driver.findElement(By.id("foo"));
String contents = (String)((JavascriptExecutor)driver).executeScript("return      arguments[0].innerHTML;", element); 

Esse código realmente funciona para obter JavaScript da fonte também!


0

E no teste de selênio do PHPUnit é assim:

$text = $this->byCssSelector('.some-class-nmae')->attribute('innerHTML');

0

Se você está interessado em uma solução para Controle Remoto em Python, veja como obter o innerHTML:

innerHTML = sel.get_eval("window.document.getElementById('prodid').innerHTML")

Obrigado pela ajuda, eu usei isso. Também acho que innerHTML = {solenium selector code}.textfunciona da mesma forma.
Shane

0

O método para obter o HTML renderizado que eu prefiro é o seguinte:

driver.get("http://www.google.com")
body_html = driver.find_element_by_xpath("/html/body")
print body_html.text

No entanto, o método acima remove todas as tags (sim, também as tags aninhadas) e retorna apenas o conteúdo do texto. Se você também estiver interessado em obter a marcação HTML, use o método abaixo.

print body_html.getAttribute("innerHTML")

1
Você também pode usar o driver.find_element_by_tag ("corpo") para alcançar o conteúdo do corpo da página.
Rusty
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.