Python 크롤러 소개(4)--HTML 텍스트 구문 분석 라이브러리 BeautifulSoup에 대한 자세한 설명

零下一度
풀어 주다: 2017-05-27 11:55:39
원래의
2109명이 탐색했습니다.

Beautiful Soup은 Python의 라이브러리입니다. 주요 기능은 웹 페이지에서 데이터를 가져오는 것입니다. 다음 기사에서는 Python 크롤러의 HTML 텍스트 구문 분석 라이브러리인 BeautifulSoup의 관련 정보를 주로 소개합니다. 기사의 소개는 매우 자세하며 필요한 모든 사람을 위한 특정 참조 및 학습 가치가 있습니다.

Preface

Python 크롤러 시리즈의 세 번째 기사에서는 요청이 데이터를 반환한 후 네트워크 요청 라이브러리 아티팩트를 소개합니다. 대상 데이터를 추출할 수 있습니다. 다양한 웹사이트에서 반환되는 콘텐츠는 일반적으로 다양한 형식을 가지고 있습니다. 그 중 하나는 json 형식이며, 이 유형의 데이터는 개발자에게 가장 친숙합니다. 또 다른 XML 형식이자 가장 일반적인 형식은 HTML 문서입니다. 오늘은 HTML

에서 흥미로운 데이터를 추출하는 방법에 대해 이야기하겠습니다. 자신만의 HTML 구문 분석 분석기를 작성하시겠습니까? 아니면 정규식을 사용하시겠습니까? 이들 중 어느 것도 최선의 해결책은 아닙니다. 다행히 Python 커뮤니티에는 이 문제에 대한 매우 성숙한 해결책이 있습니다. BeautifulSoup은 HTML 문서 작업에 중점을 두고 있으며 그 이름은 동일한 노래에서 유래되었습니다. 루이스 캐롤의 이름.

BeautifulSoup은 HTML 문서를 구문 분석하기 위한 Python 라이브러리입니다. BeautifulSoup을 통해 매우 적은 코드로 HTML의 흥미로운 콘텐츠를 추출할 수 있습니다. 또한 불완전한 형식의 HTML을 처리하는 기능도 있습니다. 문서를 올바르게 작성하세요.

Install BeautifulSoup

pip install beautifulsoup4
로그인 후 복사

BeautifulSoup3은 유지 관리를 위해 공식적으로 중단되었습니다. 최신 버전인 BeautifulSoup4를 다운로드해야 합니다.

HTML 태그

BeautifulSoup4를 배우기 전에, 다음 코드와 같이 HTML 문서에 대한 기본적인 이해가 필요합니다. 트리 조직 구조입니다.

<html> 
 <head>
  <title>hello, world</title>
 </head>
 <body>
  <h1>BeautifulSoup</h1>
  <p>如何使用BeautifulSoup</p>
 <body>
</html>
로그인 후 복사
  • html, head, title 등 여러 개의 태그(Tag)로 구성되어 있으며 모두 태그

  • @

    A 태그 쌍입니다. ...은 A 노드를 구성합니다. 루트 노드입니다

  • h1과 p와 같은 노드 사이에는 특정 관계가 있습니다. 서로 이웃하며 인접한 형제 노드입니다.

  • h1 body의 직계 자식 노드이거나 html의 자손 노드입니다.

  • body는 p의 부모 노드이고 html은 조상입니다. p의 노드

  • 태그 사이에 중첩된 문자열은 노드 아래의 특수 하위 노드입니다. 예를 들어 "hello, world"도 노드이지만 이름이 없습니다.

BeautifulSoup

BeautifulSoup 객체를 구성하려면 두 개의 매개변수가 필요합니다. 첫 번째 매개변수는 구문 분석할 HTML입니다. 텍스트 문자열인 두 번째 매개변수는 HTML을 구문 분석하는 데 사용할 파서를 BeautifulSoup에게 알려줍니다.

파서는 HTML을 관련 개체로 구문 분석하는 역할을 담당하고 BeautifulSoup은 데이터 조작(추가, 삭제, 수정 및 확인)을 담당합니다. "html.parser"는 Python에 내장된 파서이고 "lxml"은 C 언어를 기반으로 개발된 파서입니다. 실행 속도는 더 빠르지만 HTML의 모든 태그 노드에 BeautifulSoup 개체를 통해 찾을 수 있습니다.

from bs4 import BeautifulSoup 
text = """
<html> 
 <head>
  <title >hello, world</title>
 </head>
 <body>
  <h1>BeautifulSoup</h1>
  <p class="bold">如何使用BeautifulSoup</p>
  <p class="big" id="key1"> 第二个p标签</p>
  <a href="http://foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>
 </body>
</html> 
"""
soup = BeautifulSoup(text, "html.parser")

# title 标签
>>> soup.title
<title>hello, world</title>

# p 标签
>>> soup.p
<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>

# p 标签的内容
>>> soup.p.string
u&#39;\u5982\u4f55\u4f7f\u7528BeautifulSoup&#39;
로그인 후 복사

BeatifulSoup은 HTML을 네 가지 주요

데이터 유형

, 즉 Tag, NavigableString, BeautifulSoup 및 Comment로 추상화합니다. 각 태그 노드는 Tag 개체입니다. NavigableString 개체는 일반적으로 Tag 개체에 포함된 문자열입니다. BeautifulSoup 개체는 전체 HTML 문서를 나타냅니다. 예:

Tag각 태그에는 HTML 태그 이름에 해당하는 이름이 있습니다.

>>> soup.h1.name
u&#39;h1&#39;
>>> soup.p.name
u&#39;p&#39;
로그인 후 복사

태그는 속성을 가질 수도 있습니다. 속성의 액세스 방법은 사전의 액세스 방법과 유사합니다.

>>> soup.p[&#39;class&#39;]
[u&#39;bold&#39;]
로그인 후 복사

@ 목록 개체를 반환합니다. &@ NavigableString

태그의 내용을 가져옵니다. .stirng를 사용하여 직접 가져올 수 있습니다. NavigableString 개체이며 명시적으로 유니코드 문자열로 변환할 수 있습니다.

>>> soup.p.string
u&#39;\u5982\u4f55\u4f7f\u7528BeautifulSoup&#39;
>>> type(soup.p.string)
<class &#39;bs4.element.NavigableString&#39;>
>>> unicode_str = unicode(soup.p.string)
>>> unicode_str
u&#39;\u5982\u4f55\u4f7f\u7528BeautifulSoup&#39;
로그인 후 복사

기본 개념을 소개한 후, 이제 HTML에서 우리가 관심 있는 데이터를 찾는 방법에 대해 공식적으로 들어갈 수 있습니다. BeautifulSoup은 두 가지 방법을 제공합니다. 하나는 순회이고 다른 하나는 검색 작업을 완료하기 위해 일반적으로 두 가지를 결합합니다.

문서 트리 탐색

@문서 트리 탐색은 이름에서 알 수 있듯이 루트 노드 html 태그에서 시작하여 대상까지 탐색합니다. 의 한 가지 단점은 찾고 있는 콘텐츠가 문서 끝에 있는 경우 이를 찾기 위해 전체 문서를 탐색해야 하므로 속도가 느리다는 것입니다. 따라서 두 번째 방법에 협조할 필요가 있다.

문서 트리를 탐색하여 태그 노드를 얻으려면 태그 이름을 통해 직접 얻을 수 있습니다. 예:

본문 태그 얻기:

>>> soup.body
<body>\n<h1>BeautifulSoup</h1>\n<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>\n</body>
로그인 후 복사

获取 p 标签

>>> soup.body.p
<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>
로그인 후 복사

获取 p 标签的内容

>>> soup.body.p.string
\u5982\u4f55\u4f7f\u7528BeautifulSoup
로그인 후 복사

前面说了,内容也是一个节点,这里就可以用 .string 的方式得到。遍历文档树的另一个缺点是只能获取到与之匹配的第一个子节点,例如,如果有两个相邻的 p 标签时,第二个标签就没法通过 .p 的方式获取,这是需要借用 next_sibling 属性获取相邻且在后面的节点。此外,还有很多不怎么常用的属性,比如:.contents 获取所有子节点,.parent 获取父节点,更多的参考请查看官方文档。

搜索文档树

搜索文档树是通过指定标签名来搜索元素,另外还可以通过指定标签的属性值来精确定位某个节点元素,最常用的两个方法就是 find 和 find_all。这两个方法在 BeatifulSoup 和 Tag 对象上都可以被调用。

find_all()

find_all( name , attrs , recursive , text , **kwargs )
로그인 후 복사

find_all 的返回值是一个 Tag 组成的列表,方法调用非常灵活,所有的参数都是可选的。

第一个参数 name 是标签节点的名字。

# 找到所有标签名为title的节点
>>> soup.find_all("title")
[<title>hello, world</title>]
>>> soup.find_all("p")
[<p class="bold">\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup</p>, 
<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]
로그인 후 복사

第二个参数是标签的class属性值

# 找到所有class属性为big的p标签
>>> soup.find_all("p", "big")
[<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]
로그인 후 복사

等效于

>>> soup.find_all("p", class_="big")
[<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]
로그인 후 복사

因为 class 是 Python 关键字,所以这里指定为 class_。

kwargs 是标签的属性名值对,例如:查找有href属性值为 "http://foofish.net" 的标签

>>> soup.find_all(href="foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" )
[<a href="foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>]
로그인 후 복사

当然,它还支持正则表达式

>>> import re
>>> soup.find_all(href=re.compile("^http"))
[<a href="http://foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>]
로그인 후 복사

属性除了可以是具体的值、正则表达式之外,它还可以是一个布尔值(True/Flase),表示有属性或者没有该属性。

>>> soup.find_all(id="key1")
[<p class="big" id="key1"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]
>>> soup.find_all(id=True)
[<p class="big" id="key1"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]
로그인 후 복사

遍历和搜索相结合查找,先定位到 body 标签,缩小搜索范围,再从 body 中找 a 标签。

>>> body_tag = soup.body
>>> body_tag.find_all("a")
[<a href="http://foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>]
로그인 후 복사

find()

find 方法跟 find_all 类似,唯一不同的地方是,它返回的单个 Tag 对象而非列表,如果没找到匹配的节点则返回 None。如果匹配多个 Tag,只返回第0个。

>>> body_tag.find("a")
<a href="foofish.net" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >python</a>
>>> body_tag.find("p")
<p class="bold">\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup</p>
로그인 후 복사

get_text()

获取标签里面内容,除了可以使用 .string 之外,还可以使用 get_text 方法,不同的地方在于前者返回的一个 NavigableString 对象,后者返回的是 unicode 类型的字符串。

>>> p1 = body_tag.find(&#39;p&#39;).get_text()
>>> type(p1)
<type &#39;unicode&#39;>
>>> p1
u&#39;\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup&#39;

>>> p2 = body_tag.find("p").string
>>> type(p2)
<class &#39;bs4.element.NavigableString&#39;>
>>> p2
u&#39;\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup&#39;
>>>
로그인 후 복사

实际场景中我们一般使用 get_text 方法获取标签中的内容。

总结

BeatifulSoup 是一个用于操作 HTML 文档的 Python 库,初始化 BeatifulSoup 时,需要指定 HTML 文档字符串和具体的解析器。BeatifulSoup 有3类常用的数据类型,分别是 Tag、NavigableString、和 BeautifulSoup。查找 HTML元素有两种方式,分别是遍历文档树和搜索文档树,通常快速获取数据需要二者结合。

【相关推荐】

1. python爬虫入门(5)--正则表达式实例教程

2. python爬虫入门(3)--利用requests构建知乎API

3. python爬虫入门(2)--HTTP库requests

4.  总结Python的逻辑运算符and

5. python爬虫入门(1)--快速理解HTTP协议

위 내용은 Python 크롤러 소개(4)--HTML 텍스트 구문 분석 라이브러리 BeautifulSoup에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!