BeautifulSoup库的基本方法和使用详解 Python爬虫中最简单的爬虫解析库

我们在爬虫中需要使用的库-BeautifulSoup库,它的优点是:是一个灵活方便的解析库,处理高效,支持多种解析器。利用它不用编写正则表达式即可方便地实现网页信息的抓取,在很多情况下都可以代替正则

如果你使用的是Pycharm的话,安装方法就比较简单,直接在settings里面安装即可,具体位置就在下面图片中,或者使用命令pip3 install beautifulsoup4,已经更新到4版本了。

BeautifulSoup解析器

解析库使用方法优势劣势
Python标准库BeautifulSoup(markup,”html.parser”)Python内置的标准库,执行速度适中,文档容错能力强Python2.7.3 or 3.2.2前的版本中,文档容错能力差
lxml HTML解析器BeautifulSoup(markup,”lxml”)速度快,文档容错能力强需要安装C语言库
lxml XML解析器BeautifulSoup(markup,”xml”)速度快,唯一支持XML的解析器需要安装C语言库
html5libBeautifulSoup(markup,”html5lib”)最好的容错性,以浏览器的方式解析文档,生成html5格式的文档速度慢,不依赖外部扩展

使用方法非常简单,我们只需要传入html文档,指定解析器即可。

  
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml') #将html字符串传入,指定解析器,自行找html测试
print(soup.prettify())  #格式化代码,让代码更规范
print(soup.title.string)   #选择了title标签

BeautifulSoup标签选择器

选择元素
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.title)  #选择title标签
print(type(soup.title))   #查看title标签的类型,就是Tag类型
print(soup.head)
print(soup.a)   #只会输出第一个a标签
获取标签的名称和属性
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.title.name)  #选择title标签的名称
print(soup.a.attrs['id'])  #.attrs[]用来获取属性
print(soup.menu['type'])  #同上
获取内容和嵌套选择
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.title.string)   #获取title标签的内容
print(soup.html.title.string)  #跟网页的嵌套一样
获取子节点和子孙节点
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.menu.contents)  #子节点就是menu标签里面的内容,返回列表类型
#下面的方法跟上面的一样,都是返回子节点的
print(soup.menu.children)  #.children实际上是一个迭代器,需要用循环的方式
for i,child in enumerate(soup.menu.children): #返回节点的索引和内容
    print(i,child)
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.body.descendants)  #获取子孙节点,返回的同样是个迭代器
for i,child in enumerate(soup.body.descendants):
    print(i,child) #输出body标签里面的所有内容
父节点和祖先节点
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.a.parent)  #返回a标签,和他的父节点
print(soup.a.parents)   #返回的同样也是迭代器,需要采用循环
for i,child in enumerate(soup.a.parents):
    print(i,child)
兄弟节点
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(list(enumerate(soup.a.next_siblings))) #同样需要循环,输出的是a标签
print(list(enumerate(soup.a.previous_siblings))) #输出的是a标签的兄弟标签

可能我对上面的代码解释不够准确,具体的你还需要自己去尝试,然后仔细观察一下返回结果。

这种标签选择器的速度是非常快的,但是这种方式好像并不能满足我们xml文档的需求,过于单一,在后面的爬虫基本很少用

BeautifulSoup标准选择器

find_all(name,attrs,recursive,text,**kwargs)

可以根据标签名,属性,内容查找文档。跟正则表达式类似,找出所有的匹配结果,返回的是一个列表。

name
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.find_all('li'))
print(type(soup.find_all('li')[0]))

find_all()方法就是找出所有符合条件的内容,上面的代码会返回以下图片中的信息

或者使用for循环,来遍历得到的结果,下面的html同上

from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.find_all('li'))
for li in soup.find_all('li'):
    print(li.find_all('a'))
attrs

这种选择方式更加的准确,指定选择的属性

from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.find_all(attrs={"id":"commentCode"}))
print(soup.find_all(attrs={"class":"dropdown-menu"}))
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.find_all(id="commentCode"))
print(soup.find_all(class_="dropdown-menu"))

两种的使用方式都一样,注意它们的不同点,第一种是采用attrs={ }的方式,第二种采用class_=” “,class是Python中的关键字,所以为了区分需要加_

text
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.find_all(text='Python'))  #返回里面的内容
#在做一些内容匹配的时候比较有用
#在查找内容的时候并不好用
find ( name,attrs,recursive,text,**kwargs )

find 返回单个元素,find_all返回所有元素

from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.find('li'))
print(type(soup.find('li')))  #<class 'bs4.element.Tag'>
print(soup.find('ul'))
find_parents( ) 和 find_parent( )

find_parents( )返回所有祖先节点,find_parent( )返回父节点

find_next_siblings( ) 和 find_next_sibling( )

find_next_siblings( )返回后面所有兄弟节点,find_next_sibling( )返回后面第一个兄弟节点

find_previous_siblings( ) 和 find_previous_sibling( )

find_previous_siblings( ) 返回前面所有兄弟节点,find_previous_sibling( )返回前面第一个兄弟节点

find_all_next( ) 和 find_next( )

find_all_next( )返回节点后所有符合条件的节点,find_next( )返回第一个符合条件的节点

find_all_previous( ) 和 find_previous( )

find_all_previous( )返回节点后所有符合条件的节点,find_previous( )返回第一个符合条件的节点

BeautifulSoup CSS选择器

通过select( )直接传入CSS选择器即可完成选择,如果你对html有些了解,那么你就应该知道CSS选择器,这里不再介绍相关内容,简单提示一下,#用来选择id的属性,.用来选择class属性,ul li标签选择前面不用加任何东西

from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.select('.right-box'))
print(soup.select('ul li'))
print(soup.select('#myDrap'))
print(type(soup.select('#myDrap')))  #<class 'list'>
 print(type(soup.select('#myDrap')[0]))     #<class 'bs4.element.Tag'>
获取属性
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
for ul in soup.select('ul'):
    print(soup.select('li'))
print(ul['id'])
print(ul.attrs['id'])
获取内容
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
for li in soup.select('li'):
    print(li.get_text())

基本知识就这么多,我们最后再回顾一下这些基本用法:

(1)根据标签名查找
        - soup.a   只能找到第一个符合要求的标签
(2)获取属性
        - soup.a.attrs  获取a所有的属性和属性值,返回一个字典
        - soup.a.attrs['href']   获取href属性
        - soup.a['href']   也可简写为这种形式
(3)获取内容
        - soup.a.string   /text()
        - soup.a.text   //text()
        - soup.a.get_text()  //text()
       【注意】如果标签还有标签,那么string获取到的结果为None,而其它两个,可以获取文本内容
(4)find:找到第一个符合要求的标签
        - soup.find('a')  找到第一个符合要求的
        - soup.find('a', title="xxx")
        - soup.find('a', alt="xxx")
        - soup.find('a', class_="xxx")
        - soup.find('a', id="xxx")
(5)find_All:找到所有符合要求的标签
        - soup.find_All('a')
        - soup.find_All(['a','b']) 找到所有的a和b标签
        - soup.find_All('a', limit=2)  limit参数限制前两个
(6)根据选择器选择指定的内容
               - soup.select('#feng') 查找id属性为feng的标签
        - 常见的选择器:标签选择器(a,head,article,body,p)、class选择器(.)、id选择器(#)、层级选择器
            - 层级选择器:
                div .dudu #选择所有div下面class属性为dudu的标签
                div > p > a > .lala          只能是下面一级  div/img
        【注意】select选择器返回永远是列表,需要通过下标提取指定的对象
总结

好了,BeautifulSoup库的内容基本上就这些,看起来也是比较多的,要求全部记住也是不可能的,你可以根据自己的情况选择,这里我也做了以下总结:

  • 推荐使用lxml解析库,也可以使用html.parser
  • 标签选择筛选功能单一,但是速度快
  • 建议使用find( ),find_all( )查询匹配单个结果或者多个结果
  • 如果熟悉CSS选择器,那么尽量使用select( )
  • 记住常用的获取属性,文本的方法,多加练习

发表评论