beautiful soup的用法

  一、beautiful soup 是Python的一个HTML或XML的解析库。

  他提供一个简单的、Python式的函数来处理导航、搜索、修改分析数等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。

  beautiful soup 自动将输入文档转化为Unicode编码,输出文档转化为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时你仅仅需要说明一下原始的编码方式就可以了。

 

from bs4 import BeautifulSoup
soup=BeautifulSoup('<p>hello</p>','lxml')
print(soup.p.string)
# 返回了p标签的内容

html=‘<html>
<head><title>story</title></head>
<body><div>
<p class='t1' name='t2'>我的天,蒙蔽了</p>
</div></body>'

from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.prettiful())    #例子的html节点没有闭合 缺少标签</html>   返回的完整html不是prettiful做的是初始化BeautifulSoup时就完成了
print(soup.title.string)  #返回标题的内容
print(soup.title) #返回的是<title>story</title>
print(soup.head) #<head><title>story</title></head>
prinp(soup.p)    #<p>我的天,蒙蔽了</p>
#当有多个属性时,此种方法只能获取第一个匹配的节点

 

二、提取信息

上面演示了调用string属性来获取文本的值,那么如何获得节点属性的值?

(1)可以利用name属性获取几点的名称,这里还是以上面文本为例,选取title节点然后调用name属性就可以获得节点名称

 

print(soup.title.name)    #title    不懂为什么出这个命令  我可能看不出来吧
(2)获取属性
每个节点都可能有多个属性,比如id和class等,选择这个节点后,可以调用class获取所有属性
print(soup.p.attrs)
print(soup.p.attrs['name']
运行结果如下:
{'class':['t1'],'name':'t2'}
['t2']

print(soup.p['class']
print(soup.p['name']
获取需要的属性

(3)获取内容
可以利用string获取内容
print(soup.p.string)


三、
(1)嵌套选择
上面的语句中返回的都是bs4.element.Tag类型。
所谓嵌套的意思是通过第一个,可以一直找到此节点下的最后一个属性。
ex:
  print(soup.head.title.string)
(2)关联选择
  在做选择时,有时候不能做到一步就选到想要的节点元素。需要以他为基点,再选择它的子节点、父节点、兄弟节点等。
  子节点和子孙节点
  html=''
  from bs4 import BeautifulSoup
  soup=BeautifulSoup(html,'lxml')
  print(soup.p.contents)  #打印的是p节点下的所有节点与内容 包括\n 的一个列表

还可以用children属性得到相应的结果
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.p.children)    得到的是一个生成器所以要想得到结果怎么办呢?<list_iterator object at 0x00000000029C8E80>
for i,child in enumerate(soup.p.children):
  print(i,child)

descendants 得到p节点下的所有属性 包括吧节点<a>aaaa</a>中的内容单独提出来
得到的也是一个生成器需要 去想办法得到其需要的东西

父节点和祖先节点

print(soup.a.parent)    
获取选择的a节点的第一个父节点    直接其节点的代码
print(soup.a.parents)
获得的是a节点外的所有祖先节点  返回的是一个生成器

兄弟节点

print(soup.a.next_sibling)  获取节点的下一个兄弟元素
print(soup.a.previous_sibling)  获取节点的上一个兄弟元素
print(list(enumerate(soup.a.next_siblings)))  获取所有的a节点以后的所有兄弟节点
print(list(enumerate(soup.a.previous_siblings)))  获取所有的a节点以前所有的兄弟节点


方法选择器
find_all()  就是查找所有符合属性的元素,给他传入一些条件就传出,所有符合跳进的元素
它返回的是一个列表,
print(soup.find_all(name='ul')
还可以进行嵌套查询,例如查询里面的li节点
for ul in soup.find_all(name='ul'):
  print(ul.find_all(name='li'))
  for li in ul.find_all(name='li;)
    print(li.string)
  返回了li的所有文本内容


attrs()
除了根据节点名查询,
print(soup.find_all(attrs={'id':'name1'}))
print(soup.find_all(attrs={'name':'elements'}))
这里查询的时候传入的是attrs参数,参数的类型是字典类型,,得到结果是列表形式,包含的内容就是符合条件的节点。

对于一些常用的属性,比如id class 等 我们可以不用attrs来传递。
ex:
from bs4 import BeautifulSoup
soup=Beautiful(html,'lxml')
print(soup.find_all(id='index'))
print(soup.find_all(class_='element'))  
注意:由于class是Python的关键字,所以在这里的class用class_ 来代替
返回的结果依然是列表

text 参数可以用来匹配节点的文本,传入的形式可以是字符串,可以使正则表达式对象。
返回的是文本,不包括节点。

find()
除了find_all()外还有find()方法,只不过后者返回的是单个元素,也就是第一个匹配的元素,而前者返回的是所有匹配的元素组成的列表。

还有很多查询方法:
find_parents()find_parent()    返回所有符合条件的祖先节点/一个
find_next_siblings() find_next_sibling()  后面的兄弟节点
find_previous_siblings()  find_previous_siblings()    前面的兄弟节点
find_all_next()    find_next()    返回所有后面符合条件的节点    一个
find_all_previous  find_previous()  返回所有前面符合条件的节点    一个

CSS选择器
熟悉web开发的肯定熟悉选择器,不熟悉,请自行学习。
使用选择器时,调用select(),传入相应的css选择器即可。
ex:
  print(soup.select('.first .second))  类选择器
  print(soup.select('div ul')    标签选择器
  print(soup.select('#id .first))  id选择器 加类选择器
输出的都是列表
嵌套选择:
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
for ul in soup.select('ul'):
 print(ul.select('li'))  获ul中的li节点
  print(ul['id])    获取属性
  print(ul.attrs['id'])    获取属性

获取文本
print(soup.select('li').get_text())
print(soup.select('li').string())    它俩的效果一致


总结:
  推荐使用lxml,必要时使用lxml.parser
  节点选择筛选功能弱,但速度块
  建议使用find()  find_all()查询单个或者多个结果
  css选择器也是个不错的选择
posted @ 2018-09-03 22:01  都是弟弟  阅读(11249)  评论(0编辑  收藏  举报