python学习之 beautifulsoup选择器

来源:官方文档 http://beautifulsoup.readthedocs.io/zh_CN/latest/

如何使用

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

from bs4 import BeautifulSoup

soup = BeautifulSoup(open("index.html"))

soup = BeautifulSoup("data")

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

对象的种类

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

Tag

Tag 对象与XML或HTML原生文档中的tag(即标签)相同:

soup = BeautifulSoup('Extremely bold')
tag = soup.b
type(tag)
# 

Tag有很多方法和属性,在 遍历文档树 和 搜索文档树 中有详细解释.现在介绍一下tag中最重要的属性: name和attributes

Name

每个tag都有自己的名字,通过 .name 来获取:

tag.name
# u'b'

如果改变了tag的name,那将影响所有通过当前Beautiful Soup对象生成的HTML文档:

tag.name = "blockquote"
tag
# 
Extremely bold

Attributes

一个tag可能有很多个属性. tag  class="boldest"> 有一个 “class” 的属性,值为 “boldest” . tag的属性的操作方法与字典相同:

tag['class']
# u'boldest'(获得的是一个unicode对象,不是NavitableString)
(关于unicode对象和string对象的区别,参见http://blog.csdn.net/sentimental_dog/article/details/52658725)

也可以直接”点”取属性, 比如: .attrs :

tag.attrs
# {u'class': u'boldest'}

tag的属性可以被添加,删除或修改. 再说一次, tag的属性操作方法与字典一样

tag['class'] = 'verybold'
tag['id'] = 1
tag
# 
Extremely bold
del tag['class'] del tag['id'] tag #
Extremely bold
tag['class'] # KeyError: 'class' print(tag.get('class')) # None

如果我们需要获取某个class='asdasd'标签的‘title’的属性值
我们可以先用tag=soup.find(class_='asdasd')
然后用tag['title]来获得


可以遍历的字符串

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

tag.string
# u'Extremely bold'
type(tag.string)
# 

一个 NavigableString 字符串与Python中的Unicode字符串相同,并且还支持包含在 遍历文档树 和 搜索文档树 中的一些特性. 通过 unicode() 方法可以直接将 NavigableString对象转换成Unicode字符串:

unicode_string = unicode(tag.string)
unicode_string
# u'Extremely bold'
type(unicode_string)
# 

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

tag.string.replace_with("No longer bold")
tag
# 
No longer bold

NavigableString 对象支持 遍历文档树 和 搜索文档树 中定义的大部分属性, 并非全部.尤其是,一个字符串不能包含其它内容(tag能够包含字符串或是其它tag),字符串不支持.contents 或 .string 属性或 find() 方法.

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

BeautifulSoup

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

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

soup.name
# u'[document]'

注释及特殊字符串

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

markup = ""
soup = BeautifulSoup(markup)
comment = soup.b.string
type(comment)
# 

Comment 对象是一个特殊类型的 NavigableString 对象:

comment
# u'Hey, buddy. Want to buy a used parser'

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

print(soup.b.prettify())
# 
#  
# 

tag的名字

操作文档树最简单的方法就是告诉它你想获取的tag的name.如果想获取 标签,只要用 soup.head :

soup.head
# The Dormouse's story

soup.title
# The Dormouse's story

这是个获取tag的小窍门,可以在文档树的tag中多次调用这个方法.下面的代码可以获取标签中的第一个标签:

soup.body.b
# The Dormouse's story

通过点取属性的方式只能获得当前名字的第一个tag:

soup.a
# Elsie

如果想要得到所有的标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到Searching the tree 中描述的方法,比如: find_all()

soup.find_all('a')
# [Elsie,
#  Lacie,
#  Tillie]

.contents 和 .children

tag的 .contents 属性可以将tag的子节点以列表的方式输出:

head_tag = soup.head
head_tag
# The Dormouse's story

head_tag.contents
[The Dormouse's story]

title_tag = head_tag.contents[0]
title_tag
# The Dormouse's story
title_tag.contents
# [u'The Dormouse's story']

BeautifulSoup 对象本身一定会包含子节点,也就是说标签也是 BeautifulSoup对象的子节点:

len(soup.contents)
# 1
soup.contents[0].name
# u'html'

字符串没有 .contents 属性,因为字符串没有子节点:

text = title_tag.contents[0]
text.contents
# AttributeError: 'NavigableString' object has no attribute 'contents'

通过tag的 .children 生成器,可以对tag的子节点进行循环:

for child in title_tag.children:
    print(child)
    # The Dormouse's story

.descendants

.contents 和 .children 属性仅包含tag的直接子节点.例如,标签只有一个直接子节点</span></p> <div class="highlight-python" style="color:rgb(62,67,73)"> <div class="highlight" style=""> <pre style="overflow-x:auto; overflow-y:hidden; font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; padding:7px 30px; margin-top:15px; margin-bottom:15px; line-height:1.3em; background:rgb(238,238,238)"><span class="n">head_tag</span><span class="o" style="color:rgb(102,102,102)">.</span><span class="n">contents</span> <span class="c1" style="color:rgb(64,128,144); font-style:italic"># [<title>The Dormouse's story]

但是标签也包含一个子节点:字符串 “The Dormouse’s story”,这种情况下字符串 “The Dormouse’s story”也属于<head>标签的子孙节点. </span><code class="docutils literal" style="color:rgb(34,34,34); font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; background-color:rgb(236,240,243)"><span class="pre">.descendants</span></code><span style="color:#3e4349"> 属性可以对</span><span style="color:#ff0000">所有</span><span style="color:#3e4349">tag的子孙节点进行递归循环 </span>[5]<span style="color:#3e4349"> :</span></p> <div class="highlight-python" style="color:rgb(62,67,73)"> <div class="highlight" style=""> <pre style="overflow-x:auto; overflow-y:hidden; font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; padding:7px 30px; margin-top:15px; margin-bottom:15px; line-height:1.3em; background:rgb(238,238,238)"><span class="k" style="color:rgb(0,112,32); font-weight:bold">for</span> <span class="n">child</span> <span class="ow" style="color:rgb(0,112,32); font-weight:bold">in</span> <span class="n">head_tag</span><span class="o" style="color:rgb(102,102,102)">.</span><span class="n">descendants</span><span class="p">:</span> <span class="k" style="color:rgb(0,112,32); font-weight:bold">print</span><span class="p">(</span><span class="n">child</span><span class="p">)</span> <span class="c1" style="color:rgb(64,128,144); font-style:italic"># <title>The Dormouse's story # The Dormouse's story

上面的例子中, 标签只有一个子节点,但是有2个子孙节点:节点和的子节点, BeautifulSoup 有一个直接子节点(节点),却有很多子孙节点:

len(list(soup.children))
# 1
len(list(soup.descendants))
# 25

.string

如果tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 .string 得到子节点:

title_tag.string
# u'The Dormouse's story'

如果一个tag仅有一个子节点,那么这个tag也可以使用 .string 方法,输出结果与当前唯一子节点的 .string 结果相同:

head_tag.contents
# [The Dormouse's story]

head_tag.string
# u'The Dormouse's story'

如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容,.string 的输出结果是 None :

print(soup.html.string)
# None

搜索文档树

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

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

html_doc = """
The Dormouse's story

The Dormouse's story

Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well.

...

""" from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc, 'html.parser')

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

过滤器

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

字符串

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

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

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

正则表达式

如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以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

使用find_all经常需要配合 for 循环

列表

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

find_all()

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

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

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

soup.find_all("p", "title")
# [

The Dormouse's story

]
soup.find_all("a") # [Elsie, # Lacie, # Tillie] soup.find_all(id="link2") # [Lacie] import re soup.find(string=re.compile("sisters")) # u'Once upon a time there were three little sisters; and their names were\n'

有几个方法很相似,还有几个方法是新的,参数中的 string 和 id 是什么含义? 为什么find_all("p", "title") 返回的是CSS Class为”title”的

标签? 我们来仔细看一下find_all() 的参数

name 参数

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

简单的用法如下:

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

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

keyword 参数

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

soup.find_all(id='link2')
# [Lacie]

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

soup.find_all(href=re.compile("elsie"))
# [Elsie]

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

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

soup.find_all(id=True)
# [Elsie,
#  Lacie,
#  Tillie]

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

soup.find_all(href=re.compile("elsie"), id='link1')
# [three]

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

data_soup = BeautifulSoup('
foo!
'
) 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"})
# [
foo!
]

按CSS搜索

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

soup.find_all("a", class_="sister")
# [Elsie,
#  Lacie,
#  Tillie]

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

soup.find_all(class_=re.compile("itl"))
# [

The Dormouse's story

]
def has_six_characters(css_class): return css_class is not None and len(css_class) == 6 soup.find_all(class_=has_six_characters) # [Elsie, # Lacie, # Tillie]

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

css_soup = BeautifulSoup('

'
) css_soup.find_all("p", class_="strikeout") # [

]
css_soup.find_all("p", class_="body") # [

]

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

css_soup.find_all("p", class_="body strikeout")
# [

]

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

soup.find_all("a", attrs={"class": "sister"})
# [Elsie,
#  Lacie,
#  Tillie]

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”的标签:

limit 参数

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

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

soup.find_all("a", limit=2)
# [Elsie,
#  Lacie]

recursive 参数

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

一段简单的文档:


 
  
   The Dormouse's story
  
 
...

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

soup.html.find_all("title")
# [The Dormouse's story]

soup.html.find_all("title", recursive=False)
# []

这是文档片段


        
        
        The Dormouse's story
    
        
        ...

标签在 <html> 标签下, 但并不是直接子节点, <head> 标签才是直接子节点. 在允许查询所有后代节点时 Beautiful Soup 能够查找到 <title> 标签. 但是使用了 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">recursive=False</span></code>参数之后,只能查找直接子节点,这样就查不到 <title> 标签了.</p> <p style="line-height:1.4em">Beautiful Soup 提供了多种DOM树搜索方法. 这些方法都使用了类似的参数定义. 比如这些方法: <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">find_all()</span></code>: <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">name</span></code>, <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">attrs</span></code>, <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">text</span></code>, <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">limit</span></code>. 但是只有 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">find_all()</span></code> 和 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">find()</span></code> 支持<code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">recursive</span></code> 参数.</p> <div> <div class="section" id="find-all-tag" style="color:rgb(62,67,73); font-family:'goudy old style','minion pro','bell mt',Georgia,'Hiragino Mincho Pro',serif; font-size:17px"> <h2 style="font-family:Garamond,Georgia,serif; font-weight:normal; margin:30px 0px 10px; padding:0px; font-size:30.6px"> 像调用 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:transparent">find_all()</code> 一样调用tag</h2> <p style="line-height:1.4em"><code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">find_all()</span></code> 几乎是Beautiful Soup中最常用的搜索方法,所以我们定义了它的简写方法.<code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">BeautifulSoup</span></code> 对象和 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">tag</span></code> 对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">find_all()</span></code> 方法相同,下面两行代码是等价的:</p> <div class="highlight-python"> <div class="highlight" style=""> <pre style="overflow-x:auto; overflow-y:hidden; font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; padding:7px 30px; margin-top:15px; margin-bottom:15px; line-height:1.3em; background:rgb(238,238,238)"><span class="n">soup</span><span class="o" style="color:rgb(102,102,102)">.</span><span class="n">find_all</span><span class="p">(</span><span class="s2" style="color:rgb(64,112,160)">"a"</span><span class="p">)</span> <span class="n">soup</span><span class="p">(</span><span class="s2" style="color:rgb(64,112,160)">"a"</span><span class="p">)</span> </pre> </div> </div> <p style="line-height:1.4em">这两行代码也是等价的:</p> <div class="highlight-python"> <div class="highlight" style=""> <pre style="overflow-x:auto; overflow-y:hidden; font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; padding:7px 30px; margin-top:15px; margin-bottom:15px; line-height:1.3em; background:rgb(238,238,238)"><span class="n">soup</span><span class="o" style="color:rgb(102,102,102)">.</span><span class="n">title</span><span class="o" style="color:rgb(102,102,102)">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">string</span><span class="o" style="color:rgb(102,102,102)">=</span><span class="bp" style="color:rgb(0,112,32)">True</span><span class="p">)</span> <span class="n">soup</span><span class="o" style="color:rgb(102,102,102)">.</span><span class="n">title</span><span class="p">(</span><span class="n">string</span><span class="o" style="color:rgb(102,102,102)">=</span><span class="bp" style="color:rgb(0,112,32)">True</span><span class="p">)</span> </pre> <div> <span class="p"><br> </span> </div> </div> </div> </div> <div class="section" id="find" style="color:rgb(62,67,73); font-family:'goudy old style','minion pro','bell mt',Georgia,'Hiragino Mincho Pro',serif; font-size:17px"> </div> <div class="section" id="id27" style="color:rgb(62,67,73); font-family:'goudy old style','minion pro','bell mt',Georgia,'Hiragino Mincho Pro',serif; font-size:17px"> <div class="section" id="id41"> <h2 style="font-family:Garamond,Georgia,serif; font-weight:normal; margin:30px 0px 10px; padding:0px; font-size:30.6px"> CSS选择器</h2> <p style="line-height:1.4em">Beautiful Soup支持大部分的CSS选择器 http://www.w3.org/TR/CSS2/selector.html [6] , 在 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">Tag</span></code>或 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">BeautifulSoup</span></code> 对象的 <code class="docutils literal" style="font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; color:rgb(34,34,34); background-color:rgb(236,240,243)"><span class="pre">.select()</span></code> 方法中传入字符串参数, 即可使用CSS选择器的语法找到tag:</p> <div class="highlight-python"> <div class="highlight" style=""> <pre style="overflow-x:auto; overflow-y:hidden; font-family:Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; font-size:0.9em; padding:7px 30px; margin-top:15px; margin-bottom:15px; line-height:1.3em; background:rgb(238,238,238)"><span class="n">soup</span><span class="o" style="color:rgb(102,102,102)">.</span><span class="n">select</span><span class="p">(</span><span class="s2" style="color:rgb(64,112,160)">"title"</span><span class="p">)</span> <span class="c1" style="color:rgb(64,128,144); font-style:italic"># [<title>The Dormouse's story] soup.select("p nth-of-type(3)") # [

...

]

通过tag标签逐层查找:

soup.select("body a")
# [Elsie,
#  Lacie,
#  Tillie]

soup.select("html head title")
# [The Dormouse's story]

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

soup.select("head > title")
# [The Dormouse's story]

soup.select("p > a")
# [Elsie,
#  Lacie,
#  Tillie]

soup.select("p > a:nth-of-type(2)")
# [Lacie]

soup.select("p > #link1")
# [Elsie]

soup.select("body > a")
# []

找到兄弟节点标签:

soup.select("#link1 ~ .sister")
# [Lacie,
#  Tillie]

soup.select("#link1 + .sister")
# [Lacie]

通过CSS的类名查找:

soup.select(".sister")
# [Elsie,
#  Lacie,
#  Tillie]

soup.select("[class~=sister]")
# [Elsie,
#  Lacie,
#  Tillie]

通过tag的id查找:

soup.select("#link1")
# [Elsie]

soup.select("a#link2")
# [Lacie]

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

soup.select("#link1,#link2")
# [Elsie,
#  Lacie]

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

soup.select('a[href]')
# [Elsie,
#  Lacie,
#  Tillie]

通过属性的值来查找:

soup.select('a[href="http://example.com/elsie"]')
# [Elsie]

soup.select('a[href^="http://example.com/"]')
# [Elsie,
#  Lacie,
#  Tillie]

soup.select('a[href$="tillie"]')
# [Tillie]

soup.select('a[href*=".com/el"]')
# [Elsie]

通过语言设置来查找:

multilingual_markup = """
 

Hello

Howdy, y'all

Pip-pip, old fruit

Bonjour mes amis

""" multilingual_soup = BeautifulSoup(multilingual_markup) multilingual_soup.select('p[lang|=en]') # [

Hello

,
#

Howdy, y'all

,
#

Pip-pip, old fruit

]

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

soup.select_one(".sister")
# Elsie

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










你可能感兴趣的:(机器学习)