BeautifulSoup有多个标签,每个标签都有一个特定的类

时间:2016-11-07 08:36:00

标签: python html tags beautifulsoup findall

我正在尝试使用beautifulsoup来解析网站上的表格。 (我无法共享网站源代码,因为它是限制使用的。)

我正在尝试仅在具有以下两个具有这些特定类的标记时提取数据。

td, width=40%
tr, valign=top

我这样做的原因是提取具有这些标签和类的数据。

我发现了一些关于使用多个标签here的讨论,但这个只讨论标签而不是类。但是,我确实尝试使用相同的使用列表的逻辑来扩展代码,但我认为我得到的并不是我想要的:

 my_soup=soup.find_all(['td',{"width":"40%"},'tr',{'valign':'top'}])

总结一下,我的查询是如何在find_all中使用多个标签,每个标签都有一个特定的类,以便结果' ands'两个标签。

2 个答案:

答案 0 :(得分:0)

让我们说bsObj是你美丽的汤对象 尝试:

tr = bsObj.findAll('tr', {'valign': 'top'})
td = tr.findAll('td', {'width': '40%'})

希望这有帮助。

答案 1 :(得分:0)

您可以将re.compile对象与soup.find_all一起使用:

import re
from bs4 import BeautifulSoup as soup
html = """
  <table>
    <tr style='width:40%'>
      <td style='align:top'></td>
    </tr>
  </table>
"""
results = soup(html, 'html.parser').find_all(re.compile('td|tr'), {'style':re.compile('width:40%|align:top')})

输出:

[<tr style="width:40%">
   <td style="align:top"></td>
 </tr>, <td style="align:top"></td>]

通过提供re.compile对象来指定所需的标记和style值,find_all将返回包含内联的trtd标记的任何实例stylewidth:40%的{​​{1}}属性。

可以通过提供多个属性值来推断此方法以查找元素:

align:top

输出:

html = """
 <table>
   <tr style='width:40%'>
    <td style='align:top' class='get_this'></td>
    <td style='align:top' class='ignore_this'></td>
  </tr>
</table>
"""
results = soup(html, 'html.parser').find_all(re.compile('td|tr'), {'style':re.compile('width:40%|align:top'), 'class':'get_this'})

编辑2:简单的递归解决方案:

[<td class="get_this" style="align:top"></td>]

输出:

import bs4
from bs4 import BeautifulSoup as soup
def get_tags(d, params):
  if any((lambda x:b in x if a == 'class' else b == x)(d.attrs.get(a, [])) for a, b in params.get(d.name, {}).items()):
     yield d
  for i in filter(lambda x:x != '\n' and not isinstance(x, bs4.element.NavigableString) , d.contents):
     yield from get_tags(i, params)

html = """
 <table>
  <tr style='align:top'>
    <td style='width:40%'></td>
    <td style='align:top' class='ignore_this'></td>
 </tr>
 </table>
"""
print(list(get_tags(soup(html, 'html.parser'), {'td':{'style':'width:40%'}, 'tr':{'style':'align:top'}})))

递归函数使您能够为自己的字典提供某些标签的所需目标属性:此解决方案尝试将任何指定的属性与传递给函数的[<tr style="align:top"> <td style="width:40%"></td> <td class="ignore_this" style="align:top"></td> </tr>, <td style="width:40%"></td>] 对象进行匹配,以及是否找到匹配项,则该元素是bs4版。