如何检查网页元素是不是可见

Posted

技术标签:

【中文标题】如何检查网页元素是不是可见【英文标题】:How to check if a web element is visible如何检查网页元素是否可见 【发布时间】:2014-04-22 13:29:27 【问题描述】:

我正在使用 Python 和 BeautifulSoup4,我需要检索页面上的可见链接。鉴于此代码:

soup = BeautifulSoup(html)
links = soup('a')

我想创建一个方法is_visible 来检查页面上是否显示链接。

使用 Selenium 的解决方案

由于我也在使用 Selenium,因此我知道存在以下解决方案:

from selenium.webdriver import Firefox

firefox = Firefox()
firefox.get('https://google.com')
links = firefox.find_elements_by_tag_name('a')

for link in links:
    if link.is_displayed():
        print(' => Visible'.format(link.text))
    else:
        print(' => Hidden'.format(link.text))

firefox.quit()

性能问题

不幸的是,is_displayed 方法和获取文本属性执行 http 请求来检索此类信息。因此,当页面上有许多链接或您必须多次执行此操作时,事情会变得非常缓慢。

另一方面,BeautifulSoup 可以在获得页面源后零时间执行这些解析操作。但我不知道该怎么做。

【问题讨论】:

我认为你能做的最好的就是检查美丽汤标签的style属性并解析该值以查看其中是否有类似的display:none 不幸的是,Beautifulsoup 是一个 html 解析器,而不是浏览器,所以它对如何渲染页面一无所知。我认为你必须坚持使用 Selenium。 pyself,我很确定@fasouto 是对的。 beautifulsoup 实际上并没有渲染任何东西,如果你阅读 selenium 文档,它会自动化 BROWSERS.. 而不仅仅是纯 HTML。如果你真的想这样做,我认为你必须坚持使用 selenium 来做这件事。 元素被内联、链接或内部 CSS 隐藏(input 除外)。或者用JS隐藏。然后你有其他不可见的东西,比如白色背景上的白色文本。你到底想检查什么?只有 CSS display:none?比您需要使用 tinycss 解析 all 样式表并查看规则是否与元素匹配。如果找到匹配项,请检查应用了哪些样式。困难在于级联部分。此外,如果隐藏了父级,则隐藏了子级。因此,您必须检查该元素的所有父元素是否也可见......或者只使用 Selenium。 看看这个帖子:***.com/questions/1936466/… 【参考方案1】:

AFAIK,BeautifulSoup 只会帮助您解析 HTML 文档的实际标记。如果这就是你所需要的,那么你可以用这样的方式来做(是的,我已经知道它并不完美):

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc)


def is_visible_1(link):
    #do whatever in this function you can to determine your markup is correct
    try:
        style = link.get('style')
        if 'display' in style and 'none' in style:#or use a regular expression
            return False
    except Exception:
        return False
    return True

def is_visible_2(**kwargs):
    try:
        soup = kwargs.get('soup', None)
        del kwargs['soup']
        #Exception thrown if element can't be found using kwargs
        link = soup.find_all(**kwargs)[0]
        style = link.get('style')
        if 'display' in style and 'none' in style:#or use a regular expression
            return False
    except Exception:
        return False
    return True


#checks links that already exist, not *if* they exist
for link in soup.find_all('a'):
    print(str(is_visible_1(link)))

#checks if an element exists
print(str(is_visible_2(soup=soup,id='someID')))

BeautifulSoup 考虑到会告诉您元素是否可见的其他方,例如:CSS、脚本和动态 DOM 更改。另一方面,Selenium 确实会告诉您一个元素是否正在被渲染,并且通常是通过给定浏览器中的可访问性 API 来实现的。您必须决定是否值得追求速度而牺牲准确性。祝你好运! :-)

【讨论】:

【参考方案2】:

试试find_elements_by_xpathexecute_script

from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.google.com/?hl=en")
links = driver.find_elements_by_xpath('//a')

driver.execute_script('''
    var links = document.querySelectorAll('a');

    links.forEach(function(a) 
        a.addEventListener("click", function(event) 
            event.preventDefault();
        );
    );
''')

visible = []
hidden = []
for link in links:
    try:
        link.click()
        visible.append(' => Visible'.format(link.text))
    except:
        hidden.append(' => Hidden'.format(link.get_attribute('textContent')))

    #time.sleep(0.1)

print('\n'.join(visible))
print('===============================')
print('\n'.join(hidden))
print('===============================\nTotal links length: %s' % len(links))

driver.execute_script('alert("Finish")')

【讨论】:

以上是关于如何检查网页元素是不是可见的主要内容,如果未能解决你的问题,请参考以下文章

javascript如何检查网页元素是不是包含某个特定字符串?

jquery怎么判断是不是有某个元素

如何使用 Puppeteer 和纯 JavaScript 检查元素是不是可见?

如何使用 WebDriver 检查元素是不是可见

如何在 Firebug 中检查网页的动态悬停元素?

如何检查元素是不是在屏幕上完全可见?