BeautifulSoup4库

BeautifulSoup4库

和lxml一样,Beautiful Soup也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML数据。
lxml只会局部遍历,而Beautiful Soup是基于HTMLDOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。
BeautifulSoup用未解析HTML比较简单,AP非常人性化,支持CSS选择器、Python标准库中的HTML解析器,也支持lxml的XML解析器。
Beautiful Soup3目前已经停止开发,推荐现在的项目使用Beautiful Soup 4。

解析工具

解析工具 解析速度  使用难度
BeautifulSoup 最慢 最简单
lxml 简单
re正则 最快  

简单使用:

import requests
from bs4 import BeautifulSoup
url = "https://baike.baidu.com/item/%E7%99%BE%E5%BA%A6%E7%99%BE%E7%A7%91"
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
    "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
}

url1 = requests.get(url, headers=headers)
url1.encoding="urf-8"           #适用于文字出现乱码
soup = BeautifulSoup(url1.text,'lxml')
'''
print(soup.title)            #输出标题(标签)
print(soup.a.string)            #输出a标签内的文字
print(soup.p.attrs)             #输出p标签的所有属性 得到的类型是一个字典  如果想单独获得一个属性 :soup.p['class']
#遍历文档树
print(soup.head.contents)         # .content 属性可以将tag的子节点以列表的方式输出
#print(soup.head.children)          通过遍历获取所有子节点
for child in soup.body.children:
    print(child)
for child in soup.descendants:
    print(child)
    
for string in soup.stripped_strings:
    print(repr(string))     #可以去除多余空白内容

content = soup.head.title.string
for parent in  content.parents:
    print(parent.name)          #全部父节点
'''
for sibling in soup.a.next_siblings:
    print(repr(sibling))

提取数据

from bs4 import BeautifulSoup

text = """
<table class="tablelist" cellpadding="0" cellspacing="0">
                <tbody><tr class="h">
                    <td class="l" width="374">职位名称</td>
                    <td>职位类别</td>
                    <td>人数</td>
                    <td>地点</td>
                    <td>发布时间</td>
                </tr>
                                <tr class="even">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44606&amp;keywords=技术&amp;tid=0&amp;lid=0">MIG09-QQ浏览器视频前端开发工程师</a></td>
                    <td>技术类</td>
                    <td>1</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="odd">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44599&amp;keywords=技术&amp;tid=0&amp;lid=0">17520-U3D手游客户端开发</a></td>
                    <td>技术类</td>
                    <td>2</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="even">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44602&amp;keywords=技术&amp;tid=0&amp;lid=0">22989-腾讯云高级文档开发经理(深圳)</a></td>
                    <td>产品/项目类</td>
                    <td>2</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="odd">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44604&amp;keywords=技术&amp;tid=0&amp;lid=0">18796-Android开发工程师(深圳)</a><span class="hot">&nbsp;</span></td>
                    <td>技术类</td>
                    <td>1</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="even">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44591&amp;keywords=技术&amp;tid=0&amp;lid=0">29050-数据安全经理/专家(北京)</a></td>
                    <td>职能类</td>
                    <td>2</td>
                    <td>北京</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="odd">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44587&amp;keywords=技术&amp;tid=0&amp;lid=0">29050-CII政策发展经理</a></td>
                    <td>职能类</td>
                    <td>2</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="even">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44588&amp;keywords=技术&amp;tid=0&amp;lid=0">29050-CII政策发展经理</a></td>
                    <td>职能类</td>
                    <td>2</td>
                    <td>北京</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="odd">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44590&amp;keywords=技术&amp;tid=0&amp;lid=0">29050-数据安全经理/专家(深圳)</a></td>
                    <td>职能类</td>
                    <td>2</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="even">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44581&amp;keywords=技术&amp;tid=0&amp;lid=0">28994-区块链底层开发工程师(深圳)</a></td>
                    <td>技术类</td>
                    <td>2</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="odd">
                    <td class="l square"><a target="_blank" href="position_detail.php?id=44583&amp;keywords=技术&amp;tid=0&amp;lid=0">29050-CII产品合规经理</a></td>
                    <td>职能类</td>
                    <td>2</td>
                    <td>深圳</td>
                    <td>2018-10-01</td>
                </tr>
                                <tr class="f">
                    <td colspan="5">
                        <div class="left">共<span class="lightblue total">1184</span>个职位</div>
                        <div class="right"><div class="pagenav"><a href="javascript:;" class="noactive" id="prev">上一页</a><a class="active" href="javascript:;">1</a><a href="position.php?keywords=技术&amp;start=10#a">2</a><a href="position.php?keywords=技术&amp;start=20#a">3</a><a href="position.php?keywords=技术&amp;start=30#a">4</a><a href="position.php?keywords=技术&amp;start=40#a">5</a><a href="position.php?keywords=技术&amp;start=50#a">6</a><a href="position.php?keywords=技术&amp;start=60#a">7</a><a href="position.php?keywords=技术&amp;start=70#a">...</a><a href="position.php?keywords=技术&amp;start=1180#a">119</a><a href="position.php?keywords=技术&amp;start=10#a" id="next">下一页</a><div class="clr"></div></div></div>
                        <div class="clr"></div>
                    </td>
                </tr>
            </tbody>
</table>
"""
soup = BeautifulSoup(text,'lxml')
#  1.获得所有tr标签
# trs = soup.find_all('tr')                 #find_all('tr',limit=2) limit为上限值   意思是只获得2个tr标签
# for tr in trs:
#     print(tr)

# 2.获取第二个标签
# tr = soup.find_all('tr')[1]
# print(tr)

# 3.获取所有class等于even的tr标签
# (方法1)
# trs = soup.find_all('tr',class_='even')         #class后必须加_  对python关键字进行区分
# for tr in trs:
#     print(tr)
# (方法2)
# trs = soup.find_all('tr',attrs={'class':"even"})      #指定字典的显示匹配
# for tr in trs:
#     print(tr)

# 4.将所有id等于prev,class等于noactive的a标签提取出来
# trs = soup.find_all('a',class_='noactive',id='prev')          #多个条件 或 trs = soup.find_all('a',attrs={"id":"prev","class":"noactive"})
# for tr in trs:
#     print(tr)

# 5.获得所有a标签的href属性
# alist = soup.find_all('a')
#
# for a in alist:
# # (1).通过下标操作的方式
#     # href=a['href']          #下标方式
#     # print(href)
# # (2).通过attrs属性的方式
#     href= a.attrs['href']
#     print(href)

# 6.获取职位信息
trs = soup.find_all("tr")[1:]   #第0个(地址)tr标签过滤
movies = []
for tr in trs:
    movie = {}
    #(方法1)
    # tds = tr.find_all("td")
    # print(tds[1].string)
    # title = tds[0].string
    # category = tds[1].string
    # nums = tds[2].string
    # city = tds[3].string
    # pubtime = tds[4].string
    # movie['title'] = title
    # movie['category'] = category
    # movie['nums'] = nums
    # movie['city'] = city
    # movie['pubtime'] = pubtime
    # movies.append(movie)
    #(方法2)
    infos = list(tr.stripped_strings)       #获取所有非空白字符(过滤空格、回车等字符)
    movie['title'] = infos[0]
    movie['category'] = infos[1]
    movie['nums'] = infos[2]
    movie['city'] = infos[3]
    movie['pubtime'] = infos[4]
    movies.append(movie)
print(movies)
#BeautifulSoup笔记:
##find_a11的使用:
1.在提取标签的时候,第一个参数是标签的名字。然后如果在提取标签的时候想要使用标签属性进行过滤,那么可以在这个方法中通过关键字参数的形式,将属性的名字以及对应的值传进去。或者是使用“attrs“属性,将所有的属性以及对应的值放在一个字典中传给attrs 属性。
2.有些时候,在提取标签的时候,不想提取那么多,那么可以使用‘1imit'参数。限制提取多少个。
##find与find_a11的区别:
1.find:找到第一个满足领件的标签就返回。说白了,就是只会返回一个元素。
2.find_al1:将所有满足条件的标签都返回。说白了,会返回很多标签(以列表的形式)
##使用find和find_al1的过滤条件:
1.关键字参数:将属性的名字作为关键字参数的名字,以及属性的值作为关键字参数的值进行过滤
2.attrs参数:将属性条件放到一个字典中,传给attrs参数。

##strings和stripped_strings、string属性以及get_text方法:
1.string:获取某个标签下的非标签字符串。
2.strings:获取某个标签下的子孙非标签字符串。
2.stripped_strings:获取某个标签下的子孙非标签字符串,会去掉空白字符。
4.get_text:获取某个标签下的子孙非标签字符串。不是以列表的形式返回。
eg: tr=soup.find_all('tr')[1]
text=tr.get_text()

猜你喜欢

转载自www.cnblogs.com/c-pyday/p/9760984.html