Python3 爬虫 BeautifulSoup 使用

BeautifulSoup(from bs4 import BeautifulSoup)

Beautiful Soup就是Python的一个HTML或XML的解析库,可以用它来方便地从网页中提取数据

1、准备工作

  • 安装bs4

  • 安装lxml

  • 参考:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.html#

  • 推荐使用lxml解析库,必要时使用html.parser

  • 节点选择筛选功能弱但速度快

  • 建议使用find()或者find_all()查询单个结果或者多个结果

  • 如果对CSS选择器熟悉的话,可以用select()方法选择

2、BeautifulSoup支持的解析器

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


3、节点选择器

from bs4 import BeautifulSoup

html = """
<html>
    <head><title>The Dormouse's story</title></head>
<body>
    <p class="title" name="dromouse"><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 link4"><span>Elsie</span></a>
        Hello
        <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,"lxml")#初始化BeautifulSoup对象赋值给soup变量,更正html代码格式,补全缺失标签

print(soup.prettify())      #把解析的字符串以标准的缩进格式输出
print(soup.title)#<title>The Dormouse's story</title>
print(type(soup.title))     #bs4.element.Tag类型
print(soup.title.string)    #string属性获取节点文本内容
print(soup.title.name)      #name属性获取节点名称
print(soup.p.attrs)         #atrrs属性获取属性,返回字典
print(soup.p['class'])      #获取节点属性值
print(soup.p['name'])
print(soup.p.contents)      #获取直接子节点,可以调用contents属性,返回形式是列表
print(soup.p.children)      #获取直接子节点,可以调用chhildren属性,返回形式是生成器类型,用for循环输出内容
for i,child in enumerate(soup.p.children):
    print(i, child)
print(soup.p.descendants)   #获取直接子孙节点,可以调用descendants属性,返回形式是生成器类型,用for循环输出内容
for i,child in enumerate(soup.p.descendants):
    print(i, child)
print(soup.a.parent)        #获取第一个a节点的父节点元素,可以调用parent属性
print(soup.a.parents)       #获取祖先节点,可以调用parents属性,返回生成器类型
print(list(enumerate(soup.a.parents)))          #列表输出了它的索引和内容
print('Next sibling',soup.a.next_sibling)       #获取节点下一个兄弟元素,调用next_sibling属性
print('Prev sibling',soup.a.previous_sibling)   #获取节点上一个兄弟元素,调用previous_sibling属性
print('Next siblings',list(enumerate(soup.a.next_sibling)))     #获取节点所有后面兄弟元素,调用next_siblings属性
print('Prev siblings',list(enumerate(soup.a.previous_sibling))) #获取节点所有前面兄弟元素,调用next_siblings属性

4、方法选择器

  • find_all(name, attrs, recursive, text, **kwargs):查找多个

  • 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():返回节点前面所有符合条件的节点,后者返回第一个符合条件的节点

from bs4 import BeautifulSoup
import re

html = """
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<a> Hello,this is a link</a>
<a> Hello,this is a link,too</a>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
"""
soup = BeautifulSoup(html,"lxml")

print(1,soup.find_all('ul'))            #查找所有ul节点,返回列表类型
print(2,type(soup.find_all('ul')[0]))   #bs4.element.Tag类型
for ul in soup.find_all('ul'):
    print(ul.find_all('li'))
    for li in ul.find_all('li'):
        print(li.string)
print(3,soup.find_all(attrs={'id':'list-1'}))       #查询id为list-1的所有节点,返回列表类型
print(4,soup.find_all(id='list-1'))
print(5,soup.find_all(attrs={'name':'elements'}))
print(6,soup.find_all(class_='element'))            #由于class是python的关键字,所以后面需要加一个下划线
print(7,soup.find_all('li',{'class':'element'}))    #等价于上面的一行
print(8,soup.find_all(text=re.compile('link')))     #text参数可用来匹配节点的文本,传入形式可以是字符串或是正则表达式对象
print(9,soup.find('ul'))                            #find()查找的单个元素
print(10,soup.find(class_='list'))

5、CSS选择器

只需要调用 select() 方法,传入相应的CSS选择器即可

from bs4 import BeautifulSoup
import re

html = """
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<a> Hello,this is a link</a>
<a> Hello,this is a link,too</a>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
"""
soup = BeautifulSoup(html, "lxml")

print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))             #选择所有ul节点下面的li节点,返回类型是列表
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))
for ul in soup.select('ul'):
    print(ul['id'])                     #获取每个ul节点的id属性
    print(ul.select('li'))
for li in soup.select('li'):
    print('Get TEXT:',li.get_text())    #获取文本内容
    print('String:',li.string)          #获取文本内容


未经允许请勿转载:程序喵 » Python3 爬虫 BeautifulSoup 使用

点  赞 (0) 打  赏
分享到: