Parsing library module of beautifulsoup

Description: Beautiful Soup is a Python library can extract data from HTML or XML file.

    It enables document navigation through your favorite conventional converter, search, modify the document the way .Beautiful Soup will help you save hours or even days of work.

    Beautiful Soup 3 has stopped development, the official website recommended Beautiful Soup 4 in the current project, transplanted to BS4


  1 # mounted Beautiful Soup
   2 PIP beautifulsoup4 the install
   . 3  
  . 4 # parser installed
   . 5 the HTML parser Beautiful Soup Python standard library support, some third-party parser supports, one of which is lxml. Depending on the operating system, can select the following method to install lxml:
   . 6  
  . 7 $ APT-GET-lxml the install Python
   . 8  
  . 9 $ lxml the easy_install
 10  
. 11 $ lxml the install PIP
 12 is  
13 is another alternative parser is implemented in Python pure html5lib, html5lib analytical approaches browser same, the following methods may be selected to install html5lib:
 14  
15 $ APT-GET-html5lib the install the Python
 16  
. 17 $ the easy_install html5lib
 18 is  
. 19 $ html5lib the install PIP

The following table lists the main parser, as well as their advantages and disadvantages, as the official website recommended lxml parser, because of the higher efficiency. In previous versions and Python3 Python2.7.3 in the previous 3.2.2 version, you must install or lxml html5lib, because those versions of the Python standard library built-in HTML parsing method is not stable enough.

Basic use

  1 html_doc = """
  2 <html><head><title>The Dormouse's story</title></head>
  3 <body>
  4 <p class="title"><b>The Dormouse's story</b></p>
  5 
  6 <p class="story">Once upon a time there were three little sisters; and their names were
  7 <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
  8 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
  9 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
 10 and they lived at the bottom of a well.</p>
 11 
 12 <p class="story">...</p>
 13 """
 14 
 15 #基本使用:容错处理,文档的容错能力指的是在html代码不完整的情况下,使用该模块可以识别该错误。使用BeautifulSoup解析上述代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出
 16 from bs4 import BeautifulSoup
 17 soup=BeautifulSoup(html_doc,'lxml') #具有容错功能
 18 res=soup.prettify() #处理好缩进,结构化显示
 19 print(res)

遍历文档树

遍历文档树:即直接通过标签名字选择,特点是选择速度快,但如果存在多个相同的标签则只返回第一个

  1 soup = BeautifulSoup(html_doc,"lxml")  #第一个参数指定文本内容,第二个参数解析器
  2 
  3 # soup = BeautifulSoup(open("a.html"),"lxml")   #也可以打开一个文件创建实例
  4 print(soup.prettify())  #容错性的体现,自动补全
  5 print(soup.a)  #只找到了一个,而且是从整个文档树找
  6 print(soup.a.text)   #找到a标签里面的文本
  7 print(soup.text)   #找整个文档树种所有的文本
  8 print(soup.a.attrs)   #找a标签的所有属性,字典形式
  9 print(soup.a.attrs["href"])  #找a标签的href属性
 10 print(soup.p.b)  #嵌套查找,这是只找一个
 11 print(soup.p.contents)  #子节点,找到的是一个闭标签
 12 print(list(soup.p.children )) #得到生成器
 13 print(list(soup.p.descendants))  #所有的子子孙孙
 14 print(soup.a.parent)#找父亲
 15 print(list(soup.a.parent))#父亲的父亲的父亲
 16 
 17 print(soup.p.find_all() ) #标签名可以和find可以结合在一起使用
基本使用 View Code

   1、用法  2、获取标签的名称  3、获取标签的属性  4、获取标签的内容  5、嵌套选择
   6、子节点、子孙节点  7、父节点、祖先节点  8、兄弟节点

  1 #遍历文档树:即直接通过标签名字选择,特点是选择速度快,但如果存在多个相同的标签则只返回第一个
  2 html_doc = """
  3 <html><head><title>The Dormouse's story</title></head>
  4 <body>
  5 <p id="my p" class="title"><b id="bbb" class="boldest">The Dormouse's story</b></p>
  6 
  7 <p class="story">Once upon a time there were three little sisters; and their names were
  8 <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
  9 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
 10 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
 11 and they lived at the bottom of a well.</p>
 12 
 13 <p class="story">...</p>
 14 """
 15 
 16 #1、用法
 17 from bs4 import BeautifulSoup
 18 soup=BeautifulSoup(html_doc,'lxml')
 19 # soup=BeautifulSoup(open('a.html'),'lxml')
 20 
 21 print(soup.p) #存在多个相同的标签则只返回第一个
 22 print(soup.a) #存在多个相同的标签则只返回第一个
 23 
 24 #2、获取标签的名称
 25 print(soup.p.name)
 26 
 27 #3、获取标签的属性
 28 print(soup.p.attrs)
 29 
 30 #4、获取标签的内容
 31 print(soup.p.string) # p下的文本只有一个时,取到,否则为None
 32 print(soup.p.strings) #拿到一个生成器对象, 取到p下所有的文本内容
 33 print(soup.p.text) #取到p下所有的文本内容
 34 for line in soup.stripped_strings: #去掉空白
 35     print(line)
 36 
 37 
 38 '''
 39 如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None,如果只有一个子节点那么就输出该子节点的文本,比如下面的这种结构,soup.p.string 返回为None,但soup.p.strings就可以找到所有文本
 40 <p id='list-1'>
 41     哈哈哈哈
 42     <a class='sss'>
 43         <span>
 44             <h1>aaaa</h1>
 45         </span>
 46     </a>
 47     <b>bbbbb</b>
 48 </p>
 49 '''
 50 
 51 #5、嵌套选择
 52 print(soup.head.title.string)
 53 print(soup.body.a.string)
 54 
 55 
 56 #6、子节点、子孙节点
 57 print(soup.p.contents) #p下所有子节点
 58 print(soup.p.children) #得到一个迭代器,包含p下所有子节点
 59 
 60 for i,child in enumerate(soup.p.children):
 61     print(i,child)
 62 
 63 print(soup.p.descendants) #获取子孙节点,p下所有的标签都会选择出来
 64 for i,child in enumerate(soup.p.descendants):
 65     print(i,child)
 66 
 67 #7、父节点、祖先节点
 68 print(soup.a.parent) #获取a标签的父节点
 69 print(soup.a.parents) #找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...
 70 
 71 
 72 #8、兄弟节点
 73 print('=====>')
 74 print(soup.a.next_sibling) #下一个兄弟
 75 print(soup.a.previous_sibling) #上一个兄弟
 76 
 77 print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
 78 print(soup.a.previous_siblings) #上面的兄弟们=>生成器对象
遍历文档树 View Code

搜索文档数

1、五种过滤器

  1 from bs4 import BeautifulSoup
  2 
  3 html_doc = '''<html><head><title>The Dormouse's story</title></head>
  4 <body>
  5 <p class="title"><b>The Dormouse's story</b></p>
  6 <p class="title"><b>$75</b></p>
  7 <p id="meiyuan">啦啦啦啦啦啦</p>
  8 
  9 <p class="story">Once upon a time there were three little sisters; and their names were
 10 <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
 11 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
 12 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
 13 and they lived at the bottom of a well.</p>'''
 14 soup= BeautifulSoup(html_doc,"lxml")
 15 
 16 # 1、字符串:特点:是一种完全匹配的
 17 print(soup.find_all(name="a"))  #找到所有的a标签
 18 print(soup.find_all(name="a aa"))  #找不到,会打印一个[]
 19 print(soup.find_all(attrs={"class":"sister"}))
 20 print(soup.find_all(text="The Dormouse's story"))  #按照文本来找
 21 print(soup.find_all(name="b",text="The Dormouse's story"))  #找标签名是b,并且文本是The Dormouse's story
 22 print(soup.p.find(name="b").text)  #第一个p标签的b里面的文本
 23 print(soup.find_all(name="p",attrs={"class":"story"}))  #找到标签名是p,属性名是class,
 24 print(soup.find(name="p",attrs={"class":"story"}).find_all(name="a")[2])  #找到标签名是p,属性名是class的第二个a标签
 25 
 26 # 2、正则
 27 import re
 28 
 29 print(soup.find_all(name=re.compile("^b")))  #找b开头的的标签
 30 print(soup.find_all(attrs={"id":re.compile("link")}))  #找到id属性是link的
 31 print(soup.find_all(text=re.compile(r"\$")))  #找带有$价钱的文本
 32 
 33 # # 3、列表:如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.
 34 print(soup.find_all(name=["a",re.compile("^b")]))  #找a标签或者b标签开头的所有的标签
 35 print(soup.find_all(text=["$",]))  #找不到
 36 print(soup.find_all(text=[re.compile(r"\$")]))  #['$75']
 37 print(soup.find_all(text=["a",re.compile(r"\$")]))
 38 
 39 # # 4、True:可以匹配任何值
 40 print(soup.find_all(name=True))  #找到所有标签的标签名
 41 print(soup.find_all(attrs={"id":True}))#找到只要有id属性的
 42 #
 43 print(soup.find_all(name="p",attrs={"id":True}))# 找到有id属性的p标签
 44 # 5、方法:如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
 45 #
 46 # # 有class属性没有id属性的
 47 def has_class_not_id(tag):
 48     return tag.has_attr('class') and not tag.has_attr('id')
 49     # return tag.has_attr('id') and not tag.has_attr('class')
 50 
 51     # return tag.name =="a" and tag.has_attr("class") and not tag.has_attr("id")
 52 # #     #只找a标签
 53 print(soup.find_all(has_class_not_id))  #默认是按照标签来找的
 54 
 55 
 56 print(soup.find_all(name="a",limit=2))#找所有的a标签,只找前两个
 57 print(soup.body.find_all(attrs={"class":"sister"},recursive=False))#找属性为sister的
 58 print(soup.html.find_all('a'))
 59 print(soup.html.find_all('a',recursive=False))
 60 # recursive = True  #从子子孙孙都找到了
 61 # recursive = False #如果只想搜索tag的直接子节点(就不往里面找了),可以使用参数 recursive=False .
 62 
 63 # **kwargs
 64 print(soup.find_all(attrs={"class":"sister"}))
 65 print(soup.find_all(class_="sister"))  #这两个是一样的
 66 
 67 print(soup.find_all(attrs={"id":"link3"})) #这两个是一样的,只是表示方式不一样
 68 print(soup.find_all(id="link3"))
五种过滤器 View Code

2.find_all( name , attrs , recursive , text , **kwargs )

  1 #2、find_all( name , attrs , recursive , text , **kwargs )
  2 #2.1、name: 搜索name参数的值可以使任一类型的 过滤器 ,字符窜,正则表达式,列表,方法或是 True .
  3 print(soup.find_all(name=re.compile('^t')))
  4 
  5 #2.2、keyword: key=value的形式,value可以是过滤器:字符串 , 正则表达式 , 列表, True .
  6 print(soup.find_all(id=re.compile('my')))
  7 print(soup.find_all(href=re.compile('lacie'),id=re.compile('\d'))) #注意类要用class_
  8 print(soup.find_all(id=True)) #查找有id属性的标签
  9 
 10 # 有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性:
 11 data_soup = BeautifulSoup('<div data-foo="value">foo!</div>','lxml')
 12 # data_soup.find_all(data-foo="value") #报错:SyntaxError: keyword can't be an expression
 13 # 但是可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag:
 14 print(data_soup.find_all(attrs={"data-foo": "value"}))
 15 # [<div data-foo="value">foo!</div>]
 16 
 17 #2.3、按照类名查找,注意关键字是class_,class_=value,value可以是五种选择器之一
 18 print(soup.find_all('a',class_='sister')) #查找类为sister的a标签
 19 print(soup.find_all('a',class_='sister ssss')) #查找类为sister和sss的a标签,顺序错误也匹配不成功
 20 print(soup.find_all(class_=re.compile('^sis'))) #查找类为sister的所有标签
 21 
 22 #2.4、attrs
 23 print(soup.find_all('p',attrs={'class':'story'}))
 24 
 25 #2.5、text: 值可以是:字符,列表,True,正则
 26 print(soup.find_all(text='Elsie'))
 27 print(soup.find_all('a',text='Elsie'))
 28 
 29 #2.6、limit参数:如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果
 30 print(soup.find_all('a',limit=2))
 31 
 32 #2.7、recursive:调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False .
 33 print(soup.html.find_all('a'))
 34 print(soup.html.find_all('a',recursive=False))
 35 
 36 '''
 37 像调用 find_all() 一样调用tag
 38 find_all() 几乎是Beautiful Soup中最常用的搜索方法,所以我们定义了它的简写方法. BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 find_all() 方法相同,下面两行代码是等价的:
 39 soup.find_all("a")
 40 soup("a")
 41 这两行代码也是等价的:
 42 soup.title.find_all(text=True)
 43 soup.title(text=True)
 44 '''
find_all View Code

3、find( name , attrs , recursive , text , **kwargs )

  1 #3、find( name , attrs , recursive , text , **kwargs )
  2 find_all() 方法将返回文档中符合条件的所有tag,尽管有时候我们只想得到一个结果.比如文档中只有一个<body>标签,那么使用 find_all() 方法来查找<body>标签就不太合适, 使用 find_all 方法并设置 limit=1 参数不如直接使用 find() 方法.下面两行代码是等价的:
  3 
  4 soup.find_all('title', limit=1)
  5 # [<title>The Dormouse's story</title>]
  6 soup.find('title')
  7 # <title>The Dormouse's story</title>
  8 
  9 唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.
 10 find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None .
 11 print(soup.find("nosuchtag"))
 12 # None
 13 
 14 soup.head.title 是 tag的名字 方法的简写.这个简写的原理就是多次调用当前tag的 find() 方法:
 15 
 16 soup.head.title
 17 # <title>The Dormouse's story</title>
 18 soup.find("head").find("title")
 19 # <title>The Dormouse's story</title>
find View Code

4、其他方法

见官网:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#find-parents-find-parent

5、CSS选择器

  1 #该模块提供了select方法来支持css,详见官网:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#id37
  2 html_doc = """
  3 <html><head><title>The Dormouse's story</title></head>
  4 <body>
  5 <p class="title">
  6     <b>The Dormouse's story</b>
  7     Once upon a time there were three little sisters; and their names were
  8     <a href="http://example.com/elsie" class="sister" id="link1">
  9         <span>Elsie</span>
 10     </a>
 11     <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
 12     <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
 13     <div class='panel-1'>
 14         <ul class='list' id='list-1'>
 15             <li class='element'>Foo</li>
 16             <li class='element'>Bar</li>
 17             <li class='element'>Jay</li>
 18         </ul>
 19         <ul class='list list-small' id='list-2'>
 20             <li class='element'><h1 class='yyyy'>Foo</h1></li>
 21             <li class='element xxx'>Bar</li>
 22             <li class='element'>Jay</li>
 23         </ul>
 24     </div>
 25     and they lived at the bottom of a well.
 26 </p>
 27 <p class="story">...</p>
 28 """
 29 from bs4 import BeautifulSoup
 30 soup=BeautifulSoup(html_doc,'lxml')
 31 
 32 #1、CSS选择器
 33 print(soup.p.select('.sister'))
 34 print(soup.select('.sister span'))
 35 
 36 print(soup.select('#link1'))
 37 print(soup.select('#link1 span'))
 38 
 39 print(soup.select('#list-2 .element.xxx'))
 40 
 41 print(soup.select('#list-2')[0].select('.element')) #可以一直select,但其实没必要,一条select就可以了
 42 
 43 # 2、获取属性
 44 print(soup.select('#list-2 h1')[0].attrs)
 45 
 46 # 3、获取内容
 47 print(soup.select('#list-2 h1')[0].get_text())
css选择器 View Code

修改文档数

链接:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#id40



归类 : python爬虫

Guess you like

Origin www.cnblogs.com/lz1996/p/12043713.html