使用selenium和BeautifulSoup

时间:2016-10-04 10:04:34

标签: python html selenium beautifulsoup

我想检索网页的所有可见内容。比方说this网页。我使用selenium远程使用无头firefox浏览器。

我使用的脚本看起来像这样

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有关吗?​​

3 个答案:

答案 0 :(得分:1)

当您的代码尝试访问它们时,听起来还没有加载dom元素。

尝试wait以便元素完全加载,然后替换。

当您按命令运行它时,这适用于您,因为您在执行更多命令之前让驱动程序加载所有元素。

答案 1 :(得分:1)

为了增加Or Duan的回答,我提供了我最终做的事情。查找页面或页面的某些部分是否已完全加载的问题是一个错综复杂的问题。我试图使用隐式和显式等待,但我再次收到半载帧。我的解决方法是检查原始文档的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)

答案 2 :(得分: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'))

如果这不起作用,请纠正我