파이썬 구문 분석하는 HTML BeautifulSoup로를 이용하여 아래에서

개요

아름다운 수프는 파이썬 라이브러리는 HTML이나 XML 형식 파일에서 데이터를 추출 할 수 있습니다, 그는 파이썬은 파이썬 코드에 의한 처리를 용이하게하기 위해, 객체에 HTML이나 XML 데이터를 구문 분석 할 수 있습니다.

문서 환경

CentOS의 파이썬 BeautifulSoup로

  • 이 문서는 테스트 환경 코드

아름 다 수프 지침

아름다운 수프의 기본 기능은 찾아 편집 할 수있는 HTML 태그입니다.

기본 개념 - 객체 유형

트리 구조로 아름다운 수프 복잡한 복잡한 HTML 문서가 각 노드는 파이썬 객체로 변환, 아름다운 수프는 객체의 네 가지 유형의 정의 : 태그, NavigableString, BeautifulSoup로, 코멘트.

개체 유형 기술
BeautifulSoup로 문서의 전체 내용
꼬리표 HTML 태그
NavigableString 태그는 텍스트를 포함
논평 의 유형을 정의하는 레이블이 주석 NavigableString 특수한 유형의 NavigableString,인가

설치 및 참조

# Beautiful Soup
pip install bs4

# 解析器
pip install lxml
pip install html5lib
# 初始化
from bs4 import BeautifulSoup

# 方法一,直接打开文件
soup = BeautifulSoup(open("index.html"))

# 方法二,指定数据
resp = "<html>data</html>"
soup = BeautifulSoup(resp, 'lxml')

# soup 为 BeautifulSoup 类型对象
print(type(soup))

태그 검색 및 필터링

기본 방법

검색 태그 find_all ()을 가지고 하나의 일치 결과) (발견, () 메소드의 반환을 두 가지 기본 검색 방법, find_all () 메소드가 반환 일치하는 모든 키워드 태그의 목록을 찾을 수 있습니다.

soup = BeautifulSoup(resp, 'lxml')

# 返回一个标签名为"a"的Tag
soup.find("a")

# 返回所有tag 列表
soup.find_all("a")

## find_all方法可被简写
soup("a")

#找出所有以b开头的标签
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)

#找出列表中的所有标签
soup.find_all(["a", "p"])

# 查找标签名为p,class属性为"title"
soup.find_all("p", "title")

# 查找属性id为"link2"
soup.find_all(id="link2")

# 查找存在属性id的
soup.find_all(id=True)

#
soup.find_all(href=re.compile("elsie"), id='link1')

# 
soup.find_all(attrs={"data-foo": "value"})

#查找标签文字包含"sisters"
soup.find(string=re.compile("sisters"))

# 获取指定数量的结果
soup.find_all("a", limit=2)

# 自定义匹配方法
def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')
soup.find_all(has_class_but_no_id)

# 仅对属性使用自定义匹配方法
def not_lacie(href):
        return href and not re.compile("lacie").search(href)
soup.find_all(href=not_lacie)

# 调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False 

soup.find_all("title", recursive=False)

확장 메서드

find_parents () 모든 부모 노드
find_parent () 첫 번째 노드 아버지
find_next_siblings () 모든 형제 자매 후
find_next_sibling () 제 형제 노드 후
find_previous_siblings () 이전의 모든 형제 자매
find_previous_sibling () 첫 번째 형제 전에
find_all_next () 의 모든 요소 후
find_next () 첫 번째 요소 후
find_all_previous () 요소의 모든 전
find_previous () 첫 번째 요소 전에

CSS 선택기

아름다운 수프는 대부분의 CSS 선택기가 지원 http://www.w3.org/TR/CSS2/selector.html , 전달 된 문자열 인수 ALL 기타 사항 서보 -OFF 태그 또는 BeautifulSoup로 개체 () 메소드, CSS를 선택할 수 있습니다 찾기 태그의 구문.

html_doc = """
<html>
<head>
  <title>The Dormouse's story</title>
</head>
<body>
  <p class="title"><b>The Dormouse's story</b></p>

  <p class="story">
    Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
    and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.
  </p>

  <p class="story">...</p>
"""

soup = BeautifulSoup(html_doc)

# 所有 a 标签
soup.select("a")

# 逐层查找
soup.select("body a")
soup.select("html head title")

# tag标签下的直接子标签
soup.select("head > title")
soup.select("p > #link1")

# 所有匹配标签之后的兄弟标签
soup.select("#link1 ~ .sister")

# 匹配标签之后的第一个兄弟标签
soup.select("#link1 + .sister")

# 根据calss类名
soup.select(".sister")
soup.select("[class~=sister]")

# 根据ID查找
soup.select("#link1")
soup.select("a#link1")

# 根据多个ID查找
soup.select("#link1,#link2")

# 根据属性查找
soup.select('a[href]')

# 根据属性值查找
soup.select('a[href^="http://example.com/"]')
soup.select('a[href$="tillie"]')
soup.select('a[href*=".com/el"]')

# 只获取一个匹配结果
soup.select(".sister", limit=1)

# 只获取一个匹配结果
soup.select_one(".sister")

라벨 객체 메소드

태그 속성

soup = BeautifulSoup('<p class="body strikeout" id="1">Extremely bold</p><p class="body strikeout" id="2">Extremely bold2</p>')
# 获取所有的 p标签对象
tags = soup.find_all("p")
# 获取第一个p标签对象
tag = soup.p
# 输出标签类型 
type(tag)
# 标签名
tag.name
# 标签属性
tag.attrs
# 标签属性class 的值
tag['class']
# 标签包含的文字内容,对象NavigableString 的内容
tag.string

# 返回标签内所有的文字内容
for string in tag.strings:
    print(repr(string))

# 返回标签内所有的文字内容, 并去掉空行
for string in tag.stripped_strings:
    print(repr(string))

# 获取到tag中包含的所有及包括子孙tag中的NavigableString内容,并以Unicode字符串格式输出
tag.get_text()
## 以"|"分隔
tag.get_text("|")
## 以"|"分隔,不输出空字符
tag.get_text("|", strip=True)

자식 노드를 얻기

tag.contents  # 返回第一层子节点的列表
tag.children  # 返回第一层子节点的listiterator 对象
for child in tag.children:
    print(child)

tag.descendants # 递归返回所有子节点
for child in tag.descendants:
    print(child)

부모 노드를 가져옵니다

tag.parent # 返回第一层父节点标签
tag.parents # 递归得到元素的所有父辈节点

for parent in tag.parents:
    if parent is None:
        print(parent)
    else:
        print(parent.name)

형제를 가져옵니다

# 下一个兄弟元素
tag.next_sibling 

# 当前标签之后的所有兄弟元素
tag.next_siblings
for sibling in tag.next_siblings:
    print(repr(sibling))

# 上一个兄弟元素
tag.previous_sibling

# 当前标签之前的所有兄弟元素
tag.previous_siblings
for sibling in tag.previous_siblings:
    print(repr(sibling))

이송 요소

태그 각각 다운 스프가 "요소"각각의 "요소"하향식 HTML 배치로 정의되면, 태그는 통과 명령으로 하나씩 표시 될 수있다

# 当前标签的下一个元素
tag.next_element

# 当前标签之后的所有元素
for element in tag.next_elements:
    print(repr(element))

# 当前标签的前一个元素
tag.previous_element
# 当前标签之前的所有元素
for element in tag.previous_elements:
    print(repr(element))

label 속성을 수정

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b

tag.name = "blockquote"
tag['class'] = 'verybold'
tag['id'] = 1

tag.string = "New link text."
print(tag)

라벨 내용을 수정 (NavigableString)

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
tag.string = "New link text."

추가 태그 컨텐츠 (NavigableString)

soup = BeautifulSoup("<a>Foo</a>")
tag = soup.a
tag.append("Bar")
tag.contents

# 或者

new_string = NavigableString("Bar")
tag.append(new_string)
print(tag)

추가 의견 (코멘트)

참고 NavigableString 또한 APPEND () 메소드를 통해 추가 될 수 있으며, 특별한 목적으로한다.

from bs4 import Comment
soup = BeautifulSoup("<a>Foo</a>")
new_comment = soup.new_string("Nice to see you.", Comment)
tag.append(new_comment)
print(tag)

추가 태그 (태그)

하나의 특정 태그 (추가 방법)의 내부에 첨가 된 라벨을 추가하는 방법은 두 가지가 있으며, 다른 소정의 위치 (방법 insert_after 인서트 insert_before 등)를 추가하는 것

  • APPEND 방법
    
    soup = BeautifulSoup("<b></b>")
    tag = soup.b
    new_tag = soup.new_tag("a", href="http://www.example.com")
    new_tag.string = "Link text."
    tag.append(new_tag)
    print(tag)
* insert方法,是指在当前标签子节点列表的指定位置插入对象(Tag或NavigableString)
```python
html = '<b><a href="http://example.com/">I linked to <i>example.com</i></a></b>'
soup = BeautifulSoup(html)
tag = soup.a
tag.contents
tag.insert(1, "but did not endorse ")
tag.contents
  • 이전 또는 현재 탭 첨가 원소 insert_before 후 () 및 insert_after ()를 형제 노드의 방법
    
    html = '<b><a href="http://example.com/">I linked to <i>example.com</i></a></b>'
    soup = BeautifulSoup(html)
    tag = soup.new_tag("i")
    tag.string = "Don't"
    soup.b.insert_before(tag)
    soup.b
* wrap() 和 unwrap()可以对指定的tag元素进行包装或解包,并返回包装后的结果。

```python
# 添加包装
soup = BeautifulSoup("<p>I wish I was bold.</p>")
soup.p.string.wrap(soup.new_tag("b"))
#输出 <b>I wish I was bold.</b>

soup.p.wrap(soup.new_tag("div"))
#输出 <div><p><b>I wish I was bold.</b></p></div>

# 拆解包装
markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(markup)
a_tag = soup.a

a_tag.i.unwrap()
a_tag
#输出 <a href="http://example.com/">I linked to example.com</a>

제거 라벨

html = '<b><a href="http://example.com/">I linked to <i>example.com</i></a></b>'
soup = BeautifulSoup(html)
# 清楚当前标签的所有子节点
soup.b.clear()

# 将当前标签及所有子节点从soup 中移除,返回当前标签。
b_tag=soup.b.extract()
b_tag
soup

# 将当前标签及所有子节点从soup 中移除,无返回。
soup.b.decompose()

# 将当前标签替换为指定的元素
tag=soup.i
new_tag = soup.new_tag("p")
new_tag.string = "Don't"
tag.replace_with(new_tag)

다른 방법

수출

# 格式化输出
tag.prettify()
tag.prettify("latin-1")
  • 사용 아름다운 수프가 유니 코드로 변환 된 문서를 구문 분석 한 후, 특수 문자는 유니 코드로 변환됩니다 당신이 문자열로 문서를 변환 할 경우, 유니 코드 인코딩이 올바르게 표시되지 않을 수 있습니다 UTF-8. 이러한 HTML 특수 문자로 인코딩됩니다
  • 유니 코드를 사용하는 경우, 아름다운 수프는 HTML이나 XML 특수 문자로 "인용"스마트 될 것입니다

문서 인코딩

아름다운 수프 현재 문서 인코딩을 식별하기 위해 "자동 인코딩 감지"하위 라이브러리를 사용하고 유니 코드 인코딩 변환 유니 코드로 변환 된 문서를 파싱 사용 후.

soup = BeautifulSoup(html)
soup.original_encoding

# 也可以手动指定文档的编码 
soup = BeautifulSoup(html, from_encoding="iso-8859-8")
soup.original_encoding

# 为提高“编码自动检测”的检测效率,也可以预先排除一些编码
soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])
  • 아름다운 수프 출력 문서를 통해, 상관없이 입력 문서 인코딩, 기본 출력 인코딩이 UTF-8 인코딩

문서 파서

아름다운 수프는 현재 "LXML", "html5lib"및 "html.parser을"지원

soup=BeautifulSoup("<a><b /></a>")
soup
#输出: <html><body><a><b></b></a></body></html>
soup=BeautifulSoup("<a></p>", "lxml")
soup
#输出: <html><body><a></a></body></html>
soup=BeautifulSoup("<a></p>", "html5lib")
soup
#输出: <html><head></head><body><a><p></p></a></body></html>
soup=BeautifulSoup("<a></p>", "html.parser")
soup
#输出: <a></a>

참조 문서

https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh

추천

출처blog.51cto.com/13673090/2466801