• 爬虫之`beautifulsoup4`模块


    beautifulsoup4模块

    beautifulsoup4的简介

    Beautiful Soup是一个可以从HTML或XML文件中提取数据的python库。
    
    1. 安装beautifulsoup4
    # 安装
    pip install beautifulsoup4
    
    1. 解析库

      BeautifulSoup默认支持Python的标准HTML解析库,但是它也支持一些第三方的解析库
      
      序号 解析库 使用方法 优势 劣势
      1 Python标准库 BeautifulSoup(html,’html.parser’) Python内置标准库;执行速度快 容错能力较差
      2 lxml HTML解析库 BeautifulSoup(html,’lxml’) 速度快;容错能力强 需要安装,需要C语言库
      3 lxml XML解析库 BeautifulSoup(html,[‘lxml’,’xml’]) 速度快;容错能力强;支持XML格式 需要C语言库
      4 htm5lib解析库 BeautifulSoup(html,’htm5llib’) 以浏览器方式解析,最好的容错性 速度慢
    2. 下载解析模块lxml

      # 下载解析模块lxml
      pip install lxml
      
    3. 使用

      # 初始化一个bs4对象
      import requests
      from bs4 import BeautifulSoup
      
      res = requests.get("https://www.mzitu.com/")
      soup = BeautifulSoup(res.text,'lxml') #解析的文本 解析器
      

    BeautifulSoup4中文文档

    案例1:爬取汽车之家的新闻

    汽车之家

    import requests
    
    from bs4 import BeautifulSoup
    
    res = requests.get("https://www.autohome.com.cn/news/1/#liststart")
    
    soup = BeautifulSoup(res.text, 'lxml')
    
    ul = soup.find(class_='article')  # 查找class为article的ul
    li_list = ul.find_all(name='li')  # 查找ul下的所有li
    new_list = []
    for li in li_list:
        title = li.find(name='h3')   # 查找li下name=h3的tag
        if title:
            new_list.append({
                'title': title.text,
                'link': 'http:' + li.find('a').attrs.get('href'),
                'abstract': li.find('p').text,
                'img': 'http:' + li.find(name='img').attrs.get('src')
            })
    
    import json
    
    with open('news.doc', mode='wb') as fw:
        for item in new_list:
            fw.write(json.dumps(item, ensure_ascii=False).encode('utf-8'))
            fw.write('
    
    '.encode('utf-8'))
    

    bs4模块的使用

    <1>遍历文档树
    <2>搜索文档树(5种过滤规则)
    <3>limit和recursive参数
    

    遍历文档树

    (0)用法
    (1)获取标签的名称
    (2)获取标签的属性
    (3)获取标签的内容
    (4)嵌套使用
    (5)子节点、子孙节点
    (6)父节点、祖先节点
    

    用法

    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p id="my_p" class="title">hello<b id="bbb" class="boldest">The Dormouse's story</b>
    </p>
    
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    
    <p class="story">...</p>
    """
    
    lxml文档容错能力强,能够解析非标准html文档
    
    # 使用方式1
    soup = BeautifulSoup(html_doc,'lxml')
    # print(soup.prettify())
    # 使用方式2
    soup = BeautifulSoup(open('a.html'),'lxml')
    

    获取标签的名字

    soup = BeautifulSoup(html_doc,'lxml')
    head = soup.head
    print(type(head)) # tag <class 'bs4.element.Tag'>
    print(head.name)  # head
    

    获取标签的属性(重点)

    p = soup.body.p   # <class 'bs4.element.Tag'>
    print(p.attrs)    # {'id': 'my_p', 'class': ['title']}
    
    print(p.attrs.get('id'))  # my_p
    print(p['id'])            # my_p
    print(p.get('id'))        # my_p
    

    获取标签的内容

    # text会取标签子子孙孙的内容拼接在一起
    p = soup.body.p
    print(p.text)     #helloThe Dormouse's story
    
    # p下文本只有一个的时候取到,否则为None
    print(p.string)  # None
    
    # 拿到一个生成器对象,取到p下的所有文本内容
    print(p.strings) # <generator object Tag._all_strings at 0x7f02260213c0>
    print(list(p.strings))  # ['hello', "The Dormouse's story", '
    ']
    或者
    for item in p.strings:
        print(item)
    

    嵌套使用

    a = soup.body.a
    print(a.get('id'))
    

    子节点、子孙节点

    print(soup.p.contents)  # ['hello', <b class="boldest" id="bbb">The Dormouse's story</b>, '
    '] 获取p下的所有子节点
    
    print(soup.p.children) # 获取p下的子节点,是一个生成器对象 <list_iterator object at 0x7f24215e3b80>
    
    print(list(soup.p.children)) # ['hello', <b class="boldest" id="bbb">The Dormouse's story</b>, '
    ']
    

    父节点,祖先节点

    # 获取p标签的父节点
    print(soup.p.parent)
    # a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲
    print(soup.a.parents)
    

    兄弟节点

    # print(soup.a.next_sibling) #下一个兄弟
    # print(soup.a.previous_sibling) #上一个兄弟
    
    # print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
    # print(list(soup.a.previous_siblings)) #上面的兄弟们=>生成器对象
    

    搜索文档树

    <1>find()      # 只返回找到的第一个
    <2>find_all()  # 找到所有的
    <3>5种过滤器:字符串、正则表达式、列表、True、方法
    

    字符串过滤

    # 过滤的内容是字符串
    # a=soup.find(name='a')
    # res=soup.find(id='my_p')
    # res=soup.find(class_='story')
    # res=soup.find(href='http://example.com/elsie')
    
    # res=soup.find(attrs={'id':'my_p'})
    # res=soup.find(attrs={'class':'story'})
    # print(res)
    

    正则表达式

    # import re
    # # re_b=re.compile('^b')
    # res=soup.find(name=re_b)
    # # res=soup.find_all(name=re_b)
    # res=soup.find_all(id=re.compile('^l'))
    # print(res)
    

    列表

    # res=soup.find_all(name=['body','b'])
    # res=soup.find_all(class_=['sister','title'])
    # print(res)
    

    True

    # res=soup.find_all(name=True)
    # res=soup.find_all(id=True)
    # res=soup.find_all(id=False)
    # res=soup.find_all(href=True)
    # print(res)
    

    方法

    # def has_class_but_no_id(tag):
    #     return tag.has_attr('class') and not tag.has_attr('id')
    #
    # print(soup.find_all(has_class_but_no_id))
    

    limit(限制查找的条数)

    # res=soup.find_all(name=True,limit=1)
    # print(res)
    # recursive(recursive递归查找,找子子孙孙)
    # res=soup.body.find_all(name='b ',recursive=False)
    # res=soup.body.find_all(name='p',recursive=False)
    # res=soup.body.find_all(name='b',recursive=True)
    # print(res)
    

    css选择器

    # ret=soup.select('#my_p')
    # https://www.w3school.com.cn/cssref/css_selectors.asp
    # ret=soup.select('body p')  # 子子孙孙
    # ret=soup.select('body>p')  # 直接子节点(儿子)
    # ret=soup.select('body>p')[0].text  # 直接子节点(儿子)
    # # ret=soup.select('body>p')[0].a.find()
    # print(ret)
    

    bs4的修改文档树 软件配置文件是xml格式的

    软件的配置文件的格式:

    # ini:configparser
    # conf
    # xml:bs4
    # yaml格式
    
  • 相关阅读:
    【Linux】命令——基本命令
    正则表达式
    Letex
    Markdown
    文本编辑器Vim
    【Linux】集群
    【Linux】软件安装
    共线性synteny
    windows触控手势
    【Linux】bin结尾的安装包
  • 原文地址:https://www.cnblogs.com/surpass123/p/13427572.html
Copyright © 2020-2023  润新知