Nhận nguồn HTML của WebEuity trong Selenium WebDriver bằng Python


476

Tôi đang sử dụng các liên kết Python để chạy Selenium WebDriver:

from selenium import webdriver
wd = webdriver.Firefox()

Tôi biết tôi có thể lấy một webelement như vậy:

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

Và tôi biết tôi có thể lấy nguồn trang đầy đủ với ...

wd.page_source

Nhưng có cách nào để có được "nguồn phần tử" không?

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

Các tài liệu weben selenium cho Python về cơ bản là không tồn tại và tôi không thấy bất cứ điều gì trong mã dường như cho phép chức năng đó.

Bạn có suy nghĩ nào về cách tốt nhất để truy cập HTML của một yếu tố (và con của nó) không?


8
Bạn cũng có thể phân tích cú pháp tất cả wd.page_sourcevới beautifulsoup
eLRuLL

Câu trả lời:


748

Bạn có thể đọc innerHTMLthuộc tính để lấy nguồn nội dung của phần tử hoặc outerHTMLcho nguồn có phần tử hiện tại.

Con trăn

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

C #:

element.GetAttribute("innerHTML");

Ruby:

element.attribute("innerHTML")

JS:

element.getAttribute('innerHTML');

PHP:

$element->getAttribute('innerHTML');

Đã thử nghiệm và làm việc với ChromeDriver.


9
InternalHTML là một thuộc tính không DOM. Vì vậy, câu trả lời trên sẽ không hoạt động. InternalHTML là một giá trị javascript javascript. Làm ở trên sẽ trả về null. Câu trả lời của nilesh là câu trả lời thích hợp.
bibstha

6
Điều này làm việc tuyệt vời cho tôi, và thanh lịch hơn nhiều so với câu trả lời được chấp nhận. Tôi đang sử dụng Selenium 2.24.1.
Ryan Shillington

22
Mặc dù InternalHTML không phải là một thuộc tính DOM, nhưng nó được hỗ trợ tốt bởi tất cả các trình duyệt chính ( quirksmode.org/dom/w3c_html.html ). Nó cũng hoạt động tốt cho tôi.
CườngHuyTo

3
+1 Điều này dường như cũng hoạt động trong ruby. Tôi có cảm giác rằng getAttributephương thức (hoặc tương đương trong các ngôn ngữ khác) chỉ gọi phương thức js có tên là arg. Tuy nhiên, tài liệu không nói rõ điều này, vì vậy giải pháp của nilesh nên là một dự phòng.
Kelvin

23
Điều này thất bại cho HtmlUnitDriver. Làm việc cho ChromeDriver, FirefoxDriver, InternetExplorerDriver(IE10) và PhantomJSDriver(tôi đã không kiểm tra những người khác).
acdcjunior

91

Thực sự không có cách nào dễ dàng để lấy mã nguồn html của a webelement. Bạn sẽ phải sử dụng JS. Tôi không quá chắc chắn về các ràng buộc python nhưng bạn có thể dễ dàng làm như thế này trong Java. Tôi chắc chắn phải có một cái gì đó tương tự như JavascriptExecutorlớp trong Python.

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

1
Đây thực chất là những gì tôi đã làm, mặc dù tương đương với Python.
Chris W.

8
Tôi nghĩ rằng câu trả lời dưới đây, sử dụng Element.getAttribution ("InternalHTML") dễ đọc hơn rất nhiều. Tôi không hiểu tại sao mọi người bỏ phiếu xuống.
Ryan Shillington

1
Không cần phải gọi javascript cả. Trong Python, chỉ cần sử dụng Element.get_attribution ('InternalHTML')
Anthon

6
@Anthon innerHTMLkhông phải là một thuộc tính DOM. Khi tôi trả lời câu hỏi này vào năm 2011, nó không hoạt động với tôi, có vẻ như bây giờ một số trình duyệt đang hỗ trợ nó. Nếu nó làm việc cho bạn thì sử dụng innerHTMLlà sạch hơn. Tuy nhiên không có gì đảm bảo nó sẽ hoạt động trên tất cả các trình duyệt.
nilesh

2
Rõ ràng, đây là cách duy nhất để có được InternalHTML trong khi sử dụng RemoteWebDriver
Illidan

73

Chắc chắn chúng ta có thể nhận được tất cả mã nguồn HTML với tập lệnh này bên dưới trong Selenium Python:

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

Nếu bạn muốn lưu nó vào tập tin:

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

Tôi đề nghị lưu vào một tệp vì mã nguồn rất rất dài.


2
Tôi có thể đặt độ trễ và nhận nguồn mới nhất không? Có nội dung động được tải bằng javascript.
CodeGuru

Điều này có hoạt động ngay cả khi trang không được tải đầy đủ? Ngoài ra, có cách nào để đặt độ trễ như @FellingAtom đã đề cập không?
TheRookierLearner

13

Trong Ruby, sử dụng selenium-webdo (2.32.1), có một page_sourcephương pháp chứa toàn bộ nguồn trang.


5

Trên thực tế, sử dụng phương pháp thuộc tính là dễ dàng và dễ dàng hơn.

Sử dụng Ruby với đá quý Selenium và PageObject, để có được lớp được liên kết với một yếu tố nhất định, dòng sẽ là element.attribute(Class).

Khái niệm tương tự áp dụng nếu bạn muốn có được các thuộc tính khác gắn với thành phần. Ví dụ: nếu tôi muốn Chuỗi của một phần tử , element.attribute(String).


4

Có vẻ lỗi thời, nhưng hãy để nó ở đây dù thế nào. Cách chính xác để làm điều đó trong trường hợp của bạn:

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

hoặc là

html = elem.get_attribute('innerHTML')

Cả hai đều hoạt động với tôi (selenium-server-standalone-2.35.0)


3

Java với Selenium 2.53.0

driver.getPageSource();

đó không phải là những gì câu hỏi yêu cầu
Corey Goldberg

Tùy thuộc vào webdo, getPageSourcephương thức có thể không trả về nguồn trang thực tế (nghĩa là có thể thay đổi javascript). Nguồn trả về có thể là nguồn thô được gửi bởi máy chủ. Tài liệu webdo phải được kiểm tra để đảm bảo điểm này.
Stephan

2

Tôi hy vọng điều này có thể giúp: http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebEuity.html

Dưới đây là mô tả phương thức Java:

java.lang.String    getText() 

Nhưng thật không may, nó không có sẵn trong Python. Vì vậy, bạn có thể dịch tên phương thức sang Python từ Java và thử logic khác bằng các phương thức hiện tại mà không cần lấy toàn bộ nguồn trang ...

Ví dụ

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

6
Python thực sự có một "gettext" tương đương (tôi nghĩ nó chỉ là thuộc tính "văn bản"?) Nhưng thực tế nó chỉ trả về "bản rõ" giữa các thẻ HTML và thực sự sẽ không trả về nguồn HTML đầy đủ.
Chris W.

2
Điều này chỉ trả về văn bản thuần túy (không phải html) trong Java.
Ryan Shillington

bạn phải tham chiếu nó giống như bạn đã nói elem [0] nếu không nó không hoạt động
HelloW

2

Điều này làm việc liền mạch cho tôi.

element.get_attribute('innerHTML')

1

InternalHTML sẽ trả về phần tử bên trong phần tử đã chọn và bên ngoàiHTML sẽ trả về bên trong HTML cùng với phần tử bạn đã chọn

Ví dụ: - Bây giờ giả sử Element của bạn như dưới đây

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

Phần tử bên trongHTML

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

đầu ra phần tửHTML

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

Ví dụ trực tiếp: -

http://www.java2s.com/Tutorials/JavascriptDemo/f/find thừng_the_difference_b between_innerhtml_and_outerhtml_in_javascript_example.htmlm

Dưới đây bạn sẽ tìm thấy cú pháp yêu cầu theo ràng buộc khác nhau. Thay đổi innerHTMLđể outerHTMLtheo yêu cầu.

Con trăn

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

Nếu bạn muốn toàn bộ trang HTML sử dụng mã bên dưới: -

driver.getPageSource();

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

Mã này thực sự hoạt động để có được JavaScript từ nguồn!


0

Và trong bài kiểm tra selenium PHPUnit, nó như thế này:

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

0

Nếu bạn quan tâm đến một giải pháp cho Điều khiển từ xa trong Python, đây là cách để có được InternalHTML:

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

Cảm ơn sự giúp đỡ, tôi đã sử dụng này. Tôi cũng tìm thấy innerHTML = {solenium selector code}.textcông việc giống nhau.
Shane

0

Phương pháp để nhận HTML được kết xuất mà tôi thích là như sau:

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

Tuy nhiên, phương pháp trên loại bỏ tất cả các thẻ (có các thẻ lồng nhau) và chỉ trả về nội dung văn bản. Nếu bạn cũng muốn nhận được đánh dấu HTML, thì hãy sử dụng phương pháp bên dưới.

print body_html.getAttribute("innerHTML")

1
Bạn cũng có thể sử dụng driver.find_element_by_tag ("body") để tiếp cận nội dung của trang.
Rusty
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.