zoukankan      html  css  js  c++  java
  • Python之旅的第2^4天(shelve、xml模块和re模块部分)

    实在是没想到今天的内容会这么精彩,特别是re模块,我激动了,这不就是数据抓取的基础吗?哈哈哈

    一、shelve模块

    import shelve
    # shelve模块,功能上类似于json和pickle,但是操作起来比较简单,是将传入数据转化为一个字典
    # 但是在写入过程中我们看不到字典的存在,同时不能跨语言进行传输
    
    # f = shelve.open(r'shelve_test1')    #此时会生成3个文件,但是你完全不用理会,因为你看不懂
    # f['stu1_info1'] = {'name':'alex','age':18}   #将传入的字典{'name':'alex','age':18} 变成一个v值,
    #                                              # 与我们写入的'stu1_info1'行程一个键值对,就是转换成为字典
    # f['stu1_info2'] = {'name':'zhoujielun','age':28}
    # f['shelve_test'] = {'k1':'v1'}
    # f.close()
    
    # print(f.get('stu1_info1')['name'])  #用f.get(k值)获取你要找到的字典,然后用字典内的k值得到对应的v
                                        #输出结果为:'alex'

    二、xml模块

    # 关于xml模块的引入
    import xml.etree.ElementTree as ET  #部分调用的模块由于名称太长,我们可以定义缩写
                                        #as后面跟随的内容就是缩写
    # xml当然就是用来解析xml文件的
    # 首先引入xml的文件内容,这里要明白xml中标签(tag)、属性(attrib)、标签数值(text)
    # 下面是xml文件内的内容,请对照进行操作
    # <data>
    #     <country name="Liechtenstein">
    #         <rank updated="yes">2</rank>
    #         <year updated="yes">2010</year>
    #         <gdppc>141100</gdppc>
    #         <neighbor direction="E" name="Austria" />
    #         <neighbor direction="W" name="Switzerland" />
    #     </country>
    #     <country name="Singapore">
    #         <rank updated="yes">5</rank>
    #         <year updated="yes">2013</year>
    #         <gdppc>59900</gdppc>
    #         <neighbor direction="N" name="Malaysia" />
    #     </country>
    #     <country name="Panama">
    #         <rank updated="yes">69</rank>
    #         <year updated="yes">2013</year>
    #         <gdppc>13600</gdppc>
    #         <neighbor direction="W" name="Costa Rica" />
    #         <neighbor direction="E" name="Colombia" />
    #     </country>
    # </data>
    
    # 以文件内容的第三行为例<rank updated="yes">2</rank>
    # 其中<rank></rank>  'rank'就是xml文件中的标签值
    # updated = "yes"  就是rank的属性
    # 两个括号中间的'2'就是他们的数值
    
    #ET.parse 打开一个xml文件,这里的parse的意思是解析,即为解析一个文件
    # tree = ET.parse('xml_lesson')
    #这时我们就将打开文件的句柄复制给了tree,这里用tree命名非常合适
    #xml文件机构非常像一棵树,树根<data>  第一次分叉<country>
    # <country>下面还会分出很多分支标签、对应的数值和属性
    
    # tree.getroot() 就是获得根节点的意思
    # root = tree.getroot()
    # print(root)      #输出的结果:<Element 'data' at 0x0000028F1BB4A318>
    #得到这样的结果就表示,root是一个对象,是可以被遍历的
    
    #我们可以尝试去打印root下一级的子标签
    # for i in root:
    #     print(i.tag)   #输出了data下面包含的三个country
    #我们再向下便利一层
        # for a in i:
        #     print(a.tag)   #输出rank、year、gdppc、neighbor、neighbor三次
        #                    #表示三个country下面的所有对应标签内容
    
    #.attrib 就是刚才介绍在第一个尖括号里面出现的等号两边的连起来的东西
    #<rank updated="yes">2</rank>  里面的updated="yes"就是属性
    # for i in root:
    #     print(i.attrib)   #输出{'name': 'Liechtenstein'}、{'name': 'Singapore'}、{'name': 'Panama'}
    #                       #分别是<data>下面三个country中对应的属性 name="Liechtenstein" 等
    #                       #最终表现形式是以字典的形式输出的
    # print(root.attrib)      #root 即<data>没有属性值,所以输出一个空的字典
    
    # .text 获取其中的值,<rank updated="yes">2</rank>当中的2
    # for child in root:
    #     print(child.tag, child.attrib)
    #     for i in child:
    #         print(i.tag, i.attrib, i.text)
    #
    # 输出结果是:
    # country {'name': 'Liechtenstein'}
    # rank {'updated': 'yes'} 2
    # year {'updated': 'yes'} 2010
    # gdppc {} 141100
    # neighbor {'direction': 'E', 'name': 'Austria'} None
    # neighbor {'direction': 'W', 'name': 'Switzerland'} None
    # country {'name': 'Singapore'}
    # rank {'updated': 'yes'} 5
    # year {'updated': 'yes'} 2013
    # gdppc {} 59900
    # neighbor {'direction': 'N', 'name': 'Malaysia'} None
    # country {'name': 'Panama'}
    # rank {'updated': 'yes'} 69
    # year {'updated': 'yes'} 2013
    # gdppc {} 13600
    # neighbor {'direction': 'W', 'name': 'Costa Rica'} None
    # neighbor {'direction': 'E', 'name': 'Colombia'} None
    
    #可以看出,没有返回值的时候返回None
    
    #.iter 指定遍历其中的某一个节点,比如'year'
    # 请记住iter方法是放在了root根目录下进行执行的
    # for node in root.iter('year'):
    #     print(node.tag, node.attrib, node.text)
    #输出结果:
    # year {'updated': 'yes'} 2010
    # year {'updated': 'yes'} 2013
    # year {'updated': 'yes'} 2013
    
    # 对其中year的值进行修改
    # tree = ET.parse('xml_lesson')
    # root = tree.getroot()
    
    # for node in root.iter('year'):
    #     new_year = int(node.text) + 1
    #     node.text = str(new_year)
    #     node.set('update','yes')
    # tree.write('xml_lesson')
    #此时对应的<year>部分的数值已经增加了1
    
    #.remove 删除某一节点的内容
    #.findall  感觉有点类似于iter,但是感觉只是用来找寻下一层的
    #.find     感觉有点类似于iter,
    # 要求是删除掉<rank>值大于50的<country>所有信息
    # for country in root.findall('country'):
    #     rank = int(country.find('rank').text)
    #     if rank > 50:
    #         root.remove(country)
    # tree.write('new_xml_lesson')
    #最终生成新文件,并删除了最后一个<country>
    
    #生成一个新的xml文件
    
    # new_xml = ET.Element('new_xml_test.xml')
    # name = ET.SubElement(new_xml , 'name' , attrib = {'xiaowang': 'alex'})
    # age = ET.SubElement(name , 'age' ,attrib = {'zhoujielun':'18'})
    # sex = ET.SubElement(name, "sex")
    # sex.text = '33'  #数值的写入方式很特别
    # name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
    # age = ET.SubElement(name2, "age")
    # age.text = '19'
    #
    # et = ET.ElementTree(new_xml)  #表示生成文档对象
    # et.write('test.xml',encoding = 'utf-8',xml_declaration = True)  #写入文件
    #
    # ET.dump(new_xml)   #打印生成的格式
    #以上是xml的全部内容

    三、re模块的元字符部分

    import re
    # re模块,即正则表达式,主要针对字符串进行相关处理,由c语言编制而成,运行效率很高
    # 是一个小型的高度专业的语言,主要用作模糊匹配
    # re模块包含的元字符有   .  ^  $  *  +  ?  {}  []  |  ()  
    # 先引入一个re模块的方法re.findall('查找规则','查找内容')
    # 输出一个列表,表示找到的内容
    
    # . 表示通配符,可以表示任何字符,一以对应
    # print(re.findall('a..x','adasalexdasdaayex'))
    #输出:['alex', 'ayex']
    
    # ^ 表示必须以尖角号后面的字符为开头
    # print(re.findall('^a..x','alexdadsaalex'))
    #输出:['alex']  此时只能显示在最开始出现的'alex'
    
    # $ 美元符,表示必须以美元符前面的字符为结尾
    # print(re.findall('a..x$','alexdadsaalex'))
    #输出:['alex']   此时输出的'alex'是字符串最末尾的alex
    
    # *  和  + 分表表示该字符串出现次数为:
    # * 表示(0,正无穷大)
    # + 表示(1,正无穷大)
    #同时他们都是贪婪匹配,以匹配到最多为结果
    # print(re.findall('alex*','aledsasfafa'))   #['ale']
    # print(re.findall('alex*','alexxxxxsadada'))   #['alexxxxx']
    #
    # print(re.findall('alex+','aledsasfafa'))    #[]
    # print(re.findall('alex+','alexxxxxsadada'))   #['alexxxxx']
    
    # ? 表示该字符匹配0或者1次
    # print(re.findall('alex?','aledsasfafa'))    #['ale']
    # print(re.findall('alex?','alexxxxxsadada'))   #['alex']
    
    # {} 大括号,可以设定出现次数的范围,如果只填写一个数字,则表示指定了出现次数
    # {0,正无穷} == *
    # {1,正无穷} == +
    # {0,1} == ?
    
    # [] 中括号是一个非常关键的符号,他表示其中任意一个与外面的匹配符合
    # 在[]中,除了- ^ 三个特殊符号外,里面的任何符号都是没有意义的
    # [] 中他们三个的意思分别是
    # - 表示范围
    # print(re.findall('x[a-z]','xdasdsaxdas'))   #['xd', 'xd']
    # print(re.findall('x[a-z]*','xdasdsaxdas'))   #['xdasdsaxdas']  之所以这样是因为*是贪婪匹配,有多少拿多少
    # print(re.findall('[a-z]*x','xdasdsaxdas'))   #['xdasdsax']
    # print(re.findall('^[a-z]x','xdasdsaxdas'))   #[]
    
    # ^ 表示非这些字符
    # print(re.findall('[^a-z]x','9xdasdsa0xdas'))   #['9x', '0x']
    
    #  转义符,好像括号内外都一样
    # 首先是能让没意义的有意义
    # d  匹配任何十进制数;它相当于类 [0-9]。
    # D 匹配任何非数字字符;它相当于类 [^0-9]。
    # s  匹配任何空白字符;它相当于类 [ 	
    
    fv]。
    # S 匹配任何非空白字符;它相当于类 [^ 	
    
    fv]。
    # w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
    # W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
    #   匹配一个特殊字符边界,比如空格 ,&,#等
    
    # 能让有意义的没有意义
    # 给了一个5+(9*8-5*(3-1))
    # 取出3-1部分的内容
    # a = '5+(9*8-5*(3-1))'
    # b = re.findall('([^()]*)',a)
    # print(b)   #此时可得到['(3-1)']
    
    # * 和 + 后面增加上?
    # 会由原来的贪婪匹配,转换成为惰性匹配
    # print(re.findall('alex*','alexxxxxsadada'))   #['alexxxxx']
    # print(re.findall('alex*?','alexxxxxsadada'))   #['ale']
    #
    # print(re.findall('alex+','alexxxxxsadada'))   #['alexxxxx']
    # print(re.findall('alex+?','alexxxxxsadada'))   #['alex']
    
    #关于re模块真非常神奇
    #比如可以以身份证号为参考,获取以612开头的,并且是1990年之后出生的人的身份证号码
    # 使用正则表达式  ^612...1990+*
    
    # 比如获取'das12dadsa123asd45'当中所有的数字d+即可实现

    就是这些了,没想到今天的三个小时这么精彩,非常的激动,期待明天re的新发现哦

  • 相关阅读:
    【3】hexo+github搭建个人博客的主题配置
    【2】hexo+github搭建个人博客的简单使用
    每日思考(2020/05/06)
    每日思考(2020/05/05)
    每日思考(2020/03/27)
    文件和异常
    每日思考(2020/03/24)
    图形用户界面和游戏开发
    每日思考(2020/03/19)
    面向对象进阶
  • 原文地址:https://www.cnblogs.com/xiaoyaotx/p/12452860.html
Copyright © 2011-2022 走看看