我正在尝试解析一个表,并且我正在使用 bs4。当我将 find_all 与特定类标记一起使用时,不会返回任何内容。但是,当我不指定类时,它会返回一些内容。即,这将返回表格和所有 td 元素
from bs4 import BeautifulSoup as soup
page_soup = soup(html, 'html.parser')
stat_table = page_soup.find_all('table')
stat_table = stat_table[0]
with open ('stats.txt','w', encoding = 'utf-8') as q:
for row in stat_table.find_all('tr'):
for cell in row.find_all('td'):
q.write(cell.text.strip().ljust(18))
如果我尝试使用这个:
page_soup = soup(html, 'html.parser')
stat_table = page_soup.find_all('table')
stat_table = stat_table[0]
with open ('stats.txt','w', encoding = 'utf-8') as q:
for row in stat_table.find_all('tr'):
for cell in row.find_all('td',{'class':'blah'}):
q.write(cell.text.strip().ljust(18))
此代码应返回具有指定类的特定 td 元素,但没有返回任何内容。任何帮助将不胜感激。
最佳答案
class
属性不是普通字符串,而是 multi-valued attribute .1
例如:
>>> text = "<div><span class='a b c '>spam</span></div>"
>>> soup = BeautifulSoup(text, 'html.parser')
>>> soup.span['class']
['a', 'b', 'c']
<小时/>
要搜索多值属性,您应该传递多个值:
>>> soup.find('span', class_=('a', 'b', 'c'))
<span class="a b c">spam</span>
请注意,尽管 BeautifulSoup 将值显示为列表,但它们实际上更像是一个集合 - 您可以按任何顺序传递相同的值,并且会忽略重复值:
>>> soup.find('span', class_={'a', 'b', 'c'})
<span class="a b c">spam</span>
>>> soup.find('span', class_=('c', 'b', 'a', 'a'))
<span class="a b c">spam</span>
<小时/>
您还可以使用字符串搜索多值属性,这将查找其属性包含该字符串作为其值之一的任何元素:
>>> soup.find('span', class_='c')
<span class="a b c">spam</span>
但是,如果你传递一个带有空格的字符串......据我所知,它的作用实际上没有记录,但实际发生的情况是它将与字符串传递给 BeautifulSoup 的(任意)方式完全匹配由解析器处理。
正如您在上面看到的,即使 HTML 中有 'a b c '
,BeautifulSoup 也将其转换为 'a b c'
— 去除了末尾的空格,并将任何内部的空白变成单个空格。因此,这就是您必须搜索的内容:
>>> soup.find('span', class_='a b c ')
>>> soup.find('span', class_='a b c')
<span class="a b c">spam</span>
但是,再次强调,您最好使用一个序列或一组单独的值进行搜索,而不是尝试猜测如何将它们组合成一个恰好有效的字符串。
<小时/>所以,您想做的可能是:
for cell in row.find_all('td', {'class': ('column-even', 'table-column-even', 'ft_enrolled')}):
<小时/>
或者,也许您不想用 DOM 术语来思考,但是 in CSS-selector terms :
>>> soup.select('span.a.b.c')
[<span class="a b c">spam</span>]
请注意,CSS 也不关心类的顺序或重复项:
>>> soup.select('span.c.a.b.c')
[<span class="a b c">spam</span>]
此外,这还允许您搜索类的子集,而不仅仅是其中一个或全部:
>>> soup.select('span.c.b')
[<span class="a b c">spam</span>]
<小时/>
<子>1。这是 Beautiful Soup 3 的一个变化。甚至不需要提及,因为 BS3 已经消亡近十年了,并且不能在 Python 3.x 上运行,在某些情况下甚至不能在 2.7 上运行。但人们不断地将旧的 BS3 代码复制并粘贴到博客文章和 Stack Overflow 答案中,因此其他人不断对他们在网上找到的代码实际上不起作用感到惊讶。如果这就是这里发生的情况,您需要学会识别 BS3 代码,这样您就可以忽略它并在其他地方查找。
关于python - bs4 findAll 找不到类标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50867153/