• 02 爬虫数据解析之re,xpath,beautifulsoup


    一.正则匹配

    简单用法演示:

     1 字符:
     2 print(re.findall(".","abccc31223dn哈哈")) ###  . 匹配除了换行符以外的任意字符,搭配re.S可搭配任意字符(包括空行)#['a', 'b', 'c', 'c', 'c', '3', '1', '2', '2', '3', 'd', 'n', '哈', '哈']
     3 print(re.findall("ab[c,d]f","ab,f")) #匹配集合中任意一个字符,注意逗号不是分隔符,[]不需要分隔符
     4 print(re.findall("abdf","ab5f")) #数字[0 - 9]
     5 print(re.findall("abDf","ab5f")) #非数字 结果为[]
     6 print(re.findall("abwf","ab_f")) #数字、字母、下划线、中文 结果:['ab_f']
     7 print(re.findall("abWf","ab$f"))   #非w也就是非(数字、字母、下划线、中文 ) 结果为:['ab$f']
     8 print(re.findall("absf","ab f"))  # 所有的空白字符包,括空格、制表符、换页符等等 结果为:['ab f']
     9 print(re.findall("abSf","ab f"))  # S 非空白  结果为:[]
    10 
    11 
    12 量词:
    13 print(re.findall("abc*","abccc")) #['abccc']  任意多次  >=0  贪婪匹配
    14 print(re.findall("abc?","abccc"))  #['abc'] 可有可无  0次或者1次 惰性匹配
    15 print(re.findall("abc+","ab"))  #至少1次   >=1 没有匹配不成功
    16 print(re.findall("abc{3}","abcc")) #固定m次 不够匹配不成功,超过了m个剩下的字符不要
    17 print(re.findall("abc{3,}","abccccc")) #至少m次 不够匹配不成功,超过了m个剩下的字符全要
    18 print(re.findall("abc{3,5}","abccccccc")) #固定3-5次不够匹配不成功,超过3-5的字符不要
    19 
    20 边界:
    21 print(re.findall("^(.*?)c$","abccdsac")) #: 以某某结尾
    22 print(re.findall("^a(.*?)$","abccdsac")) #: 以某某开头
    23 
    24 分组:(ab)
    25 贪婪模式: .*
    26 非贪婪(惰性)模式: .*?
    27 
    28 re.I : 忽略大小写
    29 re.M :多行匹配
    30 re.S :单行匹配
    31 
    32 re.sub(正则表达式, 替换内容, 字符串)
    View Code

    二.Xpath

    如何使用xpath?

    1.下载:pip install lxml
    2.导包:from lxml import etree
    
    3.将html文档或者xml文档转换成一个etree对象,然后调用对象中的方法查找指定的节点
    
      2.1 本地文件:tree = etree.parse(文件名)
                    tree.xpath("xpath表达式")
    
      2.2 网络数据:tree = etree.HTML(网页内容字符串)
                    tree.xpath("xpath表达式")

    xpath用法展示参考如下:

    1.文档文件

     1 # 文本:
     2 doc='''
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8" />
     6     <title>测试bs4</title>
     7 </head>
     8 <body>
     9     <div>
    10         <p>百里守约</p>
    11     </div>
    12     <div class="song">
    13         <p>李清照</p>
    14         <p>王安石</p>
    15         <p>苏轼</p>
    16         <p>柳宗元</p>
    17         <a href="http://www.song.com/" title="赵匡胤" target="_self">
    18             <span>this is span</span>
    19         宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
    20         <a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
    21         <img src="http://www.baidu.com/meinv.jpg" alt="" />
    22     </div>
    23     <div class="tang">
    24         <ul>
    25             <li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
    26             <li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
    27             <li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
    28             <li><a href="http://www.sina.com" class="du">杜甫</a></li>
    29             <li><a href="http://www.dudu.com" class="du">杜牧</a></li>
    30             <li><b>杜小月</b></li>
    31             <li><i>度蜜月</i></li>
    32             <li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
    33         </ul>
    34     </div>
    35 </body>
    36 </html>
    37 '''
    View Code

    2.xpath查询实例

     1 from lxml import etree
     2 etree.parse("github.html")   #用于打开文件 parse
     3 tree=etree.HTML(doc)         #打开HTML文档 用.HTML即可
     4 
     5 
     6 注意在使用xpath,方法是 // 代表打开的整个文档 /代表下一级
     7 属性定位:
     8     找到class属性值为song的div标签
     9 ret = tree.xpath("//div[@class='song']")
    10 
    11 层级&索引定位:
    12     找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a的网址
    13 ret = tree.xpath("//div[@class='tang']/ul/li[2]/a/@href")
    14 print(ret)
    15 
    16 
    17 逻辑运算:
    18     #找到href属性值为空且class属性值为du的a标签
    19 ret = tree.xpath('//a[@class="du" and @href=""]')
    20 print(ret)
    21 
    22 
    23 模糊匹配:
    24 查找属性title包含ng的a标签的内容
    25 ret = tree.xpath('//a[contains(@title,"ng")]/text()')   #注意:在contains和starts-with 中@xx和格式是以逗号,分开的
    26 print(ret)
    27 查找属性title以qin开始的a标签的内容
    28 ret=tree.xpath("//a[starts-with(@title,'qin')]/text()")
    29 print(ret)
    30 
    31 
    32 
    33 取文本:
    34     # /表示获取某个标签下的文本内容
    35     # //表示获取某个标签下的文本内容和所有子标签下的文本内容
    36 
    37 ret = tree.xpath('div[@class="song"]/p[1]/text()')
    38 ret = tree.xpath('div[@class="tang"]//text()')
    39 
    40 取属性:
    41 ret = tree.xpath('div[@class="tang"]//li[2]/a/@href')
    View Code

    三:Beautifulsoup(BS)

    概念:简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:

    '''
    Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
    它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
    '''

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.你可能在寻找 Beautiful Soup3 的文档,Beautiful Soup 3 目前已经停止开发,官网推荐在现在的项目中使用Beautiful Soup 4。

    解析器:

    Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。

    下面具体介绍BS的语法以及相应操作:

    1.使用流程

    - 导包:from bs4 import BeautifulSoup
    - 使用方式:可以将一个html文档,转化为BeautifulSoup对象,然后通过对象的方法或者属性去查找指定的节点内容
        (1)转化本地文件:
             - soup = BeautifulSoup(open('本地文件'), 'lxml')
        (2)转化网络文件:
             - soup = BeautifulSoup('字符串类型或者字节类型', 'lxml')
        (3)打印soup对象显示内容为html文件中的内容

    2.基本方法总结:

    (1)根据标签名查找
            - soup.a   只能找到第一个符合要求的标签
        (2)获取属性
            - soup.a.attrs  获取a所有的属性和属性值,返回一个字典
            - soup.a.attrs['href']   获取href属性
            - soup.a['href']   也可简写为这种形式
        (3)获取内容
            - soup.a.string
            - soup.a.text
            - soup.a.get_text()
           【注意】如果标签还有标签,那么string获取到的结果为None,而其它两个,可以获取文本内容
        (4)find:找到第一个符合要求的标签
            - soup.find('a')  找到第一个符合要求的
            - soup.find('a', title="xxx")
            - soup.find('a', alt="xxx")
            - soup.find('a', class_="xxx")
            - soup.find('a', id="xxx")
        (5)find_all:找到所有符合要求的标签
            - soup.find_all('a')
            - soup.find_all(['a','b']) 找到所有的a和b标签
            - soup.find_all('a', limit=2)  限制前两个
        (6)根据选择器选择指定的内容
                   select:soup.select('#feng')
            - 常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器
                - 层级选择器:
                    div .dudu #lala .meme .xixi  下面好多级
                    div > p > a > .lala          只能是下面一级
            【注意】select选择器返回永远是列表,需要通过下标提取指定的对象
    View Code

    3.基本方法示例:

    from bs4 import BeautifulSoup
    soup=BeautifulSoup(html_doc,"lxml")
    查找第一个a标签对象
    print(soup.a)
    print(type(soup.a)) # 查找到的标签类型为:<class 'bs4.element.Tag'> 是一个标签对象
    
    ################################################## 一 Tag对象的操作 ###################################################
    ------------------->> 属性操作
    print(soup.a.attrs)   #返回一个字典 结果:{'href': 'http://example.com/elsie', 'class': ['sister'], 'id': 'link1'}
    print(soup.a.attrs["href"]) #结果为:http://example.com/elsie
    print(soup.a.attrs["class"]) #结果为:['sister']
    print(soup.a.attrs.get("id"))  #结果为:link1
    建议取法:
    print(soup.a["href"])  # http://example.com/elsie
    
    ------------------->> 文本操作
    print(soup.a.text) # Elsie
    print(soup.a.get_text()) # Elsie   #text和get_text() 取得的结果是一样的.调用方式不一样而已
    print(soup.a.string)  # Elsie
    
    #注意:text和string正常情况下取得的结果是一样,但取得的标签内含有多个标签取内容时:text全部取出 string不取
    print(soup.p.text)   # The Dormouse's story123
    print(soup.p.string) # None
    View Code

    4.有关find_all和all,以及selector的具体使用

     1 # 两个重要的搜索方法:find,find_all()
     2 ################################################ 二 find,find_all()###########################################
     3 
     4 
     5 #------------------------------>>  2.1 find_all()
     6 # 1.取出文本中所有a标签,并循环打印连接和属性
     7 # for link in soup.find_all("a"):
     8 #     print(link["href"],link['class'])
     9 '''
    10 #结果为:
    11 http://example.com/elsie    ['sister']
    12 http://example.com/lacie    ['sister']
    13 http://example.com/tillie   ['sister']
    14 '''
    15 
    16 #相应参数: find_all(self, name=None, attrs={}, recursive=True, text=None,limit=None, **kwargs):
    17 
    18 #------------------>>  2.1.1 name参数:name的五种过滤器: 字符串、正则表达式、列表、True、方法
    19 #1.1、字符串:即标签名
    20 # print(soup.find_all("a"))  # name="a"
    21 
    22 #1.2、正则表达式
    23 # import re
    24 # print(soup.find_all(re.compile('^p'))) #找出p开头的标签,结果有body和b标签
    25 
    26 '''
    27 知识补充:re.compile()在正则表达式中的应用
    28 cd = re.compile('abc{2}')
    29 ret = re.findall(cd,"abccc")
    30 print(ret)
    31 
    32 '''
    33 
    34 #1.3、列表:如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签:
    35 # print(soup.find_all(["a","b"])) # name=["a","b"]  查找a标签和b标签
    36 
    37 #1.4、True:可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
    38 # print(soup.find_all(True))
    39 # for tag in soup.find_all(True):
    40 #     print(tag.name)
    41 
    42 #1.5、方法:如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
    43 # def has_class_but_no_id(tag):
    44 #     return tag.has_attr('class') and not tag.has_attr('id')
    45 # print(soup.find_all(has_class_but_no_id))
    46 
    47 
    48 
    49 #------------------>> 2.1.2 属性参数 attrs={}
    50 # print(soup.find_all("a",attrs={"class":"sister","id":"link2"}))
    51 # print(soup.find_all("a",id="link2"))
    52 # print(soup.find_all("a",class_="sister"))  #因为class是关键字,需要查找的话在class加下划线,形式为:class_
    53 
    54 #------------------>>  2.1.3 文本参数
    55 # print(soup.find_all("a",text="Elsie"))
    56 
    57 #------------------>> 2.1.4 limit参数
    58 # print(soup.find_all("a",limit=2)) #limit主要限制查找的条数
    59 
    60 #------------------>> 2.1.5 recursive参数
    61 #recursive:调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,
    62 # 如果只想搜索tag的直接子节点,可以使用参数 recursive=False .
    63 
    64 # print(soup.find_all("div",recursive=False))   ##结果为[],因为第一层没有div
    65 # print("----------------")
    66 # print(soup.body.find_all("div",recursive=False))   #有结果 因为当前层为body 也就是说只找第一层,下面的层次不管有没有都不会去找了
    67 
    68 #  局部查找
    69 # print(soup.div.find_all(recursive=False))   ##只找div的子标签,子孙标签不管
    70 
    71 
    72 ################################################ 2.2 find()
    73 
    74 # print(soup.find("a")) # 等同于 soup.a
    75 #  find参数和find_all完全一样,但find只找一个标签
    76 
    77 ################################################ 三 selector ##################################################
    78 
    79 #  这个selector等同于css选择器
    80 
    81 # print(soup.select(".sister"))
    82 # print(soup.select("#link2"))
    83 # print(soup.select(".c1 a"))
    View Code

    详细请参考:https://www.cnblogs.com/pyedu/p/10303283.html

  • 相关阅读:
    图的理论基础
    哈夫曼树(三)之 Java详解
    哈夫曼树(二)之 C++详解
    哈夫曼树(一)之 C语言详解
    基数排序
    桶排序
    归并排序
    堆排序
    选择排序
    希尔排序
  • 原文地址:https://www.cnblogs.com/Mixtea/p/10457608.html
Copyright © 2020-2023  润新知