Python 爬虫学习笔记(七(3))BeautifulSoup解析+实战

一、BeautifulSoup

简称bs4,主要功能也是解析和提取数据

缺点是效率没有lxml的效率高(xpath), 优点是接口设计人性化,使用方便

在PyCharm pip install bs4库

1.节点定位

以此html文件为例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        <li id='l1'>张三</li>
        <li id='l2'>李四</li>
        <li>王五</li>
        <a href="" id="" class="a1">哈哈哈</a>
        <span>这是span</span>
    </ul>

    <a href="" title="ttt">嘿嘿嘿</a>
</body>
</html>

先打开文件,BeautifulSoup默认打开编码是gbk,所以需要指定编码方式
第二个参数是lxml,必须要有

from bs4 import BeautifulSoup

soup = BeautifulSoup(open('bs4.html', encoding='utf-8'), 'lxml')

(1)根据标签名查找节点

soup.a 注:只能找到第一个a
.attrs返回标签的属性和属性值

print(soup.a)
print(soup.a.attrs)
返回结果:哈哈哈
返回结果:{'href': '', 'id': '', 'class': ['a1']}

(2)函数

  1. find (返回一个对象)
print(soup.find('a'))  # 返回的第一个a
print(soup.find('a', title='ttt'))  # 找title标签为'ttt'的a 
print(soup.find('a', class_='a1'))  # 找class为'a1'的a, 必须是class_
返回结果:哈哈哈
返回结果:嘿嘿嘿
返回结果:哈哈哈
  1. find_all (返回的是一个列表,并且包含所有的a标签)
print(soup.find_all('a'))
返回结果:[哈哈哈, 嘿嘿嘿]
print(soup.find_all(['a', 'span']))  #返回所有的a和span标签,要用列表 
返回结果:[哈哈哈, 这是span, 嘿嘿嘿]
print(soup.find_all('li', limit=2)) # 返回前两个li标签,使用参数limit=2
返回结果:[
  • 张三
  • ,
  • 李四
  • ]
    1. select (返回的是一个列表,并且包含所有的a标签)
    print(soup.select('a'))
    
    返回结果:[哈哈哈, 嘿嘿嘿]
    
    print(soup.select('.a1'))  # 类选择器
    print(soup.select('#l1'))  # id选择器
    
    返回结果:[哈哈哈]
    返回结果:[
  • 张三
  • ]

    属性选择器(通过属性来寻找对应的标签)

    # 查找到li标签中有id的标签
    print(soup.select('li[id]'))
    
    返回结果:[
  • 张三
  • ,
  • 李四
  • ]
    # 查找到li标签中有id为'l2'的标签
    print(soup.select('li[id="l2"]'))
    
    返回结果:[
  • 李四
  • ]

    层级选择器

    给刚才的html页面的ul标签嵌套一层div

    <body>
        <div>
            <ul>
                <li id="l1"  class="c1">张三</li>
                <li id="l2">李四</li>
                <li>王五</li>
                <a href="" id="" class="a1">哈哈哈</a>
                <span>这是span</span>
            </ul>
        </div>
    
        <a href="" title="ttt">嘿嘿嘿</a>
        
        <div id="d1">
            <span>
                这是内容
            </span>
        </div>
    </body>
    

    后代选择器

    # 找到div下面所有的li
    print(soup.select('div li'))
    
    返回结果:[
  • 张三
  • ,
  • 李四
  • ,
  • 王五
  • ]

    子代选择器

    # 找到div下面的li
    print(soup.select('div > ul > li'))
    
    返回结果:[
  • 张三
  • ,
  • 李四
  • ,
  • 王五
  • ]

    组合选择器(不需要列表,直接“,”隔开)

    # 找到a标签和li标签的所有的对象
    print(soup.select('a,li'))
    
    返回结果:[
  • 张三
  • ,
  • 李四
  • ,
  • 王五
  • , 哈哈哈, 嘿嘿嘿]

    2.节点信息

    (1).获取节点内容:适用于标签中嵌套标签的结构

    如果标签对象中只有内容,那么string和get_text()都可以使用
    如果标签对象中除了内容,还有其他标签,string不可以而get_text()可以获取到数据
    一般情况下,推荐使用get_text()

    # 先找到对象
    obj = soup.select('#d1')[0]
    # print(obj.string)
    print(obj.get_text())
    

    (2).节点的属性

    obj = soup.select('#l1')[0]
    # attrs将属性值作为一个字典返回
    print(obj.attrs)
    
    返回结果:{'id': 'l1', 'class': ['c1']}
    

    (3).获取节点的属性

    obj = soup.select('#l1')[0]
    print(obj.attrs.get('class'))  # 推荐
    print(obj.get('class'))
    print(obj['class'])
    
    返回结果:['c1']
    		 ['c1']
    		 ['c1']
    

    二、bs4解析获取StarBucks菜单

    Python 爬虫学习笔记(七(3))BeautifulSoup解析+实战_第1张图片
    分析页面源码,不难发现产品名在strong标签内
    Python 爬虫学习笔记(七(3))BeautifulSoup解析+实战_第2张图片

    完整代码:

    import urllib.request
    from bs4 import BeautifulSoup
    
    url = 'https://www.starbucks.com.cn/menu/'
    
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/98.0.4758.102 Safari/537.36 "
    }
    
    request = urllib.request.Request(url=url, headers=headers)
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    
    soup = BeautifulSoup(content, 'lxml')
    
    name_list = soup.select('ul[class="grid padded-3 product"] strong')
    # name_list = soup.select('div strong'))  # 也可以
    
    for name in name_list:
        print(name.get_text())
    

    总结

    1. BeautifulSoup效率没有xpath高,但有些设计人性化(对前端人员友好)
    2. 既可以解析本地文件,也可以解析服务器响应的数据
    3. 用BeautifulSoup打开文件时默认gbk编码,要先编码成’utf-8’,第二个参数’lxml’不能忘
    4. 要分清获取的是节点对象还是列表,如果是列表可以用索引找到第n个标签

    你可能感兴趣的:(python,爬虫,学习)