美文网首页Python
[CP_11] Python数据清洗之BeautifulSoup

[CP_11] Python数据清洗之BeautifulSoup

作者: Fighting_001 | 来源:发表于2019-04-06 18:13 被阅读0次

目录结构

一、BeautifulSoup功能应用
    1. BeautifulSoup简介&安装
    2. 获取标签信息
    3. 搜索文档树(整个标签的文档结构)
    4. CSS选择器
二、BeautifulSoup模块应用案例
    案例:获取某社招网站职位的详细信息

一、BeautifulSoup功能应用

1. BeautifulSoup简介&安装

CSS选择器:BeautifulSoup4
与lxml类似,BeautifulSoup也是一个HTML/XML解析器,其主要功能也是解析和提取HTML/XML数据。为了支持BeautifulSoup的使用,需要安装bs4。

安装bs4:

pip install bs4

BeautifulSoup使用:
bs4-001.py

from bs4 import BeautifulSoup

html='''
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">BeautifulSoup主题内容</a></p>
<ul class="simple">
<li><a class="reference" href="link2" id="id2">Element APIs</a></li>
<li><a class="reference" href="link3" id="id3">Trees Documents</a></li>
</ul>
</div>
'''

# 解析字符串形式的html
soup1=BeautifulSoup(html,"lxml")
print(soup1)

print("-------------")

# 格式化输出soup对象(美化层次感)
print(soup1.prettify())

bs4-002.py

from bs4 import BeautifulSoup

# 解析本地html文件
soup=BeautifulSoup(open(r"D:\CI_Env\Python_Test\file\test.html","r",encoding="UTF-8"))

print(soup)

2. 获取标签信息

根据标签名获取标签信息:soup.标签名
获取标签内容:soup.标签名.string
获取标签名:soup.标签名.name
获取标签内所有属性(默认第1个指定的标签):soup.标签名.attrs
获取标签内指定的属性值:soup.标签名.attrs['属性名']
获取直接下属的子标签(列表类型):soup.标签名.contents
从Python生成器(generator)中获取子标签:soup.标签名.children
从Python生成器(generator)获取所有子标签:soup.标签名.descendants

childTag.py

from bs4 import BeautifulSoup

html='''
<div class="contents topic">
<p class="topic-title"><a id="contents" name="contents">BeautifulSoup主题内容</a></p>
<ul class="simple">
<li><a class="reference" href="link2" id="id2">Element APIs</a></li>
<li><a class="reference" href="link3" id="id3">Trees Documents</a></li>
</ul>
</div>
'''

# 解析字符串形式的html
soup=BeautifulSoup(html,"lxml")

# 根据标签名获取标签信息:soup.标签名
print(soup.p)

# 获取标签内容
print(soup.p.string)

# 获取标签名
print(soup.p.name)

# 获取标签内所有属性(默认第1个指定的标签)
print(soup.a.attrs)

# 获取标签内指定的属性值
print(soup.a.attrs['name'])

# 获取直接下属的子标签(列表类型)
print(soup.li.contents)

# 从Python生成器(generator)中获取子标签
for i in soup.li.children:
    print(i)

# 从Python生成器(generator)获取所有子标签
for i in soup.p.descendants:
    print(i)

3. 搜索文档树(整个标签的文档结构)

查找指定的所有标签,返回一个结果集ResultSet,其中保存标签对象:soup.find_all("标签名")

docTree-001.py

from bs4 import BeautifulSoup

html='''
<div class="contents topic">
<p class="topic-title"><a id="contents" name="contents">BeautifulSoup主题内容</a></p>
<ul class="simple">
<li><a class="reference" href="link2" id="id2">Element APIs</a></li>
<li><a class="reference" href="link3" id="id3">Trees Documents</a></li>
</ul>
</div>
'''

# 解析字符串形式的html
soup=BeautifulSoup(html,"lxml")

# 查找所有的a标签,返回一个结果集ResultSet,其中保存标签对象
data=soup.find_all("a")
print(type(data))

print("---------------------")

# 打印a标签组成的列表集
print(data)

print("---------------------")

# 遍历获取data列表集中的每个a标签内容
for i in data:
    print(i.string)

根据正则查找标签名:soup.find_all(re.compile("匹配规则"))
根据属性查找标签:soup.find_all(属性名='属性值')
根据指定的标签内容获取明确的标签内容:soup.find_all(text=re.compile("匹配规则"))

docTree-002.py

from bs4 import BeautifulSoup
import re

html='''
<div class="contents topic">
<p class="topic-title"><a id="contents" name="contents">BeautifulSoup主题内容</a></p>
<ul class="simple"><u>u标签内容</u>
<li><a class="reference" href="link2" id="id2">Element APIs</a></li>
<li><a class="reference" href="link3" id="id3">Trees Documents</a></li>
</ul>
</div>
'''

# 解析字符串形式的html
soup=BeautifulSoup(html,"lxml")

# 根据正则查找标签名
pat=re.compile("^u")    # 以u开头的标签
data1=soup.find_all(pat)
for i in data1:
    print(i.string)

print("------------------------")

# 根据属性查找标签
data2=soup.find_all(id="id2")
for i in data2:
    print(i)

print("-------------------------")

# 根据指定的标签内容获取明确的标签内容
data3=soup.find_all(text=re.compile("Doc.*?"))
print(data3)

4. CSS选择器

根据css样式表来查找标签,对应使用的方法为:select()
CSS选择器类型:标签、类、id-选择器

通过标签名获取标签(列表类型):soup.select("标签名")
通过类名查找:soup.select(".类名")
通过id查找:soup.select("#{id取值}")
联合查找(查找某个标签下满足属性值的标签):soup.select("标签名 属性值")
通过其他属性查找满足某个属性条件的指定标签信息:soup.select('标签名[属性名="属性值"]')

cssSelect.py

from bs4 import BeautifulSoup
import re

html='''
<div class="contents topic">
<p class="topic-title"><a id="contents" name="contents">BeautifulSoup主题内容</a></p>
<ul class="simple">
<li><a class="reference" href="link1" id="id1">ID001</a></li>
<li><a class="reference" href="link2" id="id2">Element APIs</a></li>
<li><a class="reference" href="link3" id="id3">Trees Documents</a></li>
</ul>
</div>
'''

# 解析字符串形式的html
soup=BeautifulSoup(html,"lxml")

# 通过标签名获取标签
data1=soup.select("a")
print(type(data1))  # 列表类型
print(data1)

print("-------------------")

# 通过类名查找
data2=soup.select(".reference")
print(data2)

print("-------------------")

# 通过id查找
data3=soup.select("#id3")
print(data3)

print("-------------------")

# 联合查找:查找li标签下id="id1"的标签
data4=soup.select("li #id1")
print(data4)

print("-------------------")

# 通过其他属性查找满足某个属性条件的指定标签信息
data5=soup.select('a[href="link2"]')
print(data5)

二、BeautifulSoup模块应用案例

案例:获取某社招网站职位的详细信息

目标:从某社招网站爬取每个职位的详细信息(职位|工作职责|工作要求)

分析:

从网站翻页查找列表中的每个职位标题,从每个标题点击进入对应详细页,定位到职位详细内容区域,获取所需的文本内容

页码链接:
https://hr.tencent.com/position.php?keywords=&lid=0&start=0#a
https://hr.tencent.com/position.php?keywords=&lid=0&start=10#a
https://hr.tencent.com/position.php?keywords=&lid=0&start=20#a
==> start=(页码-1)*10

列表页-职位标题:

详细页-职位信息:

代码实现:

searchJob.py

from bs4 import BeautifulSoup
import urllib
from urllib import request

header={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"}

# 遍历前20页数据
for i in range(0,20):
    page=10*i
    start={"start":page}
    start=urllib.parse.urlencode(start) # 解析url的参数项
    url="https://hr.tencent.com/position.php?"+start+"#a"   # 拼接列表页的完整url

    req=urllib.request.Request(url,headers=header)  # 创建每一页链接的请求对象
    resp=urllib.request.urlopen(req).read().decode()    # 发送请求,获取响应

    soup=BeautifulSoup(resp,"lxml") # 解析字符串形式的响应数据
    data=soup.select('td a[target="_blank"]')   # 定位到职位名称所在的标签
    # 遍历获取每个职位名称对应的href属性
    for i in data:
        myurl="https://hr.tencent.com/"+i.attrs["href"] # 拼接完整的详细页访问url
        req2=urllib.request.Request(myurl,headers=header)
        resp2=urllib.request.urlopen(req2).read().decode()

        soup2=BeautifulSoup(resp2,"lxml")
        name=soup2.select('tr td[id="sharetitle"]') # 定位到职位名称所在的标签(列表类型)
        describe=soup2.select('ul[class="squareli"] li')    # 定位到职位职责和要求描述的标签(列表类型)

        text=""
        for i in describe:  # 遍历获取职位描述标签中的所有描述信息作为一个整体
            text=text+i.text

        print(name[0].string)   # 职位名称-文本内容
        print(text) # 职位描述-文本内容
        print("-----------------------------------")

执行结果:

相关文章

网友评论

    本文标题:[CP_11] Python数据清洗之BeautifulSoup

    本文链接:https://www.haomeiwen.com/subject/ghbhiqtx.html