클래스별로 요소를 찾는 방법


386

Beautifulsoup을 사용하여 "클래스"속성이있는 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'

이 오류를 어떻게 제거합니까?

답변:


646

BS3를 사용하여 주어진 클래스의 div 만 찾도록 검색을 구체화 할 수 있습니다.

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

@ Klaus- findAll을 대신 사용하려면 어떻게해야합니까?

1
고마워 그것은 단지 @class만을위한 것이 아니라 무엇이든을위한 것입니다.
prageeth

41
이것은 정확히 일치하는 경우에만 작동합니다. <.. class="stylelistrow">일치하지만 그렇지 않습니다 <.. class="stylelistrow button">.
Wernight

4
@pyCthon @jmunsch에 대한 답변을 참조하십시오. BS는 이제 class_제대로 작동 하는 것을 지원합니다 .
Wernight

25
beautifulsoup4 현재, findAll은 이제 find_all
Neoecos

273

설명서에서 :

Beautiful Soup 4.1.2부터 키워드 인수를 사용하여 CSS 클래스로 검색 할 수 있습니다 class_ .

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

이 경우 다음 중 하나입니다.

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

또한 다음과 같이 작동합니다.

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

5
당신은 soup.find_all("a", ["stylelistrowone", "stylelistrow"])또한 목록을 사용할 수 있습니다 : 많은 수업이 없다면 더 안전합니다.
Nuno André

4
이것은 받아 들일만한 대답이어야하며, 대안보다 정확하고 간결합니다.
goncalopp

1
BeautifulSoup 3에 대한 @ NunoAndré의 답변을 보완합니다 soup.findAll("a", {'class':['stylelistrowone', 'stylelistrow']}).
Brad

55

업데이트 : 2016 beautifulsoup 최신 버전에서 'findAll'메소드의 이름이 'find_all'로 변경되었습니다. 공식 문서로 연결

분석법 이름 목록이 변경됨

따라서 대답은

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

18

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">

왜 re.search ( '. * stylelistrow. *', x)?
rjurney

stylelistrow2가 일치하기 때문입니다. 더 나은 의견은 "re 대신에 string.find ()를 사용하지 않는 이유는 무엇입니까?"
FlipMcF

2
lambda x: 'stylelistrow' in x.split()간단하고 아름답습니다
fferri

그리고 나는 정규 표현식을 싫어한다. 감사합니다! (업데이트 답변) | None을 테스트하기 위해 'x and'유지
FlipMcF

16

간단한 방법은 다음과 같습니다.

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

findAll 이 아닌 findAll 의 케이스를 가져와야합니다.


4
이것은 정확히 일치하는 경우에만 작동합니다. <.. class="stylelistrow">일치하지만 그렇지 않습니다 <.. class="stylelistrow button">.
Wernight

11

클래스별로 요소를 찾는 방법

Beautifulsoup을 사용하여 "class"속성을 사용하여 html 요소를 구문 분석하는 데 문제가 있습니다.

하나의 클래스로 쉽게 찾을 수 있지만 두 클래스의 교차로 찾으려면 조금 더 어렵습니다.

로부터 문서 (강조는 추가) :

둘 이상의 CSS 클래스 와 일치 하는 태그를 검색 하려면 CSS 선택기를 사용해야합니다.

css_soup.select("p.strikeout.body")
# [<p class="body strikeout"></p>]

명확하게하기 위해, 이는 취소 선과 본문 클래스 인 p 태그 만 선택합니다.

의 교차점에 대한 찾으려면 어떤 클래스의 집합 (안 교차로,하지만 노조)에서 것은, 당신은에 대한 목록을 제공 할 수 있습니다 class_(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에서 더 Pythonic로 바뀌 었습니다 find_all.


11

CSS 선택기

싱글 클래스 첫 경기

soup.select_one('.stylelistrow')

경기 목록

soup.select('.stylelistrow')

복합 클래스 (즉, AND 다른 클래스)

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

복합 클래스 이름의 공백은 class = stylelistrow otherclassname"."으로 대체됩니다. 수업을 계속 추가 할 수 있습니다.

클래스 목록 (또는-존재하는 항목과 일치)

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

bs4 4.7.1 +

innerText문자열을 포함하는 특정 클래스

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

특정 하위 요소가있는 특정 클래스 (예 : a태그)

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

5

BeautifulSoup 4+ 기준으로

단일 클래스 이름이있는 경우 클래스 이름을 매개 변수로 다음과 같이 전달할 수 있습니다.

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

또는 클래스 이름이 두 개 이상인 경우 클래스 이름 목록을 다음과 같은 매개 변수로 전달하십시오.

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

3

다음과 같이 div에 클래스 속성이 있는지 먼저 확인하십시오.

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

1
작동하지 않습니다. 귀하의 접근 방식이 옳았지만 4 번째 줄은 의도 한대로 작동하지 않습니다.
Neo

1
아 div가 사전처럼 작동한다고 생각했는데 Beautiful Soup에 익숙하지 않아 추측 일뿐입니다.
Mew

3

이것은 클래스 속성에 액세스하는 데 도움이됩니다 (beautifulsoup 4에서는 설명서의 내용과 반대). KeyError는 사전이 아닌 목록을 반환합니다.

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

3

다음은 나를 위해 일했습니다.

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

1

이것은 나를 위해 일했다 :

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

1

또는 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

0

이것은 작동해야합니다 :

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

0

다른 답변은 저에게 효과가 없었습니다.

다른 답변에서는 findAll수프 객체 자체에서 사용되고 있지만, 수행 한 후 얻은 객체에서 추출 된 특정 요소 내부의 객체에서 클래스 이름으로 찾기를 수행하는 방법이 필요했습니다 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

참고 사항 :

  1. 검색은 'class'attribute에 있도록 명시 적으로 정의하지 않습니다. 검색 findAll("li", {"class": "song_item"})하는 유일한 속성이므로 찾고자하는 속성을 독점적으로 알려주지 않으면 기본적으로 class 속성을 검색합니다.

  2. 당신이 작업을 수행 할 때 findAllfind, 결과 객체는 클래스의 인 bs4.element.ResultSet의 서브 클래스입니다 list. 모든 ResultSet유형의 중첩 요소 내에서 (유형이있는 한 ResultSet)의 모든 메소드를 사용하여 모두 찾기 또는 찾기를 수행 할 수 있습니다.

  3. 내 BS4 버전-4.9.1, Python 버전-3.8.1


0

다음은 작동합니다

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

'totalcount'를 클래스 이름으로 바꾸고 'span'을 원하는 태그로 바꿉니다. 또한 수업에 공백이있는 여러 이름이 포함되어 있으면 하나만 선택하고 사용하십시오.

PS 주어진 기준을 가진 첫 번째 요소를 찾습니다. 모든 요소를 ​​찾으려면 'find'를 'find_all'로 바꾸십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.