当前位置: 首页 > 科技观察

每日一技能:Selenium抓不到的内容

时间:2023-03-22 01:58:44 科技观察

有些同学在写爬虫的时候过于依赖Selenium,认为只要用一个模拟的浏览器,就可以爬到任何内容而不被网站屏蔽。今天我们先不讨论字体反爬虫和CSS反爬虫这两个案例。让我们看一个非常简单的网页。这个网页只有一个HTML文件,没有加载特殊字体,也没有加载CSS文件。这个网页的奇怪之处在哪里?我们尝试使用XPathHelper提取网页上的红色文字,发现XPath无法找到这段文字,如下图:然后我们使用Selenium尝试:Selenium确实无法将红色文字提取到内容中。再打印一下网页源码:这次Selenium获取到的源码和Chrome开发者工具中显示的源码不一样?这个问题的关键在于开发者工具中的如下文字:becauseThisnodeisashadowDOM[1]。shadowDOM的行为与iframe非常相似,它将一段HTML信息嵌入到另一段HTML中。但不同的是嵌入iframe的地址需要额外搭建HTTP服务,而shadowDOM只能嵌入一段HTML代码,所以比iframe更节省资源。在上面的屏幕截图中,我们使用以下三行代码将新标记嵌入到原始HTML中:varcontent=document.querySelector('.content');varroot=content.attachShadow({mode:'open'});root.innerHTML='你看不到这段文字!

'而且这个内嵌的shadow标签,就像一个iframe,是不能直接用Selenium提取出来的。如果是强制提取,那么我们就需要使用JavaScript获取shadowDOM,然后进行提取。下面看一段运行正常的代码:shadow=driver.execute_script('returndocument.querySelector(".content").shadowRoot')content=shadow.find_element_by_class_name('real_content')print(content.text)的运行效果如下所示:这段代码首先通过JavaScript找到shadow-root的父节点元素,然后返回该元素的.shadowRoot属性。在Python中获取这个属性后,使用.find_element_by_class_name()方法获取里面的内容。需要特别注意的是,得到shadow-root节点后,里面的内容只能通过CSS选择器进一步过滤,不能使用XPath,否则会报错。参考文献[1]shadowDOM:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM本文转载自微信公众号“未听代码”,可通过以下二维码关注代码。转载本文请联系Code公众号。