如何检查网页元素是不是可见
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_xpath
和execute_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如何检查网页元素是不是包含某个特定字符串?