zoukankan      html  css  js  c++  java
  • BeautifulSoup模块

    BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后遍可以使用他提供的方法进行快速查找指定元素,从而使得在HTML或XML中查找指定元素变得简单。

    官方文档:http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/#id13

    安装

    pip install beautifulsoup4

     使用示例

    from bs4 import BeautifulSoup
     
    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    asdf
        <div class="title">
            <b>The Dormouse's story总共</b>
            <h1>f</h1>
        </div>
    <div class="story">Once upon a time there were three little sisters; and their names were
        <a  class="sister0" id="link1">Els<span>f</span>ie</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.</div>
    ad<br/>sf
    <p class="story">...</p>
    </body>
    </html>
    """
     
    soup = BeautifulSoup(html_doc, features="lxml")  # 第一个参数是网页内容的字符串形式,第二个参数是用来选择解析库
    # 找到第一个a标签
    tag1 = soup.find(name='a')
    # 找到所有的a标签
    tag2 = soup.find_all(name='a')
    # 找到id=link2的标签
    tag3 = soup.select('#link2')

    使用

    将一段文档传入BeautifulSoup的构造方法,就能得到一个文档的对象,可以传入一段字符串或一个文件句柄。

    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(open('index.html'))
    # 或者
    soup = BeautifulSoup('<html> data </html>')

     然后文档被转换成Unicode的,并且HTML的实例都被转换成Unicode的编码

    BeautifulSoup("Sacr&eacute; bleu!")
    <html><head></head><body>Sacré bleu!</body></html>

     然后,Beautiful Soup选择最合适的解析器来解析这段文档,如果手动指定解析器那么Beautiful Soup会选择指定的解析器来解析文档

    BeautifulSoup默认支持Python的标准HTML解析库,但是它也支持一些第三方的解析库:

    注:平时我们可以使用python内置的html.parser,但是用的多的还是lxml的两个解析库,速度快,容错也高

    经过解析库的解析,就会将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment .

     (1)Tag

    Tag相当于html中的一个标签。

    这里有比较重要的两个属性:

    • name:标签的名字
    • attrs:每个标签中的全部属性

     (2)NavigableString

    字符串常被包含在tag内.Beautiful Soup用 NavigableString 类来包装tag中的字符串。

    tag中包含的字符串不能编辑,但是可以被替换成其它的字符串,用 replace_with() 方法。

     如果想在Beautiful Soup之外使用 NavigableString 对象,需要调用 unicode() 方法,将该对象转换成普通的Unicode字符串,否则就算Beautiful Soup已方法已经执行结束,该对象的输出也会带有对象的引用地址.这样会浪费内存。

    (3)BeautifulSoup

    BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,它支持 遍历文档树 和 搜索文档树 中描述的大部分的方法.

    因为 BeautifulSoup 对象并不是真正的HTML或XML的tag,所以它没有name和attribute属性.但有时查看它的 .name 属性是很方便的,所以 BeautifulSoup 对象包含了一个值为 “[document]” 的特殊属性 .name

    (4)Comment

     Tag , NavigableString , BeautifulSoup 几乎覆盖了html和xml中的所有内容,但是还有一些特殊对象.容易让人担心的内容是文档的注释部分:

    Comment 对象就是一个特殊类型的 NavigableString 对象用来记录文档的。

    比如:

    markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
    soup = BeautifulSoup(markup)
    comment = soup.b.string
    type(comment)
    # <class 'bs4.element.Comment'>

    但是当它出现在HTML文档中时, Comment 对象会使用特殊的格式输出:

    print(soup.b.prettify())
    # <b>
    #  <!--Hey, buddy. Want to buy a used parser?-->
    # </b>

    常用的属性和方法

    1.name:获取标签名称

    tag = soup.find('a')
    name = tag.name # 获取
    print(name)
    tag.name = 'span' # 设置
    print(soup)
    View Code

    2.attr:获取标签属性,值为集合形式

    # tag = soup.find('a')
    # attrs = tag.attrs    # 获取
    # print(attrs)
    # tag.attrs = {'ik':123} # 设置
    # tag.attrs['id'] = 'iiiii' # 设置
    # print(soup
    #另一种方式,用get获取
    #soup.select('a')[0].get('href')
    View Code

    3.children:获取所有子标签

    # body = soup.find('body')
    # v = body.children
    View Code

    4.descendants:获取所有子子孙孙的标签

    # body = soup.find('body')
    # v = body.descendants
    View Code

    5.clear:将标签的所有子标签全部清空(保留标签名)

    # tag = soup.find('body')
    # tag.clear()
    # print(soup)
    View Code

    6.decompose:递归删除所有的标签

    # body = soup.find('body')
    # body.decompose()
    # print(soup)
    View Code

    7.extract:递归删除所有的标签,并获取删除的标签

    # body = soup.find('body')
    # v = body.extract()
    # print(soup)
    View Code

    8.decode:转换为字符串(含当前标签);decode_contents(不含当前标签)

    # body = soup.find('body')
    # v = body.decode()
    # v = body.decode_contents()
    # print(v)
    View Code

    9.encode:转换为字节(含当前标签);encode_contents(不包含当前标签)

    # body = soup.find('body')
    # v = body.encode()
    # v = body.encode_contents()
    # print(v)
    View Code

    10.find:获取匹配的第一个标签

    # tag = soup.find('a')
    # print(tag)
    # tag = soup.find(name='a', attrs={'class': 'sister'}, recursive=True, text='Lacie')
    # tag = soup.find(name='a', class_='sister', recursive=True, text='Lacie')
    # print(tag)
    View Code

    11.find_all:获取匹配的所有标签

    # tags = soup.find_all('a')
    # print(tags)
     
    # tags = soup.find_all('a',limit=1)
    # print(tags)
     
    # tags = soup.find_all(name='a', attrs={'class': 'sister'}, recursive=True, text='Lacie')
    # # tags = soup.find(name='a', class_='sister', recursive=True, text='Lacie')
    # print(tags)
     
     
    # ####### 列表 #######
    # v = soup.find_all(name=['a','div'])
    # print(v)
     
    # v = soup.find_all(class_=['sister0', 'sister'])
    # print(v)
     
    # v = soup.find_all(text=['Tillie'])
    # print(v, type(v[0]))
     
     
    # v = soup.find_all(id=['link1','link2'])
    # print(v)
     
    # v = soup.find_all(href=['link1','link2'])
    # print(v)
     
    # ####### 正则 #######
    import re
    # rep = re.compile('p')
    # rep = re.compile('^p')
    # v = soup.find_all(name=rep)
    # print(v)
     
    # rep = re.compile('sister.*')
    # v = soup.find_all(class_=rep)
    # print(v)
     
    # rep = re.compile('http://www.oldboy.com/static/.*')
    # v = soup.find_all(href=rep)
    # print(v)
     
    # ####### 方法筛选 #######
    # def func(tag):
    # return tag.has_attr('class') and tag.has_attr('id')
    # v = soup.find_all(name=func)
    # print(v)
     
     
    # ## get,获取标签属性
    # tag = soup.find('a')
    # v = tag.get('id')
    # print(v)
    View Code

    12.has_attr:检查标签是否具有该属性

    # tag = soup.find('a')
    # v = tag.has_attr('id')
    # print(v)
    View Code

    13.get_text:获取标签内部文本内容

    # tag = soup.find('a')
    # v = tag.get_text('id')
    # print(v)
    View Code

    14.index:检查标签在某标签中的索引位置

    # tag = soup.find('body')
    # v = tag.index(tag.find('div'))
    # print(v)
     
    # tag = soup.find('body')
    # for i,v in enumerate(tag):
    # print(i,v)
    View Code

    15. is_empty_element,是否是空标签(是否可以是空)或者自闭合标签,

    判断是否是如下标签:'br' , 'hr', 'input', 'img', 'meta','spacer', 'link', 'frame', 'base'

    # tag = soup.find('br')
    # v = tag.is_empty_element
    # print(v)
    View Code

    16. 当前的关联标签

    # soup.next
    # soup.next_element
    # soup.next_elements
    # soup.next_sibling
    # soup.next_siblings
     
    #
    # tag.previous
    # tag.previous_element
    # tag.previous_elements
    # tag.previous_sibling
    # tag.previous_siblings
     
    #
    # tag.parent
    # tag.parents
    View Code

    17. 查找某标签的关联标签

    # tag.find_next(...)
    # tag.find_all_next(...)
    # tag.find_next_sibling(...)
    # tag.find_next_siblings(...)
     
    # tag.find_previous(...)
    # tag.find_all_previous(...)
    # tag.find_previous_sibling(...)
    # tag.find_previous_siblings(...)
     
    # tag.find_parent(...)
    # tag.find_parents(...)
     
    # 参数同find_all
    View Code

    18.select,select_one, CSS选择器

    soup.select("title")
     
    soup.select("p nth-of-type(3)")
     
    soup.select("body a")
     
    soup.select("html head title")
     
    tag = soup.select("span,a")
     
    soup.select("head > title")
     
    soup.select("p > a")
     
    soup.select("p > a:nth-of-type(2)")
     
    soup.select("p > #link1")
     
    soup.select("body > a")
     
    soup.select("#link1 ~ .sister")
     
    soup.select("#link1 + .sister")
     
    soup.select(".sister")
     
    soup.select("[class~=sister]")
     
    soup.select("#link1")
     
    soup.select("a#link2")
     
    soup.select('a[href]')
     
    soup.select('a[href="http://example.com/elsie"]')
     
    soup.select('a[href^="http://example.com/"]')
     
    soup.select('a[href$="tillie"]')
     
    soup.select('a[href*=".com/el"]')
     
     
    from bs4.element import Tag
     
    def default_candidate_generator(tag):
        for child in tag.descendants:
            if not isinstance(child, Tag):
                continue
            if not child.has_attr('href'):
                continue
            yield child
     
    tags = soup.find('body').select("a", _candidate_generator=default_candidate_generator)
    print(type(tags), tags)
     
    from bs4.element import Tag
    def default_candidate_generator(tag):
        for child in tag.descendants:
            if not isinstance(child, Tag):
                continue
            if not child.has_attr('href'):
                continue
            yield child
     
    tags = soup.find('body').select("a", _candidate_generator=default_candidate_generator, limit=1)
    print(type(tags), tags)
    View Code

    19. 标签的内容

    # tag = soup.find('span')
    # print(tag.string)          # 获取
    # tag.string = 'new content' # 设置
    # print(soup)
     
    # tag = soup.find('body')
    # print(tag.string)
    # tag.string = 'xxx'
    # print(soup)
     
    # tag = soup.find('body')
    # v = tag.stripped_strings  # 递归内部获取所有标签的文本
    # print(v)
    View Code

    20.append在当前标签内部追加一个标签

    # tag = soup.find('body')
    # tag.append(soup.find('a'))
    # print(soup)
    #
    # from bs4.element import Tag
    # obj = Tag(name='i',attrs={'id': 'it'})
    # obj.string = '我是一个新来的'
    # tag = soup.find('body')
    # tag.append(obj)
    # print(soup)
    View Code

    21.insert在当前标签内部指定位置插入一个标签

    # from bs4.element import Tag
    # obj = Tag(name='i', attrs={'id': 'it'})
    # obj.string = '我是一个新来的'
    # tag = soup.find('body')
    # tag.insert(2, obj)
    # print(soup)
    View Code

    22. insert_after,insert_before 在当前标签后面或前面插入

    # from bs4.element import Tag
    # obj = Tag(name='i', attrs={'id': 'it'})
    # obj.string = '我是一个新来的'
    # tag = soup.find('body')
    # # tag.insert_before(obj)
    # tag.insert_after(obj)
    # print(soup)
    View Code

    23. replace_with 在当前标签替换为指定标签

    # from bs4.element import Tag
    # obj = Tag(name='i', attrs={'id': 'it'})
    # obj.string = '我是一个新来的'
    # tag = soup.find('div')
    # tag.replace_with(obj)
    # print(soup)
    View Code

    24. 创建标签之间的关系

    # tag = soup.find('div')
    # a = soup.find('a')
    # tag.setup(previous_sibling=a)
    # print(tag.previous_sibling)
    View Code

    25. wrap,将指定标签把当前标签包裹起来

    # from bs4.element import Tag
    # obj1 = Tag(name='div', attrs={'id': 'it'})
    # obj1.string = '我是一个新来的'
    #
    # tag = soup.find('a')
    # v = tag.wrap(obj1)
    # print(soup)
     
    # tag = soup.find('a')
    # v = tag.wrap(soup.find('p'))
    # print(soup)
    View Code

    26. unwrap,去掉当前标签,将保留其包裹的标签

    # tag = soup.find('a')
    # v = tag.unwrap()
    # print(soup)
    View Code

    小例子

    from bs4.element import Tag
    
    tags = soup.find("body").children
    for tag in tags:
        if type(tag) == Tag:
            print(tag)
        else:
            print("文本。。")
    将标签和文本分开
  • 相关阅读:
    【codecombat】 试玩全攻略 第二章 边远地区的森林 一步错
    【codecombat】 试玩全攻略 第十八关 最后的kithman族
    【codecombat】 试玩全攻略 第二章 边远地区的森林 woodlang cubbies
    【codecombat】 试玩全攻略 第二章 边远地区的森林 羊肠小道
    【codecombat】 试玩全攻略 第十七关 混乱的梦境
    【codecombat】 试玩全攻略 第二章 边远地区的森林 林中的死亡回避
    【codecombat】 试玩全攻略 特别关:kithguard斗殴
    【codecombat】 试玩全攻略 第二章 边远地区的森林 森林保卫战
    【codecombat】 试玩全攻略 第二章 边远地区的森林
    实验3 类和对象||
  • 原文地址:https://www.cnblogs.com/kuxingseng95/p/9351326.html
Copyright © 2011-2022 走看看