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)?


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.


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); 

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.


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.


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).


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)


3

Java z Selenium 2.53.0

driver.getPageSource();

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')

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


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();

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!


0

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

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

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")

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")

1
Możesz także użyć driver.find_element_by_tag („body”), aby przejść do treści treści strony.
Rusty
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.