Pobierz źródło HTML WebElement w Selenium WebDriver za pomocą Pythona

475

Korzystam z powiązań Python do uruchamiania Selenium WebDriver:

from selenium import webdriver
wd = webdriver.Firefox()

Wiem, że mogę pobrać taki element sieciowy:

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

I wiem, że mogę uzyskać pełne źródło strony dzięki ...

wd.page_source

Ale czy w ogóle można uzyskać „źródło elementu”?

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

Dokumenty selenium webdriver dla Pythona w zasadzie nie istnieją i nie widzę w kodzie nic, co zdawałoby się włączać tę funkcjonalność.

Masz jakieś przemyślenia na temat najlepszego sposobu uzyskania dostępu do HTML elementu (i jego dzieci)?

Chris W.
źródło
8
Możesz także po prostu przeanalizować wszystko za wd.page_sourcepomocą beautifulsoup
eLRuLL

Odpowiedzi:

747

Możesz odczytać innerHTMLatrybut, aby uzyskać źródło treści elementu lub outerHTMLźródło z bieżącym elementem.

Pyton:

element.get_attribute('innerHTML')

Jawa:

elem.getAttribute("innerHTML");

DO#:

element.GetAttribute("innerHTML");

Rubin:

element.attribute("innerHTML")

JS:

element.getAttribute('innerHTML');

PHP:

$element->getAttribute('innerHTML');

Testowany i współpracuje z ChromeDriver.

Nerijus
źródło
9
innerHTML nie jest atrybutem DOM. Tak więc powyższa odpowiedź nie zadziała. innerHTML to wartość javascript. Wykonanie powyższej czynności zwróci wartość zero. Odpowiedź nilesha jest właściwą odpowiedzią.
bibstha
6
Działa to dla mnie świetnie i jest znacznie bardziej eleganckie niż zaakceptowana odpowiedź. Używam Selenium 2.24.1.
Ryan Shillington,
22
Chociaż innerHTML nie jest atrybutem DOM, jest dobrze obsługiwany przez wszystkie główne przeglądarki ( quirksmode.org/dom/w3c_html.html ). Działa mi również dobrze.
CuongHuyTo
3
+1 To wydaje się działać również w rubinie. Mam wrażenie, że getAttributemetoda (lub równoważna w innych językach) po prostu wywołuje metodę js o nazwie arg. Jednak dokumentacja tego wyraźnie nie mówi, więc rozwiązaniem Nilesha powinno być rozwiązanie awaryjne.
Kelvin,
23
To się nie udaje HtmlUnitDriver. Działa na ChromeDriver, FirefoxDriver, InternetExplorerDriver(IE10) i PhantomJSDriver(nie testowałem inne).
acdcjunior
91

Tak naprawdę nie ma prostego sposobu uzyskania kodu źródłowego HTML webelement. Będziesz musiał użyć JS. Nie jestem zbyt pewny co do powiązań Pythona, ale możesz to łatwo zrobić w Javie. Jestem pewien, że JavascriptExecutorw Pythonie musi być coś podobnego do klasy.

 WebElement element = driver.findElement(By.id("foo"));
 String contents = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", element); 
Nilesh
źródło
1
Zasadniczo tak właśnie skończyłem, choć z odpowiednikiem w języku Python.
Chris W.
8
Myślę, że odpowiedź poniżej przy użyciu elementu.getAttribute („innerHTML”) jest o wiele łatwiejsza do odczytania. Nie rozumiem, dlaczego ludzie to głosują.
Ryan Shillington,
1
W ogóle nie trzeba wywoływać javascript. W Pythonie wystarczy użyć element.get_attribute ('innerHTML')
Anthon
6
@Anthon innerHTMLnie jest atrybutem DOM. Kiedy odpowiedziałem na to pytanie w 2011 roku, nie działało to dla mnie, wygląda na to, że teraz niektóre przeglądarki go obsługują. Jeśli to działa, to używanie innerHTMLjest czystsze. Jednak nie ma gwarancji, że będzie działać na wszystkich przeglądarkach.
nilesh
2
Najwyraźniej jest to jedyny sposób na uzyskanie innerHTML podczas korzystania z RemoteWebDriver
Illidan
73

Na pewno możemy pobrać cały kod źródłowy HTML za pomocą tego skryptu poniżej w Selenium Python:

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

Jeśli chcesz zapisać go do pliku:

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

Sugeruję zapisanie do pliku, ponieważ kod źródłowy jest bardzo długi.

znak
źródło
2
Czy mogę ustawić opóźnienie i uzyskać najnowsze źródło? Istnieje zawartość dynamiczna ładowana za pomocą javascript.
CodeGuru
Czy to działa, nawet jeśli strona nie jest w pełni załadowana? Ponadto, czy jest jakiś sposób, aby ustawić opóźnienie takie jak wspomniane @FlyingAtom?
TheRookierLearner
13

W Ruby, używając selenium-webdriver (2.32.1), istnieje page_sourcemetoda, która zawiera całe źródło strony.

John Alberts
źródło
5

Korzystanie z metody atrybutu jest w rzeczywistości łatwiejsze i bardziej bezpośrednie.

Używając Ruby z klejnotami Selenium i PageObject, aby powiązać klasę z określonym elementem, linia byłaby element.attribute(Class) .

Ta sama koncepcja obowiązuje, jeśli chcesz powiązać inne atrybuty z elementem. Na przykład, jeśli chciałem ciąg pierwiastka element.attribute(String).

Tiffany G.
źródło
4

Wygląda na przestarzałe, ale niech i tak tu będzie. Właściwy sposób to zrobić w twoim przypadku:

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

lub

html = elem.get_attribute('innerHTML')

Oba działają dla mnie (selenium-server-standalone-2.35.0)

nefski
źródło
3

Java z Selenium 2.53.0

driver.getPageSource();
WltrRpo
źródło
nie o to pytano
Corey Goldberg
W zależności od serwera WWW getPageSourcemetoda może nie zwrócić faktycznego źródła strony (tj. Z możliwymi zmianami w javascript). Zwróconym źródłem może być surowe źródło wysłane przez serwer. Dokument webdriver musi zostać sprawdzony, aby zapewnić ten punkt.
Stephan
2

Mam nadzieję, że to może pomóc: http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html

Oto opis metody Java:

java.lang.String    getText() 

Ale niestety nie jest dostępny w Pythonie. Możesz więc przetłumaczyć nazwy metod na Python z Javy i wypróbować inną logikę przy użyciu obecnych metod bez pobierania całego źródła strony ...

Na przykład

 my_id = elem[0].get_attribute('my-id')
oleksii.burdin
źródło
6
Python faktycznie ma odpowiednik „gettext” (myślę, że jest to po prostu atrybut „text”?), Ale tak naprawdę po prostu zwraca „tekst jawny” między znacznikami HTML i tak naprawdę nie zwraca pełnego źródła HTML.
Chris W.
2
Zwraca to również zwykły tekst (nie HTML) w Javie.
Ryan Shillington,
musisz odwołać się do niego tak, jak powiedziałeś elem [0], w przeciwnym razie to nie zadziała
HelloW
2

To działa dla mnie bezproblemowo.

element.get_attribute('innerHTML')
Jitendra Pisal
źródło
1

InnerHTML zwróci element wewnątrz wybranego elementu, a outerHTML zwróci wewnątrz HTML wraz z wybranym elementem

Przykład: - Załóżmy teraz, że Twój element jest jak poniżej

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

element innerHTML Wyjście

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

element outerHTML Wyjście

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

Przykład na żywo: -

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

Poniżej znajdziesz składnię, która wymaga różnych powiązań. Zmień innerHTMLnaouterHTML zgodnie z wymaganiami.

Pyton:

element.get_attribute('innerHTML')

Jawa:

elem.getAttribute("innerHTML");

Jeśli chcesz HTML całej strony, użyj poniższego kodu: -

driver.getPageSource();
Shubham Jain
źródło
0
WebElement element = driver.findElement(By.id("foo"));
String contents = (String)((JavascriptExecutor)driver).executeScript("return      arguments[0].innerHTML;", element); 

Ten kod naprawdę działa również w celu pobrania JavaScript ze źródła!

Ilya
źródło
0

A w teście selenu PHPUnit wygląda to tak:

$text = $this->byCssSelector('.some-class-nmae')->attribute('innerHTML');
Zorgijs
źródło
0

Jeśli interesuje Cię rozwiązanie do zdalnego sterowania w Pythonie, oto jak uzyskać innerHTML:

innerHTML = sel.get_eval("window.document.getElementById('prodid').innerHTML")
StanleyD
źródło
Dzięki za pomoc, wykorzystałem to. Uważam też, że innerHTML = {solenium selector code}.textprace są takie same.
Shane
0

Preferowaną metodą uzyskania renderowanego HTML jest:

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

Jednak powyższa metoda usuwa wszystkie tagi (tak również tagi zagnieżdżone) i zwraca tylko treść tekstową. Jeśli chcesz uzyskać znaczniki HTML, skorzystaj z poniższej metody.

print body_html.getAttribute("innerHTML")
Zardzewiały
źródło
1
Możesz także użyć driver.find_element_by_tag („body”), aby przejść do treści treści strony.
Rusty