解析库

解析器 使用方法 优势 劣势
Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库、执行速度适中 、文档容错能力强 Python 2.7.3 or 3.2.2)前的版本中文容错能力差
lxml HTML 解析器 BeautifulSoup(markup, "lxml") 速度快、文档容错能力强 需要安装C语言库
lxml XML 解析器 BeautifulSoup(markup, "xml") 速度快、唯一支持XML的解析器 需要安装C语言库
html5lib BeautifulSoup(markup, "html5lib") 最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档 速度慢、不依赖外部扩展

基本使用

html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<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">
<span>Elsie</span>
</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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())
print(soup.title.string)

标签选择器

选择元素

print(soup.title)
print(type(soup.title))
print(soup.head)
print(soup.p)

获取名称

print(soup.title.name)

title

获取属性

print(soup.p.attrs['name'])
print(soup.p['name'])

dromouse

dromouse

获取内容

print(soup.p.string)

The Dormouse's story

嵌套选择

print(soup.head.title.string)

The Dormouse's story

子节点和子孙节点

print(soup.p.contents)

['\n Once upon a time there were three little sisters; and their names were\n ', Elsie, '\n', Lacie, ' \n and\n ', Tillie, '\n and they lived at the bottom of a well.\n ']

print(soup.p.children)
for i,child in enumerate(soup.p.children):
print(i,child)

父节点和祖先节点

print(soup.a.parent)

Once upon a time there were three little sisters; and their names were
Elsie
Lacie
and
Tillie
and they lived at the bottom of a well.

print(list(enumerate(soup.a.parents)))

兄弟节点

print(list(enumerate(soup.a.next_siblings))
print(list(enumerate(soup.a.previous_siblings)))

[(0, '\n'), (1, Lacie), (2, ' \n and\n '), (3, Tillie), (4, '\n and they lived at the bottom of a well.\n ')]

[(0, '\n Once upon a time there were three little sisters; and their names were\n ')]

标准选择器

find_all(name,attrs,recursive,text,**kwargs)

可根据标签名、属性、内容查找文档

name

html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all('ul'))
print(type(soup.find_all('ul')[0]))
for ul in soup.find_all('ul'):
print(ul.find_all('li'))

attrs

print(soup.find_all(attrs={'id': 'list-1'}))
print(soup.find_all(attrs={'name': 'elements'}))
print(soup.find_all(id='list-1'))
print(soup.find_all(class_='element'))

text

print(soup.find_all(text='Foo'))

find( name , attrs , recursive , text , **kwargs )

find返回单个元素,find_all返回所有元素

print(soup.find('ul'))
print(type(soup.find('ul')))
print(soup.find('page'))

find_parents() find_parent()

find_parents()返回所有祖先节点,find_parent()返回直接父节点。

find_next_siblings() find_next_sibling()

find_next_siblings()返回后面所有兄弟节点,find_next_sibling()返回后面第一个兄弟节点。

find_previous_siblings() find_previous_sibling()

find_previous_siblings()返回前面所有兄弟节点,find_previous_sibling()返回前面第一个兄弟节点。

find_all_next() find_next()

find_all_next()返回节点后所有符合条件的节点, find_next()返回第一个符合条件的节点

find_all_previous() 和 find_previous()

find_all_previous()返回节点后所有符合条件的节点, find_previous()返回第一个符合条件的节点

CSS选择器

通过select()直接传入CSS选择器即可完成选择

print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0])) [<div class="panel-heading">
<h4>Hello</h4>
</div>]
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
<class 'bs4.element.Tag'>
for ul in soup.select('ul'):
print(ul.select('li')) [<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])

list-1

list-1

list-2

list-2

获取内容

for li in soup.select('li'):
print(li.get_text())

Foo

Bar

Jay

Foo

Bar

总结

  • 推荐使用lxml解析库,必要时使用html.parser
  • 标签选择筛选功能弱但是速度快
  • 建议使用find()、find_all()查询匹配单个结果或者多个结果
  • 如果对CSS选择器熟悉建议使用select()
  • 记住使用的获取属性和文本值得方法

参考来源:https://cuiqingcai.com/5548.html

最新文章

  1. laravel的门面模式
  2. Java与C++程序在编译和运行上的区别
  3. php 以图搜图
  4. 在Oracle Linux上使用DTrace的相关指导
  5. Java编程思想学习(八) 内部类
  6. Unique Paths | &amp; ||
  7. 为什么要CGI
  8. HDU 4604 Deque 最长子序列
  9. 什么是BIG?如何买BIG?
  10. Windows核心编程&amp;线程
  11. 【MySQL 读书笔记】普通索引和唯一索引应该怎么选择
  12. 网络协议 9 - TCP协议(下):聪明反被聪明误
  13. egret编译 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed process out of memory解决
  14. asp.net core web 项目附加进程调试
  15. shell编程-文件包含(十)
  16. 数据层的多租户浅谈(SAAS多租户数据库设计)
  17. .NETCore_初探
  18. cache line 伪共享
  19. win10 修改root文件
  20. php 统计fasta 序列长度和GC含量

热门文章

  1. (转)OpenFire源码学习之六:用户注册
  2. 在Linux下安装PyEmu
  3. HDU 6685 Rikka with Coin (枚举 思维)
  4. ASP.NET中ajax验证用户名和邮箱是否重复
  5. 利用dynamic解决匿名对象不能赋值的问题
  6. 2019-10-10-dotnet-新-sdk-style-项目格式的一些命名空间和引用
  7. 链表vector
  8. mfc中的_T
  9. vue $emit 子传父
  10. laravel passport client_credentials