python - bs4 findAll 找不到类标签

标签 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 元素,但没有返回任何内容。任何帮助将不胜感激。

最佳答案

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 ',Be​​autifulSoup 也将其转换为 '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/

相关文章:

python - 用户输入的输出字典不正确

python - 根据其他列值的组合检查唯一列值

python - 打印错误 'bs4.element.NavigableString'

java - 从看起来像Javascript的网页中获取数据到Java中?

python - 使用 Python Elasticserarch-py 包时出错

html - 更改窗口大小时重新调整标题大小

php - 从数据库渲染复选框,然后更新数据库(如果修改)

jquery - 如果表格标题有多行并且 colspan 到表格单元格,则表格列大小调整不起作用

python - 抓取脚本提供的 JSON 并转换为数据帧

python - 有没有更简洁的方法来构建这个列表? python 3