bs4 findAll找不到类标签

时间:2018-06-14 23:14:17

标签: python html web-scraping beautifulsoup

我正在尝试解析表格,而我正在使用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元素,但不返回任何内容。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

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。这是从美丽的汤3的变化。甚至不需要提及,因为BS3已经死了近十年,并且不会在Python 3.x上运行,或者在某些情况下甚至不运行2.7。但人们不断将旧的BS3代码复制并粘贴到博客帖子和Stack Overflow答案中,因此其他人不断惊讶于他们在网上找到的代码实际上并不起作用。如果这就是发生在这里的事情,你需要学会发现BS3代码,这样你就可以忽略它并寻找其他地方。

相关问题