【问题标题】:BeautifulSoup drops children when parent is in an implied namespace当父级在隐含的命名空间中时,BeautifulSoup 会丢弃子级
【发布时间】:2013-01-31 20:25:15
【问题描述】:

我正在使用 selenium 和 BeautifulSoup 为 Nordstrom 的网站构建一个屏幕截图。该网站实际上并没有命名空间中的每个标签,但 Firefox 网络驱动程序会创建一个以避免歧义(具体来说,该网站有一个 <html xmlns> 似乎会混淆驱动程序的标签)。
因此,所有内容都放在命名空间a0 中。但是,当调用 find() 时,Beautiful Soup 仅返回父元素和(有时)一级子元素。
以这个 html 为例:

<div class='division'>
   <a href='#'>
      <img />
   </a>
</div>

一切都在隐含的a0 命名空间中,因此我们可以通过以下方式获取图像:

soup.find('a0:div',{'class':'division'}).find('a0:img')

但是,这将返回 None。我查看了soup.prettify(),可以肯定地说a0:imga0:div 之内。这是一个预期的功能(在这种情况下我需要找到一种新的方法)还是一个错误(在这种情况下我需要一个解决方法)?

编辑

为避免混淆,这是一个演示整个工作流程的示例:

from selenium import webdriver
from BeautifulSoup import BeautifulSoup # Note that this is BeautifulSoup 3
b = webdriver.Firefox()
b.get("http://shop.nordstrom.com/c/womens-skirts")
borscht = BeautifulSoup(b.page_source)
theImageThatCannotBeFound = borscht.find('a0:div',{'class':'fashion-item'}).find('a0:img')

上述代码将theImageThatCannotBeFound 设置为None,我认为这是不正确的。我希望这可以澄清。

【问题讨论】:

  • 请注意 soup.find('a0:div',{'class':'division'}) 返回 div 但没有图像(或任何其他二级子级)。
  • 你能提供一个具体的网址吗?
  • 该特定网址不包含&lt;div class="division"&gt;。事实上,对页面源的简单搜索根本找不到字符串“division”的实例。
  • 你可能应该假设我正在举一个类似情况的例子。试试这个:soup.find('a0:div',{'class':'fashion-item'}).find('a0:img')

标签: python firefox selenium beautifulsoup


【解决方案1】:

这对我有用。

import urllib
from BeautifulSoup import BeautifulSoup

url = 'http://shop.nordstrom.com/c/womens-skirts'
fp = urllib.urlopen(url)
soup = BeautifulSoup(fp)

print soup.find('div',{'class':'fashion-item'}).findAll('img') # also tried .find

尝试排除a0:。这似乎是你的问题。

编辑:

在 Selenium 内外使用 Chrome 和 Firefox 浏览器时,xmlns 在我查看时被设置为一个空字符串,这就是上面代码对我有用的原因。似乎由于某处某些组件的不匹配,我们没有得到相同的结果,并且您得到了命名空间a0:

因为我无法重现这种情况,所以我能找到的唯一解决方案(虽然很hacky)是手动替换命名空间:

source = browser.page_source.replace('a0:div','div')
soup = BeautifulSoup(source)

print soup.find('div',{'class':'fashion-item'}).find('img')

我承认它并不是一个理想的解决方案。如果我找到更优雅的解决方法,我会继续寻找并更新我的答案。

【讨论】:

  • 请注意,这必须在 Selenium 中完成才能正确解析 javascript。
  • urllib 解析 html 的方式与我在这里使用的 selenium.webdriver.Firefox 不同。我确实提到我在问题中使用了硒。
  • 我随意猜测a0命名空间与firebug有关。无论哪种方式,通过字符串操作手动删除命名空间似乎都有效(我只是将 'a0:' 替换为 '' 到处都忽略了可能对内容产生的任何影响)。
猜你喜欢
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
  • 2017-09-20
  • 2016-03-05
  • 1970-01-01
  • 2018-07-22
  • 1970-01-01
相关资源
最近更新 更多