上节讲解了如何用requests请求网页,本节讲解如何使用bs4对请求到的页面内容进行解析从而获取到所需信息
这里只讲解bs4模块中最常见的使用方法,如果想要更深入的了解,请查看beautifulSoup手册;同时本节还需要有一定的html和css的知识,如果想了解这方面基础的可以查看我在“web前端”的相应文章
下面正式开始:
使用bs4有什么用呢,我们知道使用requests下载下来的页面是一大堆的代码,可是我们真正想要的可能只是里面的某一段文字,比如,标题,作者,文章内容等等。而bs4就可以帮助我们从这么一大段内容中获取到我们想要的内容,当然我们要提供给bs4这些内容的位置,告诉她这个内容在哪些html标签中,在那个id或者哪个class所在的标签中。
首先要pip安装bs4模块
pip install bs4
假如你现在的页面中有这么一段a标签的内容,那么我们现在使用bs4获取到这个标签以及它的相关信息
from bs4 import BeautifulSoup
content = """Python"""
#创建beautifulSoup对象
soup = BeautifulSoup(
content, #HTML文档字符串
'html.parser' #指定HTML解析器
)
#搜索节点 语法为find_all(name,attrs,string)
#搜索所有标签为a的节点
node = soup.find_all("a")
#搜索所有标签为a,链接符合/view/123.htm形式的节点
node = soup.find_all("a",href="/view/123.html")
#还可以用正则
node = soup.find_all("a",href=re.compile(r"/view/d+.html"))
#加了r,有反斜线的时候我们只用写一个不用写两个
#搜索所有标签为a,class为abc,文字为Python的节点
node = soup.find_all("a",class_="abc",string="Python")
#class_="abc"加了下划线是因为class是关键字,为了避免冲突
#访问节点信息
print(node.name) #获取标签名称
print(node['href']) #获取查到的节点属性值
print(node.get_text()) #获取链接中的文字
find_all会搜索到所有符合的节点;find只会找一个
find_all返回一个数组里面包含多个对象;find只返回一个对象
如果有多个条件例如,title为container,class为main-box的一个div想要获取这个节点可以这样
div_tag = soup.find("div",attrs={"title":"container","class":"main-box"})
下面再举一个例子:
import re
from bs4 import BeautifulSoup
#试验beautiful Soup
html_doc = """
The Dormouse's story
The Dormouse's story
Once upon a time there were three little sisters; and their names were Elsie, Lacie and 你好吗; and they lived at the bottom of a well.
...
如果想将一个节点和里面的内容变成字符串可以
cont_div = soup.find("div",class_="cont")
cont_div = str(cont_div)
是么时候会需要将节点和里面的内容变成字符串呢? 当我们采集一大段文字,如文章内容,里面会有很多标签,不太好将里面所有标签中的纯文本提取出来,此时就可以用这种方式将整个节点都变成字符串然后放到数据库中
bs4的一些其他操作
打开html文件进行解析:
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('test.html')) #也可以传入文件对象
print(soup.prettify) #返回整段HTML内容
print(soup.title) #显示
xxx,但其实他返回的是一个节点对象 print(soup.title.name) #返回标签名 print(soup.title.string) #获取title标签的innerHTML内容 print(soup.a.string) #如果他有多个a标签,这样写就会获取第一个a标签 for items in soup.body.contents: print(item) print(item.name) #contents属性会返回这个元素下的所有的子元素节点,包括换行也算子节点 #但是不包含子孙节点
也可以使用css选择器获取节点: 使用select()方法
print(soup.select(".sister")) #获取class为sister的节点,返回的是一个列表包含着节点对象。有点类似jQuery的CSS选择器
print(soup.select("#link1")) #根据id找,返回的还是个列表
print(soup.select("p > a")) #找p下的子元素的a标签
#反正jQuery的选择器可以怎么写,这里就能怎么写
#因为返回的列表中是节点对象,所以这些节点对象还可以继续用select()来找里面的元素
sister = soup.select(".sister")
sister_son_p = sister[0].select("p")
PS:如果使用了select所获取到的节点想再往里面获取节点只能用select和find方法 而不能用findall方法
那么beautifulSoup说到这里就差不多够用了,如果想更深入了解可以查看bs4官网提供的文档