zoukankan      html  css  js  c++  java
  • bs4--官文--搜索文档树

    搜索文档树

    Beautiful Soup定义了很多搜索方法,这里着重介绍2个: find()  find_all() .其它方法的参数和用法类似,请读者举一反三.

    再以“爱丽丝”文档作为例子:

    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title"><b>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>
    """
    
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html_doc, 'html.parser')
    

    使用 find_all() 类似的方法可以查找到想要查找的文档内容

    过滤器

    介绍 find_all() 方法前,先介绍一下过滤器的类型 [3] ,这些过滤器贯穿整个搜索的API.过滤器可以被用在tag的name中,节点的属性中,字符串中或他们的混合中.

    字符串

    最简单的过滤器是字符串.在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容,下面的例子用于查找文档中所有的<b>标签:

    soup.find_all('b')
    # [<b>The Dormouse's story</b>]
    

    如果传入字节码参数,Beautiful Soup会当作UTF-8编码,可以传入一段Unicode 编码来避免Beautiful Soup解析编码出错

    正则表达式

    如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以b开头的标签,这表示<body>和<b>标签都应该被找到:

    import re
    for tag in soup.find_all(re.compile("^b")):
        print(tag.name)
    # body
    # b
    

    下面代码找出所有名字中包含”t”的标签:

    for tag in soup.find_all(re.compile("t")):
        print(tag.name)
    # html
    # title
    

    列表

    如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签:

    soup.find_all(["a", "b"])
    # [<b>The Dormouse's story</b>,
    #  <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    True

    True 可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点

    for tag in soup.find_all(True):
        print(tag.name)
    # html
    # head
    # title
    # body
    # p
    # b
    # p
    # a
    # a
    # a
    # p
    

    方法

    如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 [4] ,如果这个方法返回 True表示当前元素匹配并且被找到,如果不是则反回 False

    下面方法校验了当前元素,如果包含 class 属性却不包含 id 属性,那么将返回 True:

    def has_class_but_no_id(tag):
        return tag.has_attr('class') and not tag.has_attr('id')
    

    将这个方法作为参数传入 find_all() 方法,将得到所有<p>标签:

    soup.find_all(has_class_but_no_id)
    # [<p class="title"><b>The Dormouse's story</b></p>,
    #  <p class="story">Once upon a time there were...</p>,
    #  <p class="story">...</p>]
    

    返回结果中只有<p>标签没有<a>标签,因为<a>标签还定义了”id”,没有返回<html>和<head>,因为<html>和<head>中没有定义”class”属性.

    通过一个方法来过滤一类标签属性的时候, 这个方法的参数是要被过滤的属性的值, 而不是这个标签. 下面的例子是找出 href 属性不符合指定正则的 a 标签.

    def not_lacie(href):
            return href and not re.compile("lacie").search(href)
    soup.find_all(href=not_lacie)
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    标签过滤方法可以使用复杂方法. 下面的例子可以过滤出前后都有文字的标签.

    from bs4 import NavigableString
    def surrounded_by_strings(tag):
        return (isinstance(tag.next_element, NavigableString)
                and isinstance(tag.previous_element, NavigableString))
    
    for tag in soup.find_all(surrounded_by_strings):
        print tag.name
    # p
    # a
    # a
    # a
    # p
    

    现在来了解一下搜索方法的细节

    find_all()

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

    find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件.这里有几个例子:

    soup.find_all("title")
    # [<title>The Dormouse's story</title>]
    
    soup.find_all("p", "title")
    # [<p class="title"><b>The Dormouse's story</b></p>]
    
    soup.find_all("a")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    soup.find_all(id="link2")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    
    import re
    soup.find(string=re.compile("sisters"))
    # u'Once upon a time there were three little sisters; and their names were
    '
    

    有几个方法很相似,还有几个方法是新的,参数中的 string  id 是什么含义? 为什么 find_all("p", "title")返回的是CSS Class为”title”的<p>标签? 我们来仔细看一下 find_all() 的参数

    name 参数

    name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉.

    简单的用法如下:

    soup.find_all("title")
    # [<title>The Dormouse's story</title>]
    

    重申: 搜索 name 参数的值可以使任一类型的 过滤器 ,字符窜,正则表达式,列表,方法或是 True .

    keyword 参数

    如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.

    soup.find_all(id='link2')
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    

    如果传入 href 参数,Beautiful Soup会搜索每个tag的”href”属性:

    soup.find_all(href=re.compile("elsie"))
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    

    搜索指定名字的属性时可以使用的参数值包括 字符串 , 正则表达式 , 列表, True .

    下面的例子在文档树中查找所有包含 id 属性的tag,无论 id 的值是什么:

    soup.find_all(id=True)
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    使用多个指定名字的参数可以同时过滤tag的多个属性:

    soup.find_all(href=re.compile("elsie"), id='link1')
    # [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]
    

    有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性:

    data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
    data_soup.find_all(data-foo="value")
    # SyntaxError: keyword can't be an expression
    

    但是可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag:

    data_soup.find_all(attrs={"data-foo": "value"})
    # [<div data-foo="value">foo!</div>]
    

    按CSS搜索

    按照CSS类名搜索tag的功能非常实用,但标识CSS类名的关键字 class 在Python中是保留字,使用 class做参数会导致语法错误.从Beautiful Soup的4.1.1版本开始,可以通过 class_ 参数搜索有指定CSS类名的tag:

    soup.find_all("a", class_="sister")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    class_ 参数同样接受不同类型的 过滤器 ,字符串,正则表达式,方法或 True :

    soup.find_all(class_=re.compile("itl"))
    # [<p class="title"><b>The Dormouse's story</b></p>]
    
    def has_six_characters(css_class):
        return css_class is not None and len(css_class) == 6
    
    soup.find_all(class_=has_six_characters)
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    tag的 class 属性是 多值属性 .按照CSS类名搜索tag时,可以分别搜索tag中的每个CSS类名:

    css_soup = BeautifulSoup('<p class="body strikeout"></p>')
    css_soup.find_all("p", class_="strikeout")
    # [<p class="body strikeout"></p>]
    
    css_soup.find_all("p", class_="body")
    # [<p class="body strikeout"></p>]
    

    搜索 class 属性时也可以通过CSS值完全匹配:

    css_soup.find_all("p", class_="body strikeout")
    # [<p class="body strikeout"></p>]
    

    完全匹配 class 的值时,如果CSS类名的顺序与实际不符,将搜索不到结果:

    soup.find_all("a", attrs={"class": "sister"})
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    string 参数

    通过 string 参数可以搜搜文档中的字符串内容.与 name 参数的可选值一样, string 参数接受 字符串 , 正则表达式 , 列表, True . 看例子:

    soup.find_all(string="Elsie")
    # [u'Elsie']
    
    soup.find_all(string=["Tillie", "Elsie", "Lacie"])
    # [u'Elsie', u'Lacie', u'Tillie']
    
    soup.find_all(string=re.compile("Dormouse"))
    [u"The Dormouse's story", u"The Dormouse's story"]
    
    def is_the_only_string_within_a_tag(s):
        ""Return True if this string is the only child of its parent tag.""
        return (s == s.parent.string)
    
    soup.find_all(string=is_the_only_string_within_a_tag)
    # [u"The Dormouse's story", u"The Dormouse's story", u'Elsie', u'Lacie', u'Tillie', u'...']
    

    虽然 string 参数用于搜索字符串,还可以与其它参数混合使用来过滤tag.Beautiful Soup会找到 .string方法与 string 参数值相符的tag.下面代码用来搜索内容里面包含“Elsie”的<a>标签:

    soup.find_all("a", string="Elsie")
    # [<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>]
    

    limit 参数

    find_all() 方法返回全部的搜索结构,如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果.

    文档树中有3个tag符合搜索条件,但结果只返回了2个,因为我们限制了返回数量:

    soup.find_all("a", limit=2)
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    

    recursive 参数

    调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False .

    一段简单的文档:

    <html>
     <head>
      <title>
       The Dormouse's story
      </title>
     </head>
    ...
    

    是否使用 recursive 参数的搜索结果:

    soup.html.find_all("title")
    # [<title>The Dormouse's story</title>]
    
    soup.html.find_all("title", recursive=False)
    # []
    

    这是文档片段

    <html>
            <head>
            <title>
            The Dormouse's story
        </title>
            </head>
            ...
    

    <title>标签在 <html> 标签下, 但并不是直接子节点, <head> 标签才是直接子节点. 在允许查询所有后代节点时 Beautiful Soup 能够查找到 <title> 标签. 但是使用了 recursive=False 参数之后,只能查找直接子节点,这样就查不到 <title> 标签了.

    Beautiful Soup 提供了多种DOM树搜索方法. 这些方法都使用了类似的参数定义. 比如这些方法: find_all(): name, attrs, text, limit. 但是只有 find_all()  find() 支持 recursive 参数.

    像调用 find_all() 一样调用tag

    find_all() 几乎是Beautiful Soup中最常用的搜索方法,所以我们定义了它的简写方法. BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 find_all() 方法相同,下面两行代码是等价的:

    soup.find_all("a")
    soup("a")
    

    这两行代码也是等价的:

    soup.title.find_all(string=True)
    soup.title(string=True)
    

    find()

    find( name , attrs , recursive , string , **kwargs )

    find_all() 方法将返回文档中符合条件的所有tag,尽管有时候我们只想得到一个结果.比如文档中只有一个<body>标签,那么使用 find_all() 方法来查找<body>标签就不太合适, 使用 find_all 方法并设置 limit=1 参数不如直接使用 find() 方法.下面两行代码是等价的:

    soup.find_all('title', limit=1)
    # [<title>The Dormouse's story</title>]
    
    soup.find('title')
    # <title>The Dormouse's story</title>
    

    唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.

    find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None .

    print(soup.find("nosuchtag"))
    # None
    

    soup.head.title  tag的名字 方法的简写.这个简写的原理就是多次调用当前tag的 find() 方法:

    soup.head.title
    # <title>The Dormouse's story</title>
    
    soup.find("head").find("title")
    # <title>The Dormouse's story</title>
    

    find_parents() 和 find_parent()

    find_parents( name , attrs , recursive , string , **kwargs )

    find_parent( name , attrs , recursive , string , **kwargs )

    我们已经用了很大篇幅来介绍 find_all()  find() 方法,Beautiful Soup中还有10个用于搜索的API.它们中的五个用的是与 find_all() 相同的搜索参数,另外5个与 find() 方法的搜索参数类似.区别仅是它们搜索文档的不同部分.

    记住: find_all()  find() 只搜索当前节点的所有子节点,孙子节点等. find_parents()  find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容. 我们从一个文档中的一个叶子节点开始:

    a_string = soup.find(string="Lacie")
    a_string
    # u'Lacie'
    
    a_string.find_parents("a")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    
    a_string.find_parent("p")
    # <p class="story">Once upon a time there were three little sisters; and their names were
    #  <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
    #  and they lived at the bottom of a well.</p>
    
    a_string.find_parents("p", class="title")
    # []
    

    文档中的一个<a>标签是是当前叶子节点的直接父节点,所以可以被找到.还有一个<p>标签,是目标叶子节点的间接父辈节点,所以也可以被找到.包含class值为”title”的<p>标签不是不是目标叶子节点的父辈节点,所以通过 find_parents() 方法搜索不到.

    find_parent()  find_parents() 方法会让人联想到 .parent  .parents 属性.它们之间的联系非常紧密.搜索父辈节点的方法实际上就是对 .parents 属性的迭代搜索.

    find_next_siblings() 合 find_next_sibling()

    find_next_siblings( name , attrs , recursive , string , **kwargs )

    find_next_sibling( name , attrs , recursive , string , **kwargs )

    这2个方法通过 .next_siblings 属性对当tag的所有后面解析 [5] 的兄弟tag节点进行迭代, find_next_siblings() 方法返回所有符合条件的后面的兄弟节点, find_next_sibling() 只返回符合条件的后面的第一个tag节点.

    first_link = soup.a
    first_link
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    
    first_link.find_next_siblings("a")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    first_story_paragraph = soup.find("p", "story")
    first_story_paragraph.find_next_sibling("p")
    # <p class="story">...</p>
    

    find_previous_siblings() 和 find_previous_sibling()

    find_previous_siblings( name , attrs , recursive , string , **kwargs )

    find_previous_sibling( name , attrs , recursive , string , **kwargs )

    这2个方法通过 .previous_siblings 属性对当前tag的前面解析 [5] 的兄弟tag节点进行迭代, find_previous_siblings() 方法返回所有符合条件的前面的兄弟节点, find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点:

    last_link = soup.find("a", id="link3")
    last_link
    # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
    
    last_link.find_previous_siblings("a")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    
    first_story_paragraph = soup.find("p", "story")
    first_story_paragraph.find_previous_sibling("p")
    # <p class="title"><b>The Dormouse's story</b></p>
    

    find_all_next() 和 find_next()

    find_all_next( name , attrs , recursive , string , **kwargs )

    find_next( name , attrs , recursive , string , **kwargs )

    这2个方法通过 .next_elements 属性对当前tag的之后的 [5] tag和字符串进行迭代, find_all_next() 方法返回所有符合条件的节点, find_next() 方法返回第一个符合条件的节点:

    first_link = soup.a
    first_link
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    
    first_link.find_all_next(string=True)
    # [u'Elsie', u',
    ', u'Lacie', u' and
    ', u'Tillie',
    #  u';
    and they lived at the bottom of a well.', u'
    
    ', u'...', u'
    ']
    
    first_link.find_next("p")
    # <p class="story">...</p>
    

    第一个例子中,字符串 “Elsie”也被显示出来,尽管它被包含在我们开始查找的<a>标签的里面.第二个例子中,最后一个<p>标签也被显示出来,尽管它与我们开始查找位置的<a>标签不属于同一部分.例子中,搜索的重点是要匹配过滤器的条件,并且在文档中出现的顺序而不是开始查找的元素的位置.

    find_all_previous() 和 find_previous()

    find_all_previous( name , attrs , recursive , string , **kwargs )

    find_previous( name , attrs , recursive , string , **kwargs )

    这2个方法通过 .previous_elements 属性对当前节点前面 [5] 的tag和字符串进行迭代, find_all_previous() 方法返回所有符合条件的节点, find_previous() 方法返回第一个符合条件的节点.

    first_link = soup.a
    first_link
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    
    first_link.find_all_previous("p")
    # [<p class="story">Once upon a time there were three little sisters; ...</p>,
    #  <p class="title"><b>The Dormouse's story</b></p>]
    
    first_link.find_previous("title")
    # <title>The Dormouse's story</title>
    

    find_all_previous("p") 返回了文档中的第一段(class=”title”的那段),但还返回了第二段,<p>标签包含了我们开始查找的<a>标签.不要惊讶,这段代码的功能是查找所有出现在指定<a>标签之前的<p>标签,因为这个<p>标签包含了开始的<a>标签,所以<p>标签一定是在<a>之前出现的.

    CSS选择器

    Beautiful Soup支持大部分的CSS选择器 http://www.w3.org/TR/CSS2/selector.html [6] , 在 Tag  BeautifulSoup 对象的 .select() 方法中传入字符串参数, 即可使用CSS选择器的语法找到tag:

    soup.select("title")
    # [<title>The Dormouse's story</title>]
    
    soup.select("p nth-of-type(3)")
    # [<p class="story">...</p>]
    

    通过tag标签逐层查找:

    soup.select("body a")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie"  id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    soup.select("html head title")
    # [<title>The Dormouse's story</title>]
    

    找到某个tag标签下的直接子标签 [6] :

    soup.select("head > title")
    # [<title>The Dormouse's story</title>]
    
    soup.select("p > a")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie"  id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    soup.select("p > a:nth-of-type(2)")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    
    soup.select("p > #link1")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    
    soup.select("body > a")
    # []
    

    找到兄弟节点标签:

    soup.select("#link1 ~ .sister")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie"  id="link3">Tillie</a>]
    
    soup.select("#link1 + .sister")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    

    通过CSS的类名查找:

    soup.select(".sister")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    soup.select("[class~=sister]")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    通过tag的id查找:

    soup.select("#link1")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    
    soup.select("a#link2")
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    

    同时用多种CSS选择器查询元素:

    soup.select("#link1,#link2")
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    

    通过是否存在某个属性来查找:

    soup.select('a[href]')
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    通过属性的值来查找:

    soup.select('a[href="http://example.com/elsie"]')
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    
    soup.select('a[href^="http://example.com/"]')
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    soup.select('a[href$="tillie"]')
    # [<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    soup.select('a[href*=".com/el"]')
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    

    通过语言设置来查找:

    multilingual_markup = """
     <p lang="en">Hello</p>
     <p lang="en-us">Howdy, y'all</p>
     <p lang="en-gb">Pip-pip, old fruit</p>
     <p lang="fr">Bonjour mes amis</p>
    """
    multilingual_soup = BeautifulSoup(multilingual_markup)
    multilingual_soup.select('p[lang|=en]')
    # [<p lang="en">Hello</p>,
    #  <p lang="en-us">Howdy, y'all</p>,
    #  <p lang="en-gb">Pip-pip, old fruit</p>]
    

    返回查找到的元素的第一个

    soup.select_one(".sister")
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    

    对于熟悉CSS选择器语法的人来说这是个非常方便的方法.Beautiful Soup也支持CSS选择器API, 如果你仅仅需要CSS选择器的功能,那么直接使用 lxml 也可以, 而且速度更快,支持更多的CSS选择器语法,但Beautiful Soup整合了CSS选择器的语法和自身方便使用API.

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

  • 相关阅读:
    Atitit 华为基本法 attilax读后感
    Atitit 华为管理者内训书系 以奋斗者为本 华为公司人力资源管理纲要 attilax读后感
    Atitit 项目版本管理gitflow 与 Forking的对比与使用
    Atitit 管理的模式扁平化管理 金字塔 直线型管理 垂直管理 水平管理 矩阵式管理 网状式样管理 多头管理 双头管理
    Atitit 乌合之众读后感attilax总结 与读后感结构规范总结
    深入理解 JavaScript 异步系列(4)—— Generator
    深入理解 JavaScript 异步系列(3)—— ES6 中的 Promise
    深入理解 JavaScript 异步系列(2)—— jquery的解决方案
    深入理解 JavaScript 异步系列(1)——基础
    使用 github + jekyll 搭建个人博客
  • 原文地址:https://www.cnblogs.com/amou/p/9185696.html
Copyright © 2011-2022 走看看