아름다운 수프-태그로 탐색

이 장에서는 태그 별 탐색에 대해 설명합니다.

아래는 HTML 문서입니다.

>>> html_doc = """
<html><head><title>Tutorials Point</title></head>
<body>
<p class="title"><b>The Biggest Online Tutorials Library, It's all Free</b></p>
<p class="prog">Top 5 most used Programming Languages are:
<a href="https://www.tutorialspoint.com/java/java_overview.htm" class="prog" id="link1">Java</a>,
<a href="https://www.tutorialspoint.com/cprogramming/index.htm" class="prog" id="link2">C</a>,
<a href="https://www.tutorialspoint.com/python/index.htm" class="prog" id="link3">Python</a>,
<a href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" class="prog" id="link4">JavaScript</a> and
<a href="https://www.tutorialspoint.com/ruby/index.htm" class="prog" id="link5">C</a>;
as per online survey.</p>
<p class="prog">Programming Languages</p>
"""
>>>
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(html_doc, 'html.parser')
>>>

위의 문서를 바탕으로 문서의 한 부분에서 다른 부분으로 이동하려고합니다.

아래로

HTML 문서에서 중요한 요소 중 하나는 다른 태그 / 문자열 (태그의 자식)을 포함 할 수있는 태그입니다. Beautiful Soup은 태그의 자식을 탐색하고 반복하는 다양한 방법을 제공합니다.

태그 이름을 사용하여 탐색

구문 분석 트리를 검색하는 가장 쉬운 방법은 이름으로 태그를 검색하는 것입니다. <head> 태그를 원한다면 soup.head를 사용하십시오.

>>> soup.head
<head>&t;title>Tutorials Point</title></head>
>>> soup.title
<title>Tutorials Point</title>

<body> 태그에서 특정 태그 (예 : 첫 번째 <b> 태그)를 가져옵니다.

>>> soup.body.b
<b>The Biggest Online Tutorials Library, It's all Free</b>

태그 이름을 속성으로 사용하면 해당 이름의 첫 번째 태그 만 제공됩니다.

>>> soup.a
<a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a>

모든 태그의 속성을 얻으려면 find_all () 메소드를 사용할 수 있습니다.

>>> soup.find_all("a")
[<a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a>, <a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a>, <a class="prog" href="https://www.tutorialspoint.com/python/index.htm" id="link3">Python</a>, <a class="prog" href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" id="link4">JavaScript</a>, <a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a>]>>> soup.find_all("a")
[<a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a>, <a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a>, <a class="prog" href="https://www.tutorialspoint.com/python/index.htm" id="link3">Python</a>, <a class="prog" href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" id="link4">JavaScript</a>, <a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a>]

.contents 및 .children

.contents로 목록에서 태그의 자식을 검색 할 수 있습니다.

>>> head_tag = soup.head
>>> head_tag
<head><title>Tutorials Point</title></head>
>>> Htag = soup.head
>>> Htag
<head><title>Tutorials Point</title></head>
>>>
>>> Htag.contents
[<title>Tutorials Point</title>
>>>
>>> Ttag = head_tag.contents[0]
>>> Ttag
<title>Tutorials Point</title>
>>> Ttag.contents
['Tutorials Point']

BeautifulSoup 객체 자체에는 자식이 있습니다. 이 경우 <html> 태그는 BeautifulSoup 객체의 자식입니다.

>>> len(soup.contents)
2
>>> soup.contents[1].name
'html'

문자열은 아무것도 포함 할 수 없기 때문에 .contents가 없습니다.

>>> text = Ttag.contents[0]
>>> text.contents
self.__class__.__name__, attr))
AttributeError: 'NavigableString' object has no attribute 'contents'

목록으로 가져 오는 대신 .children 생성기를 사용하여 태그의 자식에 액세스합니다.

>>> for child in Ttag.children:
print(child)
Tutorials Point

.자손

.descendants 속성을 사용하면 태그의 모든 자식을 재귀 적으로 반복 할 수 있습니다.

직계 자식과 직계 자식 등

>>> for child in Htag.descendants:
print(child)
<title>Tutorials Point</title>
Tutorials Point

<head> 태그에는 자식이 하나만 있지만 하위 항목이 두 개 있습니다. <title> 태그와 <title> 태그의 자식입니다. beautifulsoup 객체는 오직 하나의 직계 자식 (<html> 태그) 만 가지고 있지만, 많은 자손이 있습니다.

>>> len(list(soup.children))
2
>>> len(list(soup.descendants))
33

.끈

태그에 자식이 하나만 있고 그 자식이 NavigableString이면 자식은 .string으로 사용할 수 있습니다.

>>> Ttag.string
'Tutorials Point'

태그의 유일한 자식이 다른 태그이고 해당 태그에 .string이있는 경우 부모 태그는 자식과 동일한 .string을 갖는 것으로 간주됩니다.

>>> Htag.contents
[<title>Tutorials Point</title>]
>>>
>>> Htag.string
'Tutorials Point'

그러나 태그에 둘 이상의 것이 포함되어 있으면 .string이 무엇을 참조해야하는지 명확하지 않으므로 .string은 None으로 정의됩니다.

>>> print(soup.html.string)
None

.strings 및 stripped_strings

태그 안에 둘 이상의 것이있는 경우에도 문자열 만 볼 수 있습니다. .strings 생성기를 사용하십시오-

>>> for string in soup.strings:
print(repr(string))
'\n'
'Tutorials Point'
'\n'
'\n'
"The Biggest Online Tutorials Library, It's all Free"
'\n'
'Top 5 most used Programming Languages are: \n'
'Java'
',\n'
'C'
',\n'
'Python'
',\n'
'JavaScript'
' and\n'
'C'
';\n \nas per online survey.'
'\n'
'Programming Languages'
'\n'

여분의 공백을 제거하려면 .stripped_strings 생성기를 사용하십시오.

>>> for string in soup.stripped_strings:
print(repr(string))
'Tutorials Point'
"The Biggest Online Tutorials Library, It's all Free"
'Top 5 most used Programming Languages are:'
'Java'
','
'C'
','
'Python'
','
'JavaScript'
'and'
'C'
';\n \nas per online survey.'
'Programming Languages'

올라간다

"가계도"비유에서 모든 태그와 모든 문자열에는 부모가 있습니다.

.부모의

요소의 상위 요소에 액세스하려면 .parent 속성을 사용하십시오.

>>> Ttag = soup.title
>>> Ttag
<title>Tutorials Point</title>
>>> Ttag.parent
<head>title>Tutorials Point</title></head>

html_doc에서 제목 문자열 자체에는 부모가 있습니다 :이를 포함하는 <title> 태그-

>>> Ttag.string.parent
<title>Tutorials Point</title>

<html>과 같은 최상위 태그의 부모는 Beautifulsoup 객체 자체입니다.

>>> htmltag = soup.html
>>> type(htmltag.parent)
<class 'bs4.BeautifulSoup'>

Beautifulsoup 객체의 부모는 None으로 정의됩니다-

>>> print(soup.parent)
None

.부모님

모든 상위 요소를 반복하려면 .parents 속성을 사용하십시오.

>>> link = soup.a
>>> link
<a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a>
>>>
>>> for parent in link.parents:
if parent is None:
print(parent)
else:
print(parent.name)
p
body
html
[document]

옆으로

아래는 간단한 문서입니다.

>>> sibling_soup = BeautifulSoup("<a><b>TutorialsPoint</b><c><strong>The Biggest Online Tutorials Library, It's all Free</strong></b></a>")
>>> print(sibling_soup.prettify())
<html>
<body>
   <a>
      <b>
         TutorialsPoint
      </b>
      <c>
         <strong>
            The Biggest Online Tutorials Library, It's all Free
         </strong>
      </c>
   </a>
</body>
</html>

위 문서에서 <b> 및 <c> 태그는 동일한 수준에 있으며 둘 다 동일한 태그의 하위입니다. <b> 및 <c> 태그는 모두 형제입니다.

.next_sibling 및 .previous_sibling

.next_sibling 및 .previous_sibling을 사용하여 구문 분석 트리의 동일한 수준에있는 페이지 요소 사이를 탐색합니다.

>>> sibling_soup.b.next_sibling
<c><strong>The Biggest Online Tutorials Library, It's all Free</strong></c>
>>>
>>> sibling_soup.c.previous_sibling
<b>TutorialsPoint</b>

<b> 태그에는 .next_sibling이 있지만 .previous_sibling은 없습니다. 동일한 수준의 트리에서 <b> 태그 앞에 아무것도 없기 때문에 동일한 대소 문자가 <c> 태그와 함께 사용됩니다.

>>> print(sibling_soup.b.previous_sibling)
None
>>> print(sibling_soup.c.next_sibling)
None

두 문자열은 동일한 부모가 없기 때문에 형제가 아닙니다.

>>> sibling_soup.b.string
'TutorialsPoint'
>>>
>>> print(sibling_soup.b.string.next_sibling)
None

.next_siblings 및 .previous_siblings

태그의 형제를 반복하려면 .next_siblings 및 .previous_siblings를 사용하십시오.

>>> for sibling in soup.a.next_siblings:
print(repr(sibling))
',\n'
<a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a>
',\n'
>a class="prog" href="https://www.tutorialspoint.com/python/index.htm" id="link3">Python</a>
',\n'
<a class="prog" href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" id="link4">JavaScript</a>
' and\n'
<a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm"
id="link5">C</a>
';\n \nas per online survey.'
>>> for sibling in soup.find(id="link3").previous_siblings:
print(repr(sibling))
',\n'
<a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a>
',\n'
<a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a>
'Top 5 most used Programming Languages are: \n'

앞뒤로

이제 이전 "html_doc"예제에서 처음 두 줄로 돌아가 보겠습니다.

&t;html><head><title>Tutorials Point</title></head>
<body>
<h4 class="tagLine"><b>The Biggest Online Tutorials Library, It's all Free</b></h4>

HTML 파서는 위의 문자열을 "open an <html> tag", "open an <head> tag", "open the <title> tag", "add a string"과 같은 일련의 이벤트로 변환합니다. "닫기 </ title> 태그", "닫기 </ head> 태그", "<h4> 태그 열기"등. BeautifulSoup은 문서의 초기 구문 분석을 재구성하는 다양한 방법을 제공합니다.

.next_element 및 .previous_element

태그 또는 문자열의 .next_element 속성은 직후 파싱 된 모든 것을 가리 킵니다. 때로는 .next_sibling과 비슷해 보이지만 완전히 동일하지는 않습니다. 다음은 "html_doc"예제 문서의 마지막 <a> 태그입니다.

>>> last_a_tag = soup.find("a", id="link5")
>>> last_a_tag
<a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a>
>>> last_a_tag.next_sibling
';\n \nas per online survey.'

그러나 <a> 태그 바로 뒤에 파싱 된 <a> 태그의 .next_element는 그 문장의 나머지 부분이 아닙니다. "C"라는 단어입니다.

>>> last_a_tag.next_element
'C'

위의 동작은 원래 마크 업에서 "C"문자가 세미콜론 앞에 나타나기 때문입니다. 구문 분석기는 <a> 태그, 문자 "C", 닫는 </a> 태그, 세미콜론 및 나머지 문장을 발견했습니다. 세미콜론은 <a> 태그와 같은 수준에 있지만 문자 "C"가 먼저 발견되었습니다.

.previous_element 속성은 .next_element의 정반대입니다. 이 요소 바로 전에 구문 분석 된 요소를 가리 킵니다.

>>> last_a_tag.previous_element
' and\n'
>>>
>>> last_a_tag.previous_element.next_element
<a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a>

.next_elements 및 .previous_elements

이 반복기를 사용하여 요소로 앞뒤로 이동합니다.

>>> for element in last_a_tag.next_e lements:
print(repr(element))
'C'
';\n \nas per online survey.'
'\n'
<p class="prog">Programming Languages</p>
'Programming Languages'
'\n'