- 2
- 이니스프리
- 조회 수 1214
안녕하세요?
Beautifulsoup에서 .find(text=True, recursive=False)과 관련하여 질문 드립니다.
대략 다음과 같은 html 소스와 파이썬 스크립트가 있다고 가정하면요.
from bs4 import BeautifulSoup html = '<span class="member"><span class="lv-icon lv-100">100</span> <img src="https://able.net/data/member/abc.gif"> 댄스</span>' soup = BeautifulSoup(html, 'html5lib')
member = soup.select_one('span.member').find(text=True, recursive=False).strip()
=> '' (none)
member = soup.select_one('span.member').find(text=True).strip()
=> 100
member = soup.select_one('span.member').text
=> 100 댄스
위와 같은 결과가 나오는데요.
text=True 옵션은 .text 메서드와 같은 결과를 리턴하고, recursive=False는 child를 제외한 해당 element만 선택한다고 알고 있는데요.
첫번째에서 ' 댄스'가 나오고, 두번째에서는 세번째와 같은 결과가 나와야 하는 것이 아닌가 하는 생각을 했는데요.
구글링해보니 다음과 같은 글이 있기는 한데 직관적으로 이해가 되지 않네요.
"If used with find_all
or find
, text=true
looks for every tags with texts inside it while get_text()
returns the text from your found tags."
출처: https://stackoverflow.com/questions/46124681/difference-and-when-to-use-text-true-and-get-text
제가 어디에서 실수를 하거나, 어느 부분에서 잘못 생각한 것인지 여쭤봅니다 ㅠㅠ
어제와 오늘 이 부분에서 막혀서 고민했는데 제 실력에서는 도저히 답이 안 나오네요~
그럼 즐거운 2020년의 첫 불금 되세요 ^-^
항상 감사드립니다!
soup.select_one('span.member').find(text=True, recursive=False)
=> 100와 의 사이에 있는 공백이 나오게 됩니다. 그래서 여기에서 strip() 함수를 적용하면 빈 문자가 나오게 됩니다.
2번째 경우에는 find로 찾기 때문에 마찬가지로 첫 번째 텍스트 노드인 100이 반환됩니다. 만약 find 부분을 find_all로 바꾸면 3개의 원소가 반환되는 것을 확인할 수 있습니다.
3번째 경우인 .text의 경우에는 내부적으로 모든 child node에 대해서 텍스트 노드를 찾아서 연결하기 때문에 '100 댄스'라는 결과가 나오게 됩니다.
즉 elem.text는 ''.join(soup.select_one('span.member').find_all(text=True)) 와 같이 동작한다고 생각하시면 되겠습니다.
https://github.com/wention/BeautifulSoup4/blob/master/bs4/element.py#L846