Отримайте HTML-джерело WebElement у Selenium WebDriver за допомогою Python


475

Я використовую прив'язки Python для запуску Selenium WebDriver:

from selenium import webdriver
wd = webdriver.Firefox()

Я знаю, що можу схопити таке, як:

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

І я знаю, що можу отримати повне джерело сторінки за допомогою ...

wd.page_source

Але чи все-таки можна отримати "джерело елементів"?

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

Документи Selenium webdriver для Python в основному відсутні, і я не бачу нічого в коді, який, здається, дозволяє цю функціональність.

Будь-які думки щодо найкращого способу доступу до HTML елемента (та його дітей)?


8
Ви також можете просто розібратися wd.page_sourceз красивим
набором

Відповіді:


747

Ви можете прочитати innerHTMLатрибут, щоб отримати джерело вмісту елемента або outerHTMLдля джерела з поточним елементом.

Пітон:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

C #:

element.GetAttribute("innerHTML");

Ruby:

element.attribute("innerHTML")

JS:

element.getAttribute('innerHTML');

PHP:

$element->getAttribute('innerHTML');

Тестується і працює з ChromeDriver.


9
innerHTML - атрибут не DOM. Отже, відповідь вище не працює. innerHTML - це значення JavaScript в JavaScript. Якщо робити вище, нуль повернеться. Відповідь Нілеша - це правильна відповідь.
bibstha

6
Це чудово працює для мене і набагато елегантніше, ніж прийнята відповідь. Я використовую Селен 2.24.1.
Райан Шиллінгтон

22
Хоча innerHTML не є атрибутом DOM, він добре підтримується всіма основними браузерами ( quirksmode.org/dom/w3c_html.html ). Це добре працює і для мене.
CuongHuyTo

3
+1 Це, здається, працює і в рубіні. У мене є відчуття, що getAttributeметод (або еквівалент іншими мовами) просто викликає метод js, ім'я якого - arg. Однак документація цього прямо не говорить, тому рішення Nilesh має бути резервним.
Кельвін

23
Це не вдається HtmlUnitDriver. Працює на ChromeDriver, FirefoxDriver, InternetExplorerDriver(IE10) і PhantomJSDriver(я не перевіряв інші).
acdcjunior

91

Насправді не існує прямолінійного способу отримання вихідного коду html webelement. Вам доведеться використовувати JS. Я не надто впевнений у прив'язках python, але ви можете легко зробити так, як у Java. Я впевнений, що має бути щось подібнеJavascriptExecutor в Python класу.

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

1
Це, по суті, те, що я в кінцевому підсумку робив, хоча і з еквівалентом Python.
Кріс В.

8
Я думаю, що відповідь нижче, використовуючи element.getAttribute ("innerHTML"), читати набагато простіше. Я не розумію, чому люди голосують за це.
Райан Шиллінгтон

1
Не потрібно взагалі викликати javascript. У Python просто використовуйте element.get_attribute ('innerHTML')
Антон

6
@Anthon innerHTMLне є атрибутом DOM. Коли я відповів на це запитання в 2011 році, це не спрацювало для мене, схоже, зараз деякі браузери його підтримують. Якщо це працює для вас, тоді використання innerHTMLчистіше. Однак немає гарантії, що він буде працювати у всіх браузерах.
nilesh

2
Мабуть, це єдиний спосіб отримати внутрішній HTMLML під час використання RemoteWebDriver
Illidan

73

Впевнені, що ми можемо отримати весь вихідний код HTML за допомогою цього скрипту нижче в Selenium Python:

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

Якщо ви хочете зберегти його у файл:

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

Я пропоную зберегти файл, оскільки вихідний код дуже довгий.


2
Чи можу я встановити затримку і отримати останнє джерело? Є динамічний вміст, завантажений за допомогою JavaScript.
CodeGuru

Чи працює це, навіть якщо сторінка не завантажена повністю? Крім того, чи можна встановити затримку на зразок згаданого @FlyingAtom?
TheRookierLearner

13

У Ruby, використовуючи селен-webdriver (2.32.1), існує page_sourceметод, який містить все джерело сторінки.


5

Використання методу атрибутів насправді простіше і простіше.

Використовуючи Ruby з дорогоцінними каменями Selenium і PageObject, щоб отримати клас, пов'язаний з певним елементом, рядок буде element.attribute(Class) .

Ця ж концепція застосовується, якщо ви хотіли, щоб інші атрибути були прив'язані до елемента. Наприклад, якщо я хотів рядок елемента, element.attribute(String).


4

Виглядає застарілим, але нехай це все одно буде тут. Правильний спосіб зробити це у вашому випадку:

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

або

html = elem.get_attribute('innerHTML')

Обидва працюють для мене (селен-сервер-автономний-2.35.0)


3

Java з селеном 2.53.0

driver.getPageSource();

це не те, про що задавали питання
Корі Голдберг,

Залежно від webdriver, getPageSourceметод може не повернути фактичне джерело сторінки (тобто з можливими змінами javascript). Повернене джерело може бути вихідним джерелом, надісланим сервером. Щоб забезпечити цю точку, слід перевірити документ веб-драйвера.
Стефан

2

Я сподіваюся, що це може допомогти: http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html

Тут описаний метод Java:

java.lang.String    getText() 

Але, на жаль, це не доступно в Python. Таким чином, ви можете перекласти імена методів на Python з Java та спробувати іншу логіку, використовуючи наявні методи, не отримуючи джерело всієї сторінки ...

Напр

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

6
У Python насправді є еквівалент "gettext" (я думаю, що це лише атрибут "text"?), Але це насправді просто повертає "непростий текст" між тегами HTML і фактично не повертає повне джерело HTML.
Кріс В.

2
Це повертає лише звичайний текст (не html) на Java.
Райан Шиллінгтон

ви повинні посилатися на нього так, як ви сказали, елем [0] в іншому випадку він не працює
HelloW


1

InnerHTML поверне елемент всередині вибраного елемента, а зовнішнійHTML повернеться всередині HTML разом із вибраним вами елементом

Приклад: - Тепер припустимо, що ваш Елемент є нижче

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

Вхідний елемент внутрішньогоHTML

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

зовнішній HTML-елемент

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

Живий приклад: -

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

Нижче ви знайдете синтаксис, який вимагається відповідно до різних прив'язок. Змініть innerHTMLна, outerHTMLяк потрібно.

Пітон:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

Якщо ви хочете використовувати цілу сторінку HTML, використовуйте нижче код: -

driver.getPageSource();

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

Цей код дійсно працює і для отримання JavaScript від джерела!


0

А в тесті на селен PHPUnit це так:

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

0

Якщо вас цікавить рішення для віддаленого керування в Python, ось як отримати внутрішній HTML:

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

Дякую за допомогу, я використав це. Я також знаходжу innerHTML = {solenium selector code}.textтвори саме так.
Шейн

0

Метод отримання виведеного HTML, який я віддаю перевагу, наступний:

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

Однак вищевказаний метод видаляє всі теги (так, також вкладені теги) і повертає лише текстовий вміст. Якщо ви зацікавлені в тому, щоб отримати розмітку HTML, скористайтеся наведеним нижче методом.

print body_html.getAttribute("innerHTML")

1
Ви також можете використовувати driver.find_element_by_tag ("body"), щоб досягти вмісту сторінки сторінки.
Іржавий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.