Python 爬虫解析库的使用

  • 2020 年 2 月 13 日
  • 筆記

解析库的使用–Beautiful Soup:

  • BeautifulSoup是Python的一个HTML或XML解析库,最主要的功能就是从网页爬取我们需要的数据。
  • BeautifulSoup将html解析为对象进行处理,全部页面转变为字典或者数组,相对于正则表达式的方式,可以大大简化处理过程。
  • Beautiful Soup3 目前已经停止开发,我们推荐在现在的项目中使用Beautiful Soup4,

1. BeautifulSoup 安装与使用:

  • Beautiful Soup是一个依赖于lxml的解析库,所以在安装之前要先确保lxml库已安装:pip install lxml
  • 安装 BeautifulSoup 解析器:
pip install beautifulsoup4  
  • 官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/
  • 中文文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
  • PyPI: https://pypi.python.org/pypi/beautifulsoup4
  • 主要的解析器,以及它们的优缺点:

解析器

使用方法

优势

劣势

Python标准库

BeautifulSoup(markup, "html.parser")

Python的内置标准库,执行速度适中,文档容错能力强

Python 2.7.3 or 3.2.2前的版本中文档容错能力差

lxml HTML 解析器

BeautifulSoup(markup, "lxml")

速度快 文档容错能力强

需要安装C语言库

lxml XML 解析器

BeautifulSoup(markup, ["lxml-xml"])BeautifulSoup(markup, "xml")

速度快 唯一支持XML的解析器

需要安装C语言库

html5lib

BeautifulSoup(markup, "html5lib")

最好的容错性,以浏览器的方式解析文档,生成HTML5格式的文档

速度慢、不依赖外部扩展

  • lxml解析器有解析html和xml的功能,而且速度快,容错能力强,故推荐使用。
  • 快速使用案例:
# 导入模块  from bs4 import BeautifulSoup    # 读取html文件信息(在真实代码中是爬取的网页信息)  f = open("./my.html",'r',encoding="utf-8")  content = f.read()  f.close()    # 创建解析器  soup = BeautifulSoup(content,"lxml")    # 输出网页内容:注:此内容已被缩进格式化(自动更正格式),其实这个是在上一步实例化时就已完成  print(soup.prettify())    #输出网页中title标签中的内容  print(soup.title.string)  

2. 节点选择器:

  • 直接调用节点的名称就可以选择节点元素,再调用string属性就可以得到节点内的文本了,这种方式速度非常快。
  • ① 选择元素:
...  print(soup.title) #<title>我的网页</title>  print(type(soup.title)) #<class 'bs4.element.Tag'>  print(soup.head) #获取整个head元素,及内部元素  print(soup.li) #获取第一个li元素(后面其他li不会获取)  # <li class="item-0"><a class="bb" href="http://www.baidu.com">百度</a></li>  
  • ② 提取信息:
...  print(soup.a) #获取第一个a元素标签:<a class="bb" href="http://www.baidu.com">百度</a>  print(soup.a.name)    #获取标签名:a  print(soup.a.attrs)    #获取所有属性:{'class': ['bb'], 'href': 'http://www.baidu.com'}  print(soup.a.attrs['href']) #获取其中一个属性:http://www.baidu.com  print(soup.a.string) # 获取元素标签中间的文本内容:百度  
  • ③ 嵌套选择:
print(soup.li.a) #获取网页中第一个li中的第一个a元素节点  #输出 <a class="bb" href="http://www.baidu.com">百度</a>    print(type(soup.body.h3))  ##获取body中的第一个h3元素的类型:<class 'bs4.element.Tag'>  print(soup.body.h3.string)  #获取body中的第一个h3中的文本内容:我的常用链接  
  • ④ 关联选择:
  • 我们在做选择的时候,难免有时候不能够一步就选到想要的节点元素。
  • 需要先选中某一个节点元素,然后再基于这些继续向下选择(子,父,兄弟)。
#....    # 子或子孙节点  # 以下获取的节点列表都可以使用for...in遍历  print(soup.ul.contents) #获取ul下面的所有直接子节点,返回列表  print(soup.ul.children) #获取ul下面的所有直接子节点,返回一个:<list_iterator object at 0x110346a20>    print(soup.ul.descendants) # 获取ul下的所有子孙节点。  for v in soup.ul.descendants:      print("a:",v)    # 父祖节点  print(soup.a.parent.name) #通过parent属性获取a的父节点 li  # print(list(soup.a.parents)) # 获取所有祖先节点    #兄弟节点  print(soup.li.next_siblings)    #获取指定li节点的所有后面的兄弟节点  print(soup.li.previous_siblings)#获取指定li节点的所有前面的兄弟节点  #for v in soup.li.next_siblings:  #    print(v)    # 获取信息    print(soup.a.string) #获取a节点中的文本  print(soup.a.attrs['href']) # 或a节点的href属性值  

3. 方法选择器:

  • ① find_all() — 传入属性或文本,返回所有符合条件的元素 格式:find_all(name,attrs,recursive,text, **kwargs )
# 导入模块  from bs4 import BeautifulSoup  import re  # 读取html文件信息(在真实代码中是爬取的网页信息)  f = open("./my.html",'r')  content = f.read()  f.close()    # 创建解析器  soup = BeautifulSoup(content,"lxml")    # 通过name指定li值,获取所有li元素节点,返回列表  lilist = soup.find_all(name="li")  # 通过attrs指定属性来获取所有元素节点  lilist = soup.find_all(attrs={"class":"aa"})  lilist = soup.find_all(class_="aa") #同上(class属性中包含就可以了)  lilist = soup.find_all(class_="shop") #class属性值中包含shop的所有节点  lilist = soup.find_all(id="hid") #<h3 id="hid">我的常用链接</h3>  # 通过文本内容获取  lilist = soup.find_all(text='百度') # 百度  lilist = soup.find_all(text=re.compile('张')) # 张翠山 张无忌  for i in lilist:      print(i)  
  • ② find() — 传入属性或文本,返回所有符合条件的第一个元素
  # 获取一个li元素节点  lilist = soup.find(name="li")  # 通过attrs指定属性来获取一个元素节点  lilist = soup.find(attrs={"class":"aa"})  

4. CSS选择器:

# 导入模块  from bs4 import BeautifulSoup  import re  # 读取html文件信息(在真实代码中是爬取的网页信息)  f = open("./my.html",'r')  content = f.read()  f.close()    # 创建解析器  soup = BeautifulSoup(content,"lxml")      print(soup.select("ul li a")) #获取ul里面li下面的a元素节点    print(soup.select("#hid")) #获取id属性值为hid的元素节点    print(soup.select("li.shop a")) #获取class属性为shop的li元素里面所有的a元素节点    # 套用选择解析器  blist = soup.select("ul li")  for li in blist:      a = li.select("a")[0] #获取每个li里面的a元素节点      print(a)      print(a['href']) #获取属性href的值      # print(a.attrs['href']) #等价 同上 获取属性值      print(a.get_text()) #等价 print(a.string) 获取元素节点的文本内容