目录结构
一、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("-----------------------------------")
执行结果:
网友评论