2016-10-04 64 views
2

我想檢索網頁的所有可見內容。比如說,例如this網頁。我用硒遠程使用無頭Firefox瀏覽器。使用硒和BeautifulSoup獲取頁面的可見內容

腳本我使用看起來像這樣

driver = webdriver.Remote('http://0.0.0.0:xxxx/wd/hub', desired_capabilities) 
driver.get(url) 
dom = BeautifulSoup(driver.page_source, parser) 

f = dom.find('iframe', id='dsq-app1') 
driver.switch_to_frame('dsq-app1') 
s = driver.page_source 
f.replace_with(BeautifulSoup(s, 'html.parser')) 

with open('out.html', 'w') as fe: 
    fe.write(dom.encode('utf-8')) 

這應該加載網頁,解析DOM,然後用ID dsq-app1取代的iframe與它的可見內容。如果我通過我的python命令行逐一執行這些命令,它按預期工作。然後我可以看到所有可見內容的段落。相反,我一次執行所有這些命令,無論是通過執行腳本還是將所有此代碼片段粘貼到解釋器中,它的行爲都有所不同。段落丟失,內容仍然以json格式存在,但這不是我想要的。

任何想法爲什麼會發生這種情況?可能與replace_with有關?

回答

1

當您的代碼嘗試訪問它們時,dom元素的聲音尚未加載。

嘗試wait爲元素被完全加載,然後替換。

這適用於您在通過命令運行命令時的作用,因爲這樣您就可以讓驅動程序在執行更多命令之前加載所有元素。

0

嘗試在檢測到所需ID/CSS_SELECTOR/CLASS或LINK後獲取頁面源。

您可以隨時使用Selenium WebDriver的顯式等待。

from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.by import By 
driver = webdriver.Remote('http://0.0.0.0:xxxx/wd/hub', desired_capabilities) 
driver.get(url) 
f = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,idName) 
# here 10 is time for which script will try to find given id 
# provide the id name 
dom = BeautifulSoup(driver.page_source, parser) 

f = dom.find('iframe', id='dsq-app1') 
driver.switch_to_frame('dsq-app1') 
s = driver.page_source 
f.replace_with(BeautifulSoup(s, 'html.parser')) 

with open('out.html', 'w') as fe: 
    fe.write(dom.encode('utf-8')) 

糾正我,如果這個不行

+0

這是我第一次學嘗試,但它不是正常工作,因爲該項目在實際上完全加載之前可能會出現。我猜這個等待頁面加載的整個主題是錯綜複雜的,但是我通過檢查iframe的readyState來解決它。 – LetsPlayYahtzee

+0

非常好。它可能在未來幫助我。謝謝 –

+0

我提供了我的解決方案,檢查波紋管 – LetsPlayYahtzee

1

添加或段的回答我提供什麼樣的我落得這樣做。查找頁面或頁面部分是否已完全加載的問題是複雜的。我試圖使用隱式和顯式等待,但我最終收到了半載幀。我的解決方法是檢查原始文檔的readyState和iframe的readyState。

下面是一個簡單的功能

def _check_if_load_complete(driver, timeout=10): 
    elapsed_time = 1 
    while True: 
     if (driver.execute_script('return document.readyState') == 'complete' or 
       elapsed_time == timeout): 
      break 
     else: 
      sleep(0.0001) 
     elapsed_time += 1 

然後我用該功能之後,我改變了司機的重點,在iframe

driver.switch_to_frame('dsq-app1') 
_check_if_load_complete(driver, timeout=10)