我在使用Beautifulsoup解析带有“class”属性的HTML元素时遇到了麻烦。代码看起来像这样

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div["class"] == "stylelistrow"):
        print div

我在脚本完成后的同一行上得到一个错误。

File "./beautifulcoding.py", line 130, in getlanguage
  if (div["class"] == "stylelistrow"):
File "/usr/local/lib/python2.6/dist-packages/BeautifulSoup.py", line 599, in __getitem__
   return self._getAttrMap()[key]
KeyError: 'class'

如何消除这个错误呢?


试着先检查div是否有class属性,就像这样:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs:
    if "class" in div:
        if (div["class"]=="stylelistrow"):
            print div

你可以使用BS3优化你的搜索,只找到那些给定类的div:

mydivs = soup.find_all("div", {"class": "stylelistrow"})

直接的方法是:

soup = BeautifulSoup(sdata)
for each_div in soup.findAll('div',{'class':'stylelist'}):
    print each_div

确保你使用了findAll的外壳,它不是findAll


这招对我很管用:

for div in mydivs:
    try:
        clazz = div["class"]
    except KeyError:
        clazz = ""
    if (clazz == "stylelistrow"):
        print div

从文档中可以看到:

从Beautiful Soup 4.1.2开始,你可以使用关键字参数class_通过CSS类进行搜索:

soup.find_all("a", class_="sister")

在这种情况下是:

soup.find_all("div", class_="stylelistrow")

它还适用于:

soup.find_all("div", class_="stylelistrowone stylelistrowtwo")

这可以让我访问class属性(在beautifulsoup 4上,与文档所说的相反)。KeyError返回的是一个列表,而不是字典。

for hit in soup.findAll(name='span'):
    print hit.contents[1]['class']

具体到BeautifulSoup 3:

soup.findAll('div',
             {'class': lambda x: x 
                       and 'stylelistrow' in x.split()
             }
            )

会找到所有这些:

<div class="stylelistrow">
<div class="stylelistrow button">
<div class="button stylelistrow">

更新:2016 在beautifulsoup的最新版本中,方法“findAll”已被重命名为 “find_all”。官方文件链接

因此答案将是

soup.find_all("html_element", class_="your_class_name")

如何按类查找元素 我在使用Beautifulsoup解析带有“class”属性的html元素时遇到了麻烦。

你可以很容易地找到一个类,但如果你想找到两个类的交集,这就有点困难了,

从文档(重点添加):

如果你想搜索匹配两个或多个CSS类的标签,你应该使用CSS选择器: css_soup.select(“p.strikeout.body”) # [<p class="body strikes "></p>]

明确地说,这只选择了同时是三振型和主体类的p标记。

为了找到一组类中任意的交集(不是交集,而是并集),你可以给class_ keyword参数一个列表(从4.1.2开始):

soup = BeautifulSoup(sdata)
class_list = ["stylelistrow"] # can add any other classes to this list.
# will find any divs with any names in class_list:
mydivs = soup.find_all('div', class_=class_list) 

还要注意,findAll已从camelCase重命名为更python化的find_all。


这应该可以工作:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div.find(class_ == "stylelistrow"):
        print div

CSS选择器

单班第一场比赛

soup.select_one('.stylelistrow')

匹配列表

soup.select('.stylelistrow')

复合类(即与另一个类)

soup.select_one('.stylelistrow.otherclassname')
soup.select('.stylelistrow.otherclassname')

复合类名中的空格,例如class = stylelistrow otherclassname被替换为"."。您可以继续添加类。

类列表(OR -匹配当前的任何一个)

soup.select_one('.stylelistrow, .otherclassname')
soup.select('.stylelistrow, .otherclassname')

类属性,其值包含一个字符串,例如"stylelistrow":

以“style”开头:

[class^=style]

以row结尾

[class$=row]

包含“列表”:

[class*=list]

^, $和*是操作符。更多信息请点击:https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

如果你想排除这个类,那么,以anchor tag为例,选择没有这个类的anchor tags:

a:not(.stylelistrow)

你可以在:not()伪类中传递简单、复合和复杂的css选择器列表。见https://facelessuser.github.io/soupsieve/selectors/pseudo-classes/:不是


Bs4 4.7.1 +

innerText包含字符串的特定类

soup.select_one('.stylelistrow:contains("some string")')
soup.select('.stylelistrow:contains("some string")')

N.B.

汤式饮料2.1.0 + 2020年12月

NEW: In order to avoid conflicts with future CSS specification changes, non-standard pseudo classes will now start with the :-soup- prefix. As a consequence, :contains() will now be known as :-soup-contains(), though for a time the deprecated form of :contains() will still be allowed with a warning that users should migrate over to :-soup-contains(). NEW: Added new non-standard pseudo class :-soup-contains-own() which operates similar to :-soup-contains() except that it only looks at text nodes directly associated with the currently scoped element and not its descendants.

具有特定子元素的特定类,例如标签

soup.select_one('.stylelistrow:has(a)')
soup.select('.stylelistrow:has(a)')

截至BeautifulSoup 4+,

如果你只有一个类名,你可以像这样把类名作为参数传递:

mydivs = soup.find_all('div', 'class_name')

或者如果你有多个类名,只需将类名列表作为参数传递:

mydivs = soup.find_all('div', ['class1', 'class2'])

下面的方法对我很有效

a_tag = soup.find_all("div",class_='full tabpublist')

或者我们可以使用lxml,它支持xpath和非常快!

from lxml import html, etree 

attr = html.fromstring(html_text)#passing the raw html
handles = attr.xpath('//div[@class="stylelistrow"]')#xpath exresssion to find that specific class

for each in handles:
    print(etree.tostring(each))#printing the html as string

其他答案对我不起作用。

在其他回答中,findAll被用于soup对象本身,但我需要一种方法来对从findAll之后获得的对象中提取的特定元素中的对象执行类名查找。

如果您试图在嵌套的HTML元素中进行搜索,以按类名获取对象,请尝试下面的-

# parse html
page_soup = soup(web_page.read(), "html.parser")

# filter out items matching class name
all_songs = page_soup.findAll("li", "song_item")

# traverse through all_songs
for song in all_songs:

    # get text out of span element matching class 'song_name'
    # doing a 'find' by class name within a specific song element taken out of 'all_songs' collection
    song.find("span", "song_name").text

注意事项:

I'm not explicitly defining the search to be on 'class' attribute findAll("li", {"class": "song_item"}), since it's the only attribute I'm searching on and it will by default search for class attribute if you don't exclusively tell which attribute you want to find on. When you do a findAll or find, the resulting object is of class bs4.element.ResultSet which is a subclass of list. You can utilize all methods of ResultSet, inside any number of nested elements (as long as they are of type ResultSet) to do a find or find all. My BS4 version - 4.9.1, Python version - 3.8.1


以下操作应该可以工作

soup.find('span', attrs={'class':'totalcount'})

用你的类名替换'totalcount',用你正在寻找的标签替换'span'。此外,如果类包含多个带空格的名称,只需选择一个并使用即可。

附注:这个函数用给定的条件找到第一个元素。如果你想找到所有的元素,那么将'find'替换为'find_all'。


关于@Wernight对上面关于部分匹配的答案的评论…

你可以部分匹配:

<div class="stylelistrow"> and <div class="stylelistrow button">

西班牙凉菜汤:

from gazpacho import Soup

my_divs = soup.find("div", {"class": "stylelistrow"}, partial=True)

两者都将被捕获并作为Soup对象列表返回。


使用class_=如果你想在不指定HTML标签的情况下查找元素。

对于单个元素:

soup.find(class_='my-class-name')

对于多个元素:

soup.find_all(class_='my-class-name')

soup.find("form",{"class":"c-login__form"})

多个

res=soup.find_all("input")
for each in res:
    print(each)