Python3爬虫(六) 解析库的使用之Beautiful Soup

 Infi-chu:

http://www.cnblogs.com/Infi-chu/

 

Beautiful Soup

借助网页的结构和属性等特性来解析网页,这样就可以省去复杂的正则表达式的编写。

Beautiful Soup是Python的一个HTML或XML的解析库。

1.解析器

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

综上所述,推荐lxml HTML解析器

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>Hello World</p>','lxml')
print(soup.p.string)

2.基本用法:

html = '''
<html>
<head><title>Infi-chu example</title></head>
<body>
<p class="title" name="dr"><b>title example</b></p>
<p class="story">link
<a href="http://example.com/elsie" class="sister" id="link1">elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">lacie</a>,
<a href="http://example.com/tillie" class="sister" id="link3">tillie</a>,
last sentence</p>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.prettify())    # 修复html
print(soup.title.string)    # 输出title节点的字符串内容

3.节点选择器:

选择元素

使用soup.元素的方式获取

 

提取信息

(1)获取名称

使用soup.元素.name获取元素名称

(2)获取属性

使用soup.元素.attrs

使用soup.元素.attrs['name']

(3)元素内容

使用soup.元素.string获取内容

 

嵌套选择

使用soup.父元素.元素.string获取内容

 

关联选择

(1)子节点和子孙节点

html = '''
<html>
<head><title>Infi-chu example</title></head>
<body>
<p class="title" name="dr"><b>title example</b></p>
<p class="story">link
<a href="http://example.com/elsie" class="sister" id="link1"><span>elsie</span></a>,
<a href="http://example.com/lacie" class="sister" id="link2"><span>lacie</span></a>,
<a href="http://example.com/tillie" class="sister" id="link3"><span>tillie</span></a>,
last sentence</p>
'''
from bs4 import BeautifulSoup
# 得到直接子节点,children属性
soup = BeautifulSoup(html,'lxml')
print(soup.p.children)
for i ,child in enumerate(soup.p.children):
    print(i,child)

# 得到所有的子孙节点,descendants属性
soup = BeautifulSoup(html,'lxml')
print(soup.p.descendants)
for i,child in enmuerate(soup.p.descendants):
    print(i,child)

(2)父节点和祖先节点

调用父节点,使用parent属性

获取所有祖先节点,使用parents属性

(3)兄弟节点

next_sibling  下一个兄弟元素

previous_sibling  上一个兄弟元素

next_siblings  所有前面兄弟节点

previous_siblings  所有后面兄弟节点

(4)提取信息

 

4.方法选择器:

find_all()

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

(1)name

soup.find_all(name='ul')
for ul in soup.find_all(name='ul'):
    print(ul.find_all(name='ul'))
for ul in soup.find_all(name='ul'):
    print(ul.find_all(name='li'))
    for li in ul.find_all(name='li'):
        print(li.string)

(2)attes

# 根据节点名查询
print(soup.find_all(attrs={'id':'list1'}))
print(soup.find_all(attrs={'name':'elements'}))

# 也可以写成
print(soup.find_all(id='list1'))
print(soup.find_all(class='elements'))

(3)text

text参数可以用来匹配节点的文本,传入的形式可以是字符串,可以是正则表达式对象

from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.find_all(text=re.compile('link')))

 

find()

返回一个元素

【注】

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()

 

5.CSS选择器:

嵌套选择

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

获取属性

for ul in soup.select('ul'):
    print(ul['id'])
    # 等价于
    print(ul.attrs['id'])

获取文本

获取文本除了string属性还有get_text()方法

for li in soup.select('li'):
    # 效果一样
    print(li.get_text())
    print(li.string)

 

posted @ 2018-05-02 01:22  Infi_chu  阅读(838)  评论(0编辑  收藏  举报