字符串要点,python之常用模块

作者:云顶最新线路检测

正文主要内容

  种类类型分类:

    (1卡塔尔国容器系列、扁平系列

    (2卡塔尔可变系列、不可变种类

  列表推导式

  生成器表达式

  元组拆包

  切片

  排序(list.sort方法和sorted函数)

  bisect

 

python高级——目录

  文中代码均位居github上:https://github.com/ampeeg/cnblogs/tree/master/python高级

 

一、爬虫之requests

目录:

一、字符串

源代码是这样:

队列类型分类

 

   所谓体系,即成分有序排列,python标准库用C达成了拉长的队列类型,依据系列中是还是不是可寄存不一致档案的次序的数据分为"容器系列"和"扁平种类"。

  容器种类能够存放统统类型的多少,而扁平系列只好存放意气风发种档案的次序     

    容器序列:list、tuple、collections.deque   
    扁平序列:str、bytes、bytearray、memoryview、array.array
  
  按照是否能修改的标准序列又可分为"可变序列"和"不可变序列":      
    可变序列:list、bytearrary、array.arrary、collections.deque和memoryview   
    不可变序列:tuple、str和bytes

  由于可变序列继承自不可变序列,所以可变序列继承的方法也较多,下面看看它们包含的方法:   
方法名 不可变序列 可变序列
__contains__  有 有 
__iter__  有  有 
 __len__  有  有 
__getitem__   有  有 
__reversed__   有  有 
index   有  有 
count   有  有 
__setitem__    有 
__delitem__   有 
insert   有 
append   有 
reverse   有 
extend   有 
pop   有 
remove   有 
__iadd__    有 

  

  大家以tuple和list类型为例,比较源代码中的方法,能够显然开采list的措施多于tuple:

  

图片 1

 

    a、介绍:行使requests能够依样画葫芦浏览器的倡议,比起在此以前使用的urllib,requests模块的api特别简便易行(本质正是包装了urllib3卡塔 尔(英语:State of Qatar)

 1.time和datetime模块

  •   透过string定义几个字符串,只怕经过String类来创造对象。

    •   通过new String() 创设有刹那间二种构造函数(从元数据卡塔尔国,以此顺序创造string;
    • 图片 2图片 3

      //
              // 摘要:
              //     将 System.String 类的新实例初始化为由 Unicode 字符数组指示的值。
              //
              // 参数:
              //   value:
              //     Unicode 字符的数组。
              [SecuritySafeCritical]
              public String(char[] value);
              //
              // 摘要:
              //     将 System.String 类的新实例初始化为由指向 8 位有符号整数数组的指针指示的值。
              //
              // 参数:
              //   value:
              //     一个指针,指向以 null 结尾的 8 位带符号整数数组。
              //
              // 异常:
              //   T:System.ArgumentNullException:
              //     value 为 null。
              //
              //   T:System.ArgumentException:
              //     如果 value 是用 ANSI 编码的,则不能使用 value 初始化 System.String 的新实例。
              //
              //   T:System.ArgumentOutOfRangeException:
              //     要初始化的新字符串的长度过大,无法分配,该长度由 value 的 null 终止字符决定。
              //
              //   T:System.AccessViolationException:
              //     value 指定的地址无效。
              [CLSCompliant(false)]
              [SecurityCritical]
              public String(sbyte* value);
              //
              // 摘要:
              //     将 System.String 类的新实例初始化为由指向 Unicode 字符数组的指定指针指示的值。
              //
              // 参数:
              //   value:
              //     指向以 null 终止的 Unicode 字符数组的指针。
              //
              // 异常:
              //   T:System.ArgumentOutOfRangeException:
              //     当前进程并不是对所有编址字符都有读取权限。
              //
              //   T:System.ArgumentException:
              //     value 指定了包含无效 Unicode 字符的数组,或者 value 指定了小于 64000 的地址。
              [CLSCompliant(false)]
              [SecurityCritical]
              public String(char* value);
              //
              // 摘要:
              //     将 System.String 类的新实例初始化为由重复指定次数的指定 Unicode 字符指示的值。
              //
              // 参数:
              //   c:
              //     一个 Unicode 字符。
              //
              //   count:
              //     c 出现的次数。
              //
              // 异常:
              //   T:System.ArgumentOutOfRangeException:
              //     count 小于零。
              [SecuritySafeCritical]
              public String(char c, int count);
              //
              // 摘要:
              //     将 System.String 类的新实例初始化为由 Unicode 字符数组、该数组内的起始字符位置和一个长度指示的值。
              //
              // 参数:
              //   value:
              //     Unicode 字符的数组。
              //
              //   startIndex:
              //     value 内的起始位置。
              //
              //   length:
              //     要使用的 value 内的字符数。
              //
              // 异常:
              //   T:System.ArgumentNullException:
              //     value 为 null。
              //
              //   T:System.ArgumentOutOfRangeException:
              //     startIndex 或 length 小于零。- 或 -startIndex 和 length 之和大于 value 中的元素数。
              [SecuritySafeCritical]
              public String(char[] value, int startIndex, int length);
              //
              // 摘要:
              //     将 System.String 类的新实例初始化为由指向 8 位有符号整数数组的指定指针、该数组内的起始位置和一个长度指示的值。
              //
              // 参数:
              //   value:
              //     指向 8 位带符号整数数组的指针。
              //
              //   startIndex:
              //     value 内的起始位置。
              //
              //   length:
              //     要使用的 value 内的字符数。
              //
              // 异常:
              //   T:System.ArgumentNullException:
              //     value 为 null。
              //
              //   T:System.ArgumentOutOfRangeException:
              //     startIndex 或 length 小于零。- 或 -由 value + startIndex 指定的地址相对于当前平台来说太大;即,地址计算溢出。-
              //     或 -要初始化的新字符串的长度太大,无法分配。
              //
              //   T:System.ArgumentException:
              //     由 value + startIndex 指定的地址小于 64K。- 或 -如果 value 是用 ANSI 编码的,则不能使用 value 初始化 System.String
              //     的新实例。
              //
              //   T:System.AccessViolationException:
              //     value、startIndex 和 length 共同指定的地址无效。
              [CLSCompliant(false)]
              [SecurityCritical]
              public String(sbyte* value, int startIndex, int length);
              //
              // 摘要:
              //     将 System.String 类的新实例初始化为由指向 Unicode 字符数组的指定指针、该数组内的起始字符位置和一个长度指示的值。
              //
              // 参数:
              //   value:
              //     指向 Unicode 字符数组的指针。
              //
              //   startIndex:
              //     value 内的起始位置。
              //
              //   length:
              //     要使用的 value 内的字符数。
              //
              // 异常:
              //   T:System.ArgumentOutOfRangeException:
              //     startIndex 或 length 小于零,value + startIndex 引起指针溢出,或者当前进程并不是对所有编址字符都有读取权限。
              //
              //   T:System.ArgumentException:
              //     value 指定了包含无效 Unicode 字符的数组,或者 value + startIndex 指定了小于 64000 的地址。
              [CLSCompliant(false)]
              [SecurityCritical]
              public String(char* value, int startIndex, int length);
              //
              // 摘要:
              //     将 System.String 类的新实例初始化为由指向 8 位有符号整数数组的指定指针、该数组内的起始位置、长度以及 System.Text.Encoding
              //     对象指示的值。
              //
              // 参数:
              //   value:
              //     指向 8 位带符号整数数组的指针。
              //
              //   startIndex:
              //     value 内的起始位置。
              //
              //   length:
              //     要使用的 value 内的字符数。
              //
              //   enc:
              //     一个对象,用于指定如何对 value 所引用的数组进行编码。如果 enc 为 null,则假定以 ANSI 编码。
              //
              // 异常:
              //   T:System.ArgumentNullException:
              //     value 为 null。
              //
              //   T:System.ArgumentOutOfRangeException:
              //     startIndex 或 length 小于零。- 或 -由 value + startIndex 指定的地址相对于当前平台来说太大;即,地址计算溢出。-
              //     或 -要初始化的新字符串的长度太大,无法分配。
              //
              //   T:System.ArgumentException:
              //     由 value + startIndex 指定的地址小于 64K。- 或 -未能使用 value 初始化 System.String 的新实例,假定 value
              //     按照 enc 的指定进行编码。
              //
              //   T:System.AccessViolationException:
              //     value、startIndex 和 length 共同指定的地址无效。
              [CLSCompliant(false)]
              [SecurityCritical]
              public String(sbyte* value, int startIndex, int length, Encoding enc);
      

      View Code

    • 图片 4图片 5

      char []cstr = { 'a','b','c','d','e'};
                  char cstr1 = 'a';
                  sbyte se = 113;
      
                  String a = new String(cstr);
                  //
      
                  String b = new String(&cstr1);
      
                  String c = new String(&se);
      
                  String d = new String('d',2);
      
                  String e = new String(cstr,2,3);
      
                  String f = new String(&se,0,1);
                  Console.WriteLine((int)Convert.ToChar(f)+"n");//113
                  String g = new String(&se,0,1,Encoding.UTF8);
                  Console.WriteLine("a:{0}nb:{1}nc:{2}nd:{3}ne:{4}nf:{5}ng:{6}",a,b,c,d,e,f,g);
      

      View Code

  •   string是C#基元类型(primitive),string简单的话就是编写翻译器直接扶助的数据类型。运算符(== 和 !=)是为着比较 string 对象的值, 实际不是相比援用

    • string a = "1234";
                  string b = "123";
                  b += "4";
                  Console.WriteLine(a == b);//比较值
                  Console.WriteLine((object)a == (object)b);//比较引用()
      
       
  •   string连接操作 (+=卡塔尔

    •   瑕疵很明朗, 操作频仍的话非常荒疏内部存款和储蓄器空间的
    •   使用StringBuilder类对象方法append代替+=, 质量还会有所升高
  •   null," "和string.Empty的区别
    •   null代表不引用任何变量的空引用的值,null是援用变量的暗中认可值, 值类型变量不恐怕利用
    •   ""表示分配二个内部存款和储蓄器为空的囤积空间。
    •   string.Empty表示空字符串,並且不分配内部存款和储蓄器空间。
  •   判定字符串为空 的俩种艺术
    •   x.length==0 // 不能判定为null的字符串
    •   string.IsNullOrEmpty(x)   

s=b'^SdVkT#S ]`Y\!^)x8fx80ism'
key=''
for i in s:
     i=ord(i)-16
     key+=chr(i^32)
print (key)

列表推导式

# 列表推导式生成的是列表,会占用系统内存
# 基本语法

list_1 = [x for x in range(1, 20)]
list_2 = [x ** 2 for x in range(1, 20)]


print(list_1)  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(list_2)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]

# 笛卡尔积型的列表推导式
list_3 = [(x, y) for x in range(1, 3)        # 1,2
                 for y in range(7, 10)]      # 7、8、9

                                             # 该表达式会先将1分别和7、8、9组合,然后再拿2和7、8、9组合,共6对
print(list_3)  # [(1, 7), (1, 8), (1, 9), (2, 7), (2, 8), (2, 9)]


list_4 = [x+y for x in range(1, 3)
                 for y in range(7, 10)]

print(list_4)   # [8, 9, 10, 9, 10, 11]

# 还可以添加if语句
l = [1, 3, 4, 33, 45, 36, 422, 34, 67, 23, -4, -7, -345, 46, -6, -45, 32, -8, -4, 67, -4]

list_5 = [x for x in l if x > 0]   # 只取出大于0的生成列表
print(list_5)                      # [1, 3, 4, 33, 45, 36, 422, 34, 67, 23, 46, 32, 67]

 

    b、注意:requests发送央浼是将网页内容下载来以后,并不会推行js代码,那亟需大家本身剖析目的站点然后发起新的requests恳求

 2. random模块

运作后边世了难题:ord() expected string of length 1, but int found

生成器表明式

# 虽然列表推导式可以用来初始化元组、数组或其他序列类型,但是列表推导式会直接生成列表,占用内存
# 而生成器遵守了迭代器协议,可以逐个产出元素,而不是先建立一个完整的列表


# 生成器表达式直接将推导式的方括号换成圆括号即可

g = (x for x in range(1, 10000))

print(g)    # <generator object <genexpr> at 0x105c0efc0> :生成器对象


from collections import Iterable, Iterator

if isinstance(g, Iterable):
    print("iterable")          # 输出iterable: 说明生成器g是可迭代的

if isinstance(g, Iterator):
    print("iterator")          # 输出iterator:说明生成器g是迭代器

 

  上边大家来相比一下列表推导式和生成器的频率

# 比较列表推导式和生成器
import time

start_time = time.time()
l = [x for x in range(1000000)]
print(time.time() - start_time)     # 0.1361069679260254

start_time = time.time()
g = (x for x in range(1000000))
print(time.time() - start_time)     # 1.1205673217773438e-05

# 可见,生成器远快于推导式

 

    c、安装:pip3 install requests

3. OS模块(是与操作系统交互的一个接口卡塔尔

故此现身那个主题素材,是在字符串转换进程中冒出了叁个小错误,在一美妙绝伦百度和谷歌(Google卡塔尔国后,发掘概念照旧很迷糊,但是在曙光大佬的解答后,精通了怎么管理,便是在s后加””,运营后意识完美消除

元组拆包

# 我们经常这样给两个变量同时赋值
a, b = 1, 2
print(a, b)     # 1 2

# 还可以这样
a, b = [1, 2]
print(a, b)     # 1 2

# 也可以这样
a, b = (1, 2)
print(a, b)     # 1 2

# 甚至可以这样
a, b = "ab"
print(a, b)     # a b

'''
    像以上这样连续的赋值方式,右边可以使用逗号隔开;也可以是序列。

    当拆包赋值的是序列时,python解释器会先找该序列中的__iter__方法,如果该方法不存在,则寻找__getitem__方法。

    接下来说其他用法
'''

# 赋值后优雅地交换两个变量
a, b = (1, 2)
a, b = b, a
print(a, b)        # 2 1

# 使用*号来处理多余的数据
a, b, *s = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a, b, s)        # 1 2 [3, 4, 5, 6, 7, 8, 9]
                      # 这样从第三个元素开始的所有值都赋给了s

a, b, *s = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(a, b, s)        # 1 2 [3, 4, 5, 6, 7, 8, 9]
                      # 注意,本来是元组,赋之后的s变成了列表. 如果s为空的话也会返回空列表

*s, a, b = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(s, a, b)        # [1, 2, 3, 4, 5, 6, 7] 8 9
                      # *s也可以放在前面

a, *s, b = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(a, s, b)        # 1 [2, 3, 4, 5, 6, 7, 8] 9
                      # *s也可以放在中间

# 嵌套元组拆包
a, b, (c, d) = (1, 2, (3, 4))
print(a, b, c, d)     # 1 2 3 4
                      # 只要按照右边的形式就可赋值

a, b, *c = (1, 2, (3, 4))
print(a, b, c)     # 1 2 [(3, 4)]

 

图片 6图片 7

 1 ################################
 2 #
 3 # 以下的例子用以说明拆包赋值时,解释器会按照__iter__、__getitem__的顺序调用类中的方法
 4 #
 5 ################################
 6 class Foo:
 7     def __init__(self, s):
 8         self.s = s
 9 
10     def __iter__(self):
11         print("iter")
12         return iter(self.s)
13 
14     def __getitem__(self, item):
15         return self.s[item]
16 
17 if __name__ == "__main__":
18     foo = Foo("sdfafasfasf")
19     a, b, *s = foo
20     print(a, b)

拆包赋值的里边落到实处

 

  以前大家透过源码已经相比过list和tuple类中的方法和性质,上边列出《通畅的python》收拾的列表和元组的不二等秘书籍及质量:

表 列表或元组的法子和总体性

  列  表 元  组
s.__add__(s2)
· ·
s.__iadd__(s2) ·  
s.append(e) ·  
s.clear() ·  
s.__contains__(e) · ·
s.copy() ·  
s.count(e) · ·
s.__delitem__(p) ·  
s.extend(it) ·  
s.__getitem__(p) · ·
s.__getnewargs__()   ·
s.index(e) · ·
x.insert(p,e) ·  
s.__iter__() · ·
s.__len__() · ·
s.__mul__(n) · ·
s.__imul__(n) ·  
s.__rmul__(n) · ·
s.pop([p]) ·  
s.remove(e) ·  
s.reverse() ·  
s.__reversed__() ·  
s.__setitem__(p,e) ·  
s.sort([key], [reverse]) ·  

   

  表达:以上元节组中不加黑点的不意味绝对不能够这么使用,只是其成效和列表分化(表达里面有分解卡塔尔。比如五个元组a和b实行增量赋值a+=b也是足以的,只是那几个操作不是就地拼接,而是生成了新的元组。

    d、种种诉求形式,常用的是requests.get()和requets.post()

4. sys模块(sys模块是与python解释器交互作用的一个接口卡塔尔

切片

'''
    在python中,内置的序列类型都支持切片操作,切片操作的用法十分简单:
    list[start: stop: step]    , 其中不包括区间范围内最后一个(事实上这是python的风格,一般不包含区间最后一个)
    python里面能使用切片操作是因为实现了__getitem__方法,切片时会给该方法传递slice(start: stop: step) 参数
'''

if __name__ == "__main__":
    # 基本操作
    l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(l[2:])     # 第3个元素到最后   :[3, 4, 5, 6, 7, 8, 9]
    print(l[:3])     # 第一个元素到最后   :[1, 2, 3]

    s = "abcdefghijklmn"
    print(s[2::2])   # 从第三个字母开始,隔一个字母取一个 : cegikm
    print(s[::-1])   # 倒序排列 : nmlkjihgfedcba
    print(s[::-2])   # 倒序隔一个取一个 nljhfdb
    print(s[-2::-2]) # 倒序第二隔开始,隔一个取一个

    # 利用切片赋值
    l[2:5] = [20, 30]
    print(l)         # [1, 2, 20, 30, 6, 7, 8, 9]
    try:
        l[2:5] = 40      # 报错:TypeError: can only assign an iterable
                         # 利用切片赋值时传入的必须是可迭代对象
    except Exception as e:
        print(e)         # can only assign an iterable
    l[2:5] = (40,)
    print(l)             # [1, 2, 40, 7, 8, 9]
    l[2:3] = "sajfljls"  # 字符串属于序列,也可以迭代
    print(l)             # [1, 2, 's', 'a', 'j', 'f', 'l', 'j', 'l', 's', 7, 8, 9]

 

二、基于get请求

5.体系化模块 

排序(list.sort方法和sorted函数)

'''
    list.sort方法和sorted内置函数都有排序的功能,区别如下
        list.sort是就地排序列表,不会把原列表复制一份。该方法返回None,以提醒不会新建一个列表。
        sorted函数会新建一个列表作为返回值,这个函数可以接受任何可迭代对象,甚至包括不可变序列或生成器,最后返回的总是列表。

    list.sort和sorted都有两个参数:
        reverse:默认为False,设定为True以降序排列
        key:一个只有一个参数的函数,这个函数会作用于序列的每一个元素上,然后以该函数的结果作为关键字排序

'''

if __name__ == "__main__":
    # 1、list.sort就地排序,而sorted返回列表
    l = [x for x in range(10, 0, -1)]      # 初始化一个列表:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    print(id(l), l)    # l最初的地址:4536449800 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    l.sort()
    print(id(l), l)    # 排序后的地址:4536449800 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
                       # l前后的的地址没变,说明是就地排序


    l = [x for x in range(10, 0, -1)]  # 初始化一个列表:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    print(id(l), l)  # l最初的地址:4415318984 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    l = sorted(l)
    print(id(l), l)  # 排序后的地址:4415318792 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    # 2、sorted可以接受任何可迭代对象
    l = (x for x in range(10, 0, -1))
    print(type(l))        # 迭代器 <class 'generator'>
    print(sorted(l))      # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    s = "qwertyuiopasdfghjklzxcvbnm"   # 字符串序列
    print(sorted(s))      # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

    s = (1, 3, 2, 456, 345, 12, 2, 5, 78, 34)   # 不可变元组
    print(sorted(s))      # [1, 2, 2, 3, 5, 12, 34, 78, 345, 456]

    # 3、reverse参数
    s = "qwertyuiopasdfghjklzxcvbnm"
    print(sorted(s, reverse=True))   # ['z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']


    # 4、key参数
    s = "QwERTYuioPaSdfGHjKLzXcvbnm"
    print(sorted(s))    # ['E', 'G', 'H', 'K', 'L', 'P', 'Q', 'R', 'S', 'T', 'X', 'Y', 'a', 'b', 'c', 'd', 'f', 'i', 'j', 'm', 'n', 'o', 'u', 'v', 'w', 'z']
    print(sorted(s, key=str.lower))   # 忽略大小写 ['a', 'b', 'c', 'd', 'E', 'f', 'G', 'H', 'i', 'j', 'K', 'L', 'm', 'n', 'o', 'P', 'Q', 'R', 'S', 'T', 'u', 'v', 'w', 'X', 'Y', 'z']
    print(sorted(s, key=str.upper))   # 也是忽略大小写
##########################
#
#  以下自定义一个类也可使用sorted函数
#
##########################

class Obj:
    def __init__(self):
        self.s = [x for x in range(10, 0, -1)]

    def __getitem__(self, item):
        print("getitem")
        return self.s[item]

    def __repr__(self):
        return str(self.s)

    def __iter__(self):
        return iter(self.s)

obj = Obj()
print(obj)           # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

# 添加getitem后可以使用sorted函数  (实验时请注视掉getitem方法)
print(sorted(obj))   #  打印10次getitem   , [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 添加iter方法
print(sorted(obj))   # 此时解释器会先调用iter方法,不会再使用getitem方法
                     # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
使自定义类也可使用sorted函数调用

 

    a、基本央浼

6.hashlib模块

bisect

'''
    bisect模块主要用来管理有顺序的序列
    bisect模块包含的主要函数是bisect和insort,两个函数都使用二叉树方法搜索
    1、bisect(haystack, needle)
        haystack必须是一个有序的序列,该函数搜索needle在haystack中的位置,该位置使得将needle插入后haystack仍然升序
        查找到位置后可用haystack.insert()插入

    2、insort(seq, item)
        把item插入到seq中,并能保持seq的升序

'''

#  本人认为《流畅的python》中的对该模块介绍的例子比较经典,故引用之

# 1、关于bisect.bisect的示例
import bisect
import sys

HAYSTACK = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
NEEDLES = [0, 1, 2, 5, 8, 10, 22, 23, 29, 30, 31]

ROW_FMT = '{0:2d} @ {1:2d}    {2}{0:<2d}'

def demo(bisect_fn):
    for needle in reversed(NEEDLES):
        position = bisect_fn(HAYSTACK, needle)
        offset = position * '  |'
        print(ROW_FMT.format(needle, position, offset))


if __name__ == '__main__':

    if sys.argv[-1] == 'left':
        bisect_fn = bisect.bisect_left
    else:
        bisect_fn = bisect.bisect

    print('DEMO:', bisect_fn.__name__)
    print('haystack ->', ' '.join('%2d' % n for n in HAYSTACK))
    demo(bisect_fn)


    '''   输出如下
    DEMO: bisect
    haystack ->  1  4  5  6  8 12 15 20 21 23 23 26 29 30
    31 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |31
    30 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |30
    29 @ 13      |  |  |  |  |  |  |  |  |  |  |  |  |29
    23 @ 11      |  |  |  |  |  |  |  |  |  |  |23
    22 @  9      |  |  |  |  |  |  |  |  |22
    10 @  5      |  |  |  |  |10
     8 @  5      |  |  |  |  |8 
     5 @  3      |  |  |5 
     2 @  1      |2 
     1 @  1      |1 
     0 @  0    0 
    '''
# 另,bisect.bisect函数有两个可选参数——lo和hi来缩小搜索范围,lo的默认值是0,hi的默认值是序列的长度
# 再另,bisect.bisect函数其实是bisect_right函数的别名,还有一个bisect_left,插入位置如果有相等的元素时,插入元素会放在它相等的
#      元素后面,后者会放在前面


# 根据分数,查到等级

def grade(score, breakpoints=[60, 70, 80, 90], grades = 'FDCBA'):
    i = bisect.bisect(breakpoints, score)     # 这里的bisect.bisect实际上使用的是bisect_right
    return grades[i]

print([grade(score) for score in [33, 55, 90, 87, 65, 78, 34, 60, 100]])

# 2、关于bisect.insort函数

import bisect
import random

SIZE = 7

random.seed(1729)

my_list = []
for i in range(SIZE):
    new_item = random.randrange(SIZE*2)
    bisect.insort(my_list, new_item)
    print('%2d ->' % new_item, my_list)

    '''输出:
    10 -> [10]
     0 -> [0, 10]
     6 -> [0, 6, 10]
     8 -> [0, 6, 8, 10]
     7 -> [0, 6, 7, 8, 10]
     2 -> [0, 2, 6, 7, 8, 10]
    10 -> [0, 2, 6, 7, 8, 10, 10]
    '''

# 另,insort函数也有insort_left,背后使用的是bisect_left

 

import requests
response=requests.get('http://dig.chouti.com/')
print(response.text)

7.configparser

python高端类别小说目录

python高级——目录

 

 

    b、带参数get请求-----》》params

8.logging  (记录日志的模块卡塔尔国

    c、带参数get请求-----》》headers

9.collections模块(使用counter进行记数计算卡塔尔国

#通常我们在发送请求时都需要带上请求头,请求头是将自身伪装成浏览器的关键,常见的有用的请求头如下
Host
Referer #大型网站通常都会根据该参数判断请求的来源
User-Agent #客户端
Cookie #Cookie信息虽然包含在请求头里,但requests模块有单独的参数来处理他,headers={}内就不要放它了

模块:

  Computer程序的支付进度中,随着程序代码越写越来越多,在三个文书里代码就能够特别长,更加的不便于保险。为了编写制定可保险的代码,大家把数不胜数函数分组,分别放置不一致的文本里,这样,每一种文件富含的代码就绝对非常少,非常多编制程序语言都使用这种组织代码的情势。在 Python 中,一个.py 文件就叫做三个模块(Module卡塔尔。

模块分类:

  内置模块  python安装时自带的

  扩展模块  外人写好的,安装之后能够直接使用

        itchat模块(和Wechat相关卡塔尔国, beautifulsoap(爬虫模块卡塔尔国, selenium(网页自动化测量试验工具卡塔 尔(英语:State of Qatar)

        django tornado(框架)

  自定义模块 本身写的模块 

     d、带参数get请求-----》》cookies

应用模块好处:

  提升了代码的可维护性。

  当二个模块编写实现,就能够被另内地方引用。

  使用模块可以制止函数名和变量名冲突。

三、基于post请求

 1.time和datetime模块

time模块

python中,常常由以下三种办法来代表时间:

  • 时刻戳(timestamp):常常来讲,时间戳表示的是从一九七零年四月1日00:00:00最先按秒总结的偏移,运行“type(time.time())”,再次回到的是float类型。
  • 格式化的岁月字符串(Format String):如‘2018-4-24'
  • 结构化的时刻(struct_time):元祖格局。struct_time元组共有9个要素共七个成分:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)

    import time
    # 时间戳:     
    print(time.time())     # 1520503969.847386
    # 字符串格式化时间(两种结果一样):
    print(time.strftime('%x,%X'))   # 04/24/18,16:09:53
    print(time.strftime('%c'))   # Tue Apr 24 16:11:12 2018
    print(time.strftime('%Y-%M-%d,%H:%M:%S'))   # 2018-14-24,16:14:08
    print(time.strftime('%Y-%m-%d %X'))    # 2018-03-08 18:12:49
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    # 结构化时间:   
    print(time.localtime())   # 本地时区的struct_time
    print(time.gmtime())     # UTC时区的struct_time
    

     

   此中计算机认识的时日只可以是'时间戳'格式,而程序员可管理的恐怕说人类能看懂的日子有: '格式化的日子字符串','结构化的光阴' 

三种时光格式之间的转变:

图片 8  

现实用法:

import time
# 时间戳转化为结构化时间
# time.gmtime(时间戳)     # UTC时间
# time.localtime(时间戳)  # 当地时间
ret = time.localtime(2000000000)
print(ret)
# time.struct_time(tm_year=2033, tm_mon=5, tm_mday=18, tm_hour=11, tm_min=33, tm_sec=20, tm_wday=2, tm_yday=138, tm_isdst=0)

# 结构化时间转化为格式化时间
print(time.strftime('%Y-%m-%d %H:%M:%S', ret))
# 2033-05-18 11:33:20

# 把一个结构化时间转化为格式化时间
print(time.strftime("%Y-%m-%d %X", time.localtime()))
# 把一个格式化时间字符串转化为struct_time
print(time.strptime('2018-04-24 17:37:06', '%Y-%m-%d %X'))

 

 图片 9

# 结构化时间 --> %a %b %d %H:%M:%S %Y串

# ctime,把一个时间戳转化为time.asctime()的形式
# 如果参数未给或者为None的时候,将会默认time.time()为参数
a = time.ctime(2000000000)
print(a)   # Wed May 18 11:33:20 2033
print(time.ctime(time.time()))
# Tue Apr 24 17:41:56 2018

# asctime,把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。
# 如果没有参数,则默认将time.localtime()作为参数传入。
print(time.asctime())
# Tue Apr 24 17:41:56 2018

python中时间日期格式化符号:

 1 %y 两位数的年份表示(00-99)
 2 %Y 四位数的年份表示(000-9999)
 3 %m 月份(01-12)
 4 %d 月内中的一天(0-31)
 5 %H 24小时制小时数(0-23)
 6 %I 12小时制小时数(01-12)
 7 %M 分钟数(00=59)
 8 %S 秒(00-59)
 9 %a 本地简化星期名称
10 %A 本地完整星期名称
11 %b 本地简化的月份名称
12 %B 本地完整的月份名称
13 %c 本地相应的日期表示和时间表示
14 %j 年内的一天(001-366)
15 %p 本地A.M.或P.M.的等价符
16 %U 一年中的星期数(00-53)星期天为星期的开始
17 %w 星期(0-6),星期天为星期的开始
18 %W 一年中的星期数(00-53)星期一为星期的开始
19 %x 本地相应的日期表示
20 %X 本地相应的时间表示
21 %Z 当前时区的名称

datetime模块:

import datetime

print(datetime.datetime.now())    # 2018-03-08 21:04:15.544213     

# y-m-d h:M:S       2018-04-24 17:00:00
# 计算从当下光阴起头 比起y-m-d h:M:S过去了多少年 多少月 多少天 多少h,多少m,多少s

图片 10图片 11

import time
def pass_time(times):
    pass_time = time.strptime(times, '%Y-%m-%d %X')  # 结构化时间
    pass_time_stamp = time.mktime(pass_time)   # 时间戳
    time_stamp = time.time()-pass_time_stamp  # 已经过去的时间戳
    pass_times = time.localtime(time_stamp)   # 结构化时间
    now = zip(tuple(pass_times),tuple(time.localtime(0)))
    now1 = [(i[0]-i[1]) for i in now]  # 数字型列表,对应年,月---
    return '从当前时间开始,距离%s过去了%s年%s月%s日%s时%s分%s秒' %(times,now1[0],now1[1],now1[2],now1[3],now1[4],now1[5])

print(pass_time('2018-04-24 17:00:00'))

View Code

     a、介绍

2. random模块

 1 import random
 2 # ----------------------------
 3 # 1.随机小数,发红包可用
 4 print(random.random()) #0到1之间的随机小数
 5 print(random.uniform(1,3))  #大于1且小于3的随机小数
 6 
 7 # ----------------------------
 8 # 2.随机整数,验证码可用
 9 print(random.randint(1,5)) #大于1且小于等于5之间的整数
10 print(random.randrange(1,10,2))  #大于等于1且小于3之间的整数(且是所有的奇数)
11 
12 # ----------------------------
13 # 3.随机选择一个返回,抽奖
14 print(random.choice([1,'23',[4,5]]))
15 # ----------------------------
16 # 4.随机选择返回多个,一次抽取多个
17 print(random.sample([1,'23',[4,5]],2))  #列表元素任意两个组合输出,后缀为输出个数
18 # ----------------------------
19 
20 
21 # ----------------------------
22 # 5.打乱列表顺序,洗牌
23 item=[1,5,2,3,4]
24 random.shuffle(item)  #打乱次序
25 print(item)

采取大肆数随机生成6位验证码:

图片 12图片 13

import random
def ver_code(num):
    strs = ''
    lis1 = [chr(i) for i in range(65, 91)]
    lis2 = [str(i) for i in range(10)]
    ver1 = random.sample(lis1+lis2,num)
    for i in ver1:
        strs += i
    return strs

print(ver_code(6))

View Code

图片 14图片 15

def id_code(num):  # num 字母在每一位被取到的概率相同
    ret = ''
    for i in range(num):
        number = str(random.randint(0,9))
        alph_num = random.randint(97,122)   # A65 a97 +25
        alph_num2 = random.randint(65,90)   # A65 a97 +25
        alph = chr(alph_num)
        alph2 = chr(alph_num2)
        choice = random.choice([alph,alph2])
        choice = random.choice([number,choice])
        ret += choice
    return ret
print(id_code(6))

View Code

动用自由数完成三个发红包的编制程序

图片 16图片 17

import random
inp_money = float(input('红包金额:'))
inp_count = int(input('红包个数:'))
def red_packet(money, count):
    li = []
    money = int(money*100)
    money_site = random.sample(range(1, money), count-1)
    money_site.extend([0, money])
    money_site = sorted(money_site)
    for i in range(count):
        li.append(round((money_site[i+1]-money_site[i])*0.01, 2))
    return li
    # 上面的定义li列表、for循环以及return 可以简写成下面一行。
    # return [round((sorted(money_site)[i + 1] - sorted(money_site)[i]) * 0.01, 2) for i in range(count)]
ret = red_packet(inp_money, inp_count)
print(ret)

View Code

应用随便数随机生成4位验证码,并带模糊效果

from PIL import Image, ImageDraw, ImageFont, ImageFilter

import random

# 随机字母:
def rndChar():
    return chr(random.randint(48, 57))

# 随机颜色1:
def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))

# 随机颜色2:
def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

# 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 创建Font对象:
font = ImageFont.truetype('ariblk.ttf', 40)
# 创建Draw对象:
draw = ImageDraw.Draw(image)
# 填充每个像素:
for x in range(width):
    for y in range(height):
        draw.point((x, y), fill=rndColor())
# 输出文字:
for t in range(4):
    draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')
#GET请求
HTTP默认的请求方法就是GET
     * 没有请求体
     * 数据必须在1K之内!
     * GET请求数据会暴露在浏览器的地址栏中

GET请求常用的操作:
       1. 在浏览器的地址栏中直接给出URL,那么就一定是GET请求
       2. 点击页面上的超链接也一定是GET请求
       3. 提交表单时,表单默认使用GET请求,但可以设置为POST


#POST请求
(1). 数据不会出现在地址栏中
(2). 数据的大小没有上限
(3). 有请求体
(4). 请求体中如果存在中文,会使用URL编码!


#!!!requests.post()用法与requests.get()完全一致,特殊的是requests.post()有一个data参数,用来存放请求体数据
复制代码

3. OS模块(是与操作系统交互作用的二个接口卡塔 尔(英语:State of Qatar)

# 有的文件或许转义或者会情不自禁难点,平日要在双引号前加r,打消转义,或然用双斜杠表示

# 和当前执行的python文件工作目录相关的工作路径
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的父目录字符串名:('..')

# 和文件夹相关
os.makedirs('dirname1/dirname2')    可生成多层递归目录,即文件夹下创建子文件夹,不会覆盖原文件夹
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录,即文件夹;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的所有文件和文件夹,包括隐藏文件,并以列表方式打印

# 和文件相关
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息

# 和操作系统差异相关
os.sep    输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"tn",Linux下为"n"
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

# 和执行系统命令相关
os.system("bash command")   运行shell命令,直接显示,但是显示的看不懂

 os.popen("bash command).read()  运维shell命令,获取试行结果,可看懂,如os.popen('dir').read()

os.environ 获取系统环境变量

# 路径相关系列
os.path.abspath(path)  返回path规范化的绝对路径,即从哪个盘开始全部显示出来
os.path.split(path)  将path分割成目录和文件名二元组返回
os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)  返回path最后的文件名。如何path以/或结尾,那么就会返回空值。
               即os.path.split(path)的第二个元素
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是绝对路径,返回True
os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小,文件夹的大小不准确,只显示最大值4096字节,文件准确

ret = os.path.join('F:每天视频以及笔记','day5视频')
print(ret)
---F:每天视频以及笔记day5视频    # 组合成一个完整路径

思谋怎么总计文件夹中有所文件大小?示例路径:F:每日摄像以至笔记python11期day01

图片 18图片 19

import os
def ram(file_name):
    sum = 0
    for file in os.listdir(file_name):
        path = os.path.join(file_name, file)  # 组合成一个完整路径
        if os.path.isfile(path):   # 路径下是文件
            sum += os.path.getsize(path)
        else:
            sum += ram(path)
    return sum

print(ram('F:每天视频以及笔记python11期day01'))

选拔递归思想

图片 20图片 21

import os
def get_size(path):
    l = [path]
    sum_size = 0
    while l:
        path = l.pop()    # l = ['D:python11day2','D:python11day3'...]
        for item in os.listdir(path):    #path = 'D:python11'
            path2 = os.path.join(path, item)   # path2 = 'D:python11day2'
            if os.path.isfile(path2):
                sum_size += os.path.getsize(path2)   # sum = 文件的大小 + 0
            else:                           
                l.append(path2)
    return sum_size
print(get_size('D:python11'))

栈的切磋

  # 复制文件的函数在os模块中并不设有,因为复制文件实际不是由操作系统提供的系统调用。但是大家能够调用shuti模块中的copyfile(卡塔尔完结,该模块约等于os模块的叁个补充。

    b、发送POST的伸手,模拟浏览器的报到行为

4. sys模块(sys模块是与python解释器交互作用的二个接口卡塔尔国

1 sys.argv           命令行参数是一个List,第一个元素是程序本身路径
2 sys.exit(n)        退出程序,正常退出时exit(0)
3 sys.version        获取Python解释程序的版本信息
4 sys.maxint         最大的Int值
5 sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
6 sys.platform       返回操作系统平台名称

四、响应Response

5.种类化模块 

序列化

把对象(变量)从内存中成为可存款和储蓄或传输的长河称之为连串化,在Python中叫pickling,在别的语言中也被称之为serialization,marshalling,flattening等等,都是二个意思。

类别化目标

  • 持续化某种情况。在断电只怕关机在此以前能够将如今内部存款和储蓄器中全部的数码保存下来,下一次程序运营时得以从眼下保留的文件内容继续施行。
  • 跨平台数据交互作用。

种类化有八个模块json和pickle,shelve

  json   全部编制程序语言都通用的类别化格式,不过它帮衬的数据类型非常常有限(只援助数字,字符串,体系,字典等,不协助元祖

  pickle  只可以在python语言的次第之间传递数据使用,它帮助python中有所数据类型

  shelve  在py3之后才有,python专有的连串化模块,只针对文件。它只提供四个open方法,况且一定要用字典方式探访内容

json

 Json模块提供了多个功用:dumps、loads,那么些只在内部存储器中操作数据,首要在互联网传输中央银行使,和多少个数据类型与公事打交道

             dump、load ,这两个是间接将指标类别化之后写入文件,它依据于一个文本句柄

import json
dic={'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic) #将字典转换成字符串,转换后的字典中的元素是由双引号表示的
print(str_dic,type(str_dic))#{"k1": "v1", "k2": "v2", "k3": "v3"} <class 'str'>

dic2 = json.loads(str_dic)#将一个字符串转换成字典类型
print(dic2,type(dic2))#{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} <class 'dict'>

import json
dic={'k1':'v1','k2':'v2','k3':'v3'}
f = open('a.txt','w',encoding='utf-8')
json.dump(dic,f,ensure_ascii=False)  # 先接收要序列化的对象 再接受文件句柄
f.close()

f = open('a.txt','r',encoding='utf-8')
ret = json.load(f)
print(type(ret),ret)

 # json在写入多次dump的时候,不能够对应推行数次load来去除数据,pickle可以

# json尽管要写入五个要素,应先将元素dumps系列化,再f.write(类别化+‘n’)写入文件。读的时候先按行读取,再选拔loads将读出来的字符串调换到相应数据类型。

pickle(能够把python中的任性数据类型类别化卡塔 尔(阿拉伯语:قطر‎

  在硬盘上囤积文件有相当多种格局,文本文件只是里面豆蔻梢头种,假诺想囤积列表只怕目的之类的剧情,能够把对象调换到字符串的样式写入文本文件,不过要是要从文件中还原对象,则那一个就复杂化了。而python提供的pickle刚好能成功那一点:

# 通过pickle存储python原生对象:
import pickle
D = {'a': 1, 'b': 2}
F = open('datafile.pkl', 'wb')
pickle.dump(D, F)       # pickle.dump()可以把任意对象序列化成一个bytes,然后就可以把bytes写入文件
F.close()

# 取回字典,再用pickle模块中load函数进行一次重建
F = open('datafile.pkl', 'rb')
E = pickle.load(F)
F.close()


import pickle
file = 'wish.data'
lis = ['apple', 'banban']
f = open(file, 'wb')
pickle.dump(lis, f)
f.close()

del lis
f = open(file, 'rb')
storedlis = pickle.load(f)
print(storedlis)    # 又得到了列表

至于体系化自定义类的对象:

class A:
    def __init__(self,name,age):
        self.name=name
        self.age=age
a = A('luffy',18)
# import json
# json.dumps(a)   # 报错,说明json无法存储实例化对象
import pickle
ret = pickle.dumps(a)
print(ret)   # 打印出来的是一串字节
obj = pickle.loads(ret)
print(obj)    # 打印出对象地址
print(obj.__dict__)   # {'name': 'luffy', 'age': 18}

在load的时候,必需具有被load数据类型对应的类在内部存款和储蓄器里面

shelve(用法律专科学园讲链接)

  python专有的系列化模块,只针对文件,只提供了叁个open方法,且是用key来访谈的,使用起来和字典近似。

import shelve
f = shelve.open('a.txt')
f['key'] = {'int': 10, 'float': 9.5, 'string': 'Sample data'}
f['ds'] = '范围分为we分我发'
f.close()
# 直接对文件句柄进行操作,就可以存储文件,而且程序会给我们自动创建三个后缀为dir,bak,dat的文件,其中以bat结尾的文件存储的就是b字节数据类型的数据

f1 = shelve.open('a.txt')
a = f1['ds']   # 用key直接取出存储的内容,如果key不存在则会报错
f1.close()
print(a)

# 设置只读模式
f2 = shelve.open('a.txt', flag='r')
f2['key']['float'] = 3.14    # 修改结构中得值,不可以
f2['space'] = 'dwd'          # 覆盖原来的结构,可以
f1.close()

f3 = shelve.open('a.txt')
b = f3['key']['float']       # 对结构的值作修改,但是失败了
f3.close()
print(b)    # 9.5

    a、response属性

6.hashlib模块

  摘要算法,也称哈希算法,它能将字符串转成数字,不相同的字符串转成的数字断定差别,日常用16进制表示。无论在哪台机器上,在什么样时候总括,对同生龙活虎的字符串结果总是相似的

  任何摘要算法都是把最棒多的数据集结映射到二个少于的聚合中。因而多少个分化的数量经过有个别摘要算法也大概得到大器晚成致的摘要,这种景况被喻为碰撞

用处:

  密文验证的时候加密

  文件的大器晚成致性校验

# md5算法:产业界通用算法

# sha算法:安全周到越来越高,它有很各类(sha1,sha2,sha3等卡塔尔,前面数字越大,安全周密越高,且得到的数字结果越长,总结时间越长。它的用法和md5雷同,只需把md5换来sha1就可以。

密文验证的时候加密:

# hashhlib基本用法
import hashlib
m = hashlib.md5()                     # 创建了一个md5算法对象
m.update('aptx4869'.encode('utf-8'))  # 必须将字符串转换成utf-8格式
print(m.hexdigest())                  # 固定格式
# 6d1ce7aa0a1d988dc96a2abcd187b45a

import hashlib
m = hashlib.md5()
m.update('apt'.encode('utf-8'))   # 对源码进行拆分加密,得到的结果与整体加密一致
m.update('x4869'.encode('utf-8'))
print(m.hexdigest())
# 6d1ce7aa0a1d988dc96a2abcd187b45a
# 一段字符串直接进行摘要和分成几段摘要的结果是相同的


# 如果数字过于简单,就可以根据密文进行暴力破解获得源码,安全性不是太好,因此可以采用加盐的方式加密
# 加盐:在源码的基础上提前加一层静态码‘aptx4869’进行二次加密
m3 = hashlib.md5('aptx4869'.encode('utf-8'))
m3.update('123456'.encode('utf-8'))
print(m3.hexdigest())
# 21a36cc3275d352d92ee741b5425c330

# 这种方式较第一种比较安全性有所提高

# 动态加盐: 对于用户登录,可以通过相应的用户登录名进行一次加密,用密码二次加密,密码随着用户账户的变化而变化
username = 'Learning'
password = 'aptx4869'
m4 = hashlib.md5(username.encode('utf-8'))
m4.update(password .encode('utf-8'))
print(m4.hexdigest())
# b9112f155c08b48bba0e595236facc40

# 这种方式安全性大大的有所提高,登陆过程建议使用 

文件的风姿浪漫致性校验:(用来评释文件内容是还是不是被曲解卡塔尔

# 该函数一次性全部交验,如果文件较大,则耗时较大
import hashlib
def check(filename):
    md5obj = hashlib.md5()
    with open(filename,'rb') as f:
            content = f.read()
            md5obj.update(content)
    return md5obj.hexdigest()

# 该函数对于较大的文件,一次性以一定的字节数读取验证来验证一致性
def check(filename):
    md5obj = hashlib.md5()
    with open(filename,'rb') as f:
        while True:
            content = f.read(1024)  
            if content:
                md5obj.update(content)
            else:    # 如果文件为空
                break
    return md5obj.hexdigest()


ret1 = check('file1.txt')     
ret2 = check('file2.txt')
print(ret1)
print(ret2)   

那么难点来了,怎样验证七个公文的生龙活虎致性呢?

图片 22图片 23

import hashlib
def compare(filename1,filename2):
    md5sum = []
    for file in [filename1,filename2]:
        md5 = hashlib.md5()
        with open(file,'rb') as f:
            while True:
                content = f.read(1024)
                if content:
                    md5.update(content)
                else:break
            md5sum.append(md5.hexdigest())
    if md5sum[0] == md5sum[1]:return True
    else :return False

print(compare('f1','f2'))

View Code

图片 24图片 25

import hashlib
def loc(filname1, filname2):
    def check(filename):
        md5obj = hashlib.md5()
        with open(filename,'rb') as f:
            while True:
                content = f.read(5)
                if content:
                    md5obj.update(content)
                else:    # 非空
                    break
        return md5obj.hexdigest()
    if  check(filname1) == check(filname2):
        return True
    else:
        return False

print(loc('a.txt', 'a1.txt'))

View Code

图片 26图片 27

7.configparser

在配备文件里必需有分组(节卡塔 尔(阿拉伯语:قطر‎,分组的组名能够任由起 ,能够包蕴三个或五个组,能够叫DEFAULT,它都具备独特的意思(默许的是全局变量卡塔尔

# 创建ini文件
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {'luffy':'香蕉人',
                     'zero':'三把刀',
                     'sanzhi':'秋刀鱼'}
config['name'] = {'rojie':'onepiece',
                  'BB':'c',
                  'dd':'N'}
# config['www.onepiece.online'] = {'我就试试集合行不行'}  # 报错,只能是字典形式
config['www.onepiece.online'] = {'我就试试集合行不行':'不行啊'}
with open('one.ini', 'w') as f:
   config.write(f)

 写入后内容格局(这里本身是直接用Computer自带的文书阅读器展开的,暗中认可是gbk格式,用别样阅读器非gbk会生出乱码卡塔尔:

[DEFAULT]
zero = 三把刀
sanzhi = 秋刀鱼
luffy = 香蕉人

[name]
dd = N
bb = c
rojie = onepiece

[www.onepiece.online]
自个儿就试试集结行如故不行 = 不行呀

增加和删除改操作

# 增删改操作
import configparser
config=configparser.ConfigParser()
config.read('one.ini')
# 删除节'name'
config.remove_section('name')
# 删除节下的某个value值
config.remove_option('www.onepiece.online','我就试试集合行不行')
# 判断是否存在某个标题
print(config.has_section('name'))
# 判断标题section1下是否有user
print(config.has_option('www.onepiece.online','我就试试集合行不行'))
# 添加一个标题
config.add_section('EGG')
#在标题EGG下添加name=egon,age=18的配置
config.set('EGG','name','egon')
config.set('EGG','age','18')

总结:

# section  能够间接操作他的目的来获取具备的节消息

# option  能够透过找到的节来查看全体的项

import requests
respone=requests.get('http://www.jianshu.com')
# respone属性
print(respone.text)
print(respone.content)

print(respone.status_code)
print(respone.headers)
print(respone.cookies)
print(respone.cookies.get_dict())
print(respone.cookies.items())

print(respone.url)
print(respone.history)

print(respone.encoding)

#关闭:response.close()
from contextlib import closing
with closing(requests.get('xxx',stream=True)) as response:
    for line in response.iter_content():
    pass

8.logging  (记录日志的模块卡塔尔国

  不会帮您活动抬高日志的从头到尾的经过,只可以依据技术员写的代码完毕作用

  能够因而五个参数去决定全局的日志输出情状

  能够扶助开采者同有时间向文件和荧屏输出内容

  logging模块提供5中国和东瀛记等第,从低到高贰遍:debug info warning error critical

  默许是从warning形式最先显得

日志级别
CRITICAL = 50  #FATAL = CRITICAL
ERROR = 40
WARNING = 30  #WARN = WARNING
INFO = 20
DEBUG = 10

暗中认可等级为warning,它会暗中认可打字与印刷在极端上

大约用法:basicconfig

# 默认情况下 只显示警告(warning)及警告级别以上信息
import logging
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',datefmt='%a, %d %b %y %H:%M:%S',filename = 'userinfo.log')

logging.debug('debug message')       # debug 调试模式 级别最低
logging.info('info message')         # info  显示正常信息
logging.warning('warning message')   # warning 显示警告信息
logging.error('error message')       # error 显示错误信息
logging.critical('critical message') # critical 显示严重错误信息

---WARNING:root:warning message
---ERROR:root:error message
---CRITICAL:root:critical message
---WARNING:root:warning message

logging.basicconfig()函数可配参数:

图片 28图片 29

filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。 
datefmt:指定日期时间格式。 
level:设置rootlogger(后边会讲解具体概念)的日志级别 
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

#格式
%(name)s:Logger的名字,并非用户名,详细查看

%(levelno)s:数字形式的日志级别

%(levelname)s:文本形式的日志级别

%(pathname)s:调用日志输出函数的模块的完整路径名,可能没有

%(filename)s:调用日志输出函数的模块的文件名

%(module)s:调用日志输出函数的模块名

%(funcName)s:调用日志输出函数的函数名

%(lineno)d:调用日志输出函数的语句所在的代码行

%(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示

%(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数

%(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

%(thread)d:线程ID。可能没有

%(threadName)s:线程名。可能没有

%(process)d:进程ID。可能没有

%(message)s:用户输出的消息

View Code

logging模块组件:

# Logger 产生日志对象
# Handler 接收日志然后控制打印到不同地方:
#     FileHandler用来打印到文件中,
#     StreamHandler用来打印到终端
# Filter 过滤日志对象
# Formatter 指定日志显示格式

logger对象配置:

import logging
logger = logging.getLogger()    # Logger用于产生日志,实例化一个logger对象
# Handler对象:接收logger传来的日志,并控制输出
fh = logging.FileHandler('test.log',encoding='utf-8')
# 实例化一个文件句柄,并打印到文件
ch = logging.StreamHandler()
# 打印到终端,没有这步则只在文件中打印,在终端不显示,终端就是电脑输出界面
fmt = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
# 定制化显示格式
fh.setFormatter(fmt)
ch.setFormatter(fmt)
# 为Handler对象绑定格式

logger.addHandler(fh)
logger.addHandler(ch)
# 和logger关联的只有文件句柄
logger.setLevel(logging.WARNING)
# 对象警告级别,从该级别以上开始警报
# 这里我是直接给对象设置的该级别,意味着文件和终端都是同一级别,这里可以
# 对文件和终端分别设置不同的级别

logger.debug('debug message')       # debug 调试模式 级别最低
logger.info('info message')         # info  显示正常信息
logger.warning('warning message')   # warning 显示警告信息
logger.error('error message')       # error 显示错误信息
logger.critical('critical message')

View Code

9.collections模块

嵌入数据类型根底上,collections模块还提供了多少个附加数据类型:

  counter:计数器

  deque:双端排列,能够急迅从其余风流洒脱侧追加对象

  namedtuple:生成能够采用名字来探问元素内容的tuple

  orderdict:有序字典

  defaultdict:带有暗中同意值的字典

namedtuple:

from collections import namedtuple
point = namedtuple('point', ['x','y','z'])
p = point(1,4,9)
print(p.x)  # 1
print(p.z)  # 9

# 用来计算长方体体积
square = namedtuple('length',('x','y','z'))
v = square(5,2,8)
volume = v.x *v.y * v.z
print(volume)   # 80

deque:

  它是为着落到实处插入和删除操作的双向列表,适用于队列和栈

from collections import deque
lis = deque(['a','c','b'])
lis.append(3)
lis.appendleft(5)
print(lis)    # deque([5, 'a', 'c', 'b', 3])
# 这里直接用list()可以转换成列表形式

字符串要点,python之常用模块。Counter:

  它的成效是用来追踪值现身的次数,归属贰个严节的容器类型,以字典的键值对情势积存

宗旨用法:

from collections import Counter
c = Counter('abcdeabcdabcaba')
print(dict(c))    # {'e': 1, 'b': 4, 'd': 2, 'a': 5, 'c': 3}

print(c['a'])   # 5
print(c['b'])   #4

计数器的翻新,满含扩展(update卡塔 尔(英语:State of Qatar)和减少(subtract卡塔尔二种 

from collections import Counter

# update
c = Counter('smile')
c.update('lie')
print(c['e'])   # 2

d = Counter('beautiful')
f = Counter('bee')
d.update(f)
print(d['e'])  # 3

# subtract
c = Counter('smile')
c.subtract('lie')
print(c['e'])   # 0

d = Counter('beautiful')
f = Counter('bee')
d.subtract(f)
print(d['e'])   # -1

键的改正和删除(del卡塔尔

from collections import Counter
c = Counter("abcdcba")
c['a'] = 0
print(dict(c))   # {'d': 1, 'a': 0, 'c': 2, 'b': 2}
del c['b']
print(dict(c))   # {'a': 0, 'c': 2, 'd': 1}

算数和聚合操作

  +、-、&、|操作也得以用来Counter。在那之中&和|操作分别再次来到八个Counter对象各因素的最小值和最大值。必要注意的是,拿到的Counter对象将去除小于1的成分。

c = Counter(a=8, b=1)
d = Counter(a=5, b=2)
print(dict(c+d))   # {'a': 13, 'b': 3}
print(dict(c-d))   # {'a': 3}          注意,它只保留正数计数的元素
print(dict(c&d))   # {'a': 5, 'b': 1}  求交集,min(c[x], d[x])
print(dict(c|d))   # {'b': 2, 'a': 8}  求并集,max(c[x], d[x])

Counter类常用操作

图片 30图片 31

sum(c.values())  # 所有计数的总数
c.clear()  # 重置Counter对象,注意不是删除,最终返回None
list(c)  # 将c中的键转为列表
set(c)  # 将c中的键转为set
dict(c)  # 将c中的键值对转为字典
c.items()  # 转为(elem, cnt)格式的列表
Counter(dict(list_of_pairs))  # 从(elem, cnt)格式的列表转换为Counter类对象
c.most_common()[:-n:-1]  # 取出计数最少的n个元素
c += Counter()  # 移除0和负值

View Code

# 统计划生育龙活虎篇葡萄牙语文章内种种单词出现频率,并回到现身频率最高的前拾个单词及其现身次数

#  对['a','2',2,4,5,'2','b',4,7,'a',5,'d','a','z']该列表的多寡举行计数计算

# 方法链接:

Orderedict

  保持key的顺序

from collections import OrderedDict
d = dict([('a', 3), ('b', 5), ('c', 3)])
print(d)  # {'b': 5, 'c': 3, 'a': 3}

d = OrderedDict([('a', 3), ('b', 5), ('c', 3)])
print(d)  # OrderedDict([('a', 3), ('b', 5), ('c', 3)])
# 给这个样子感觉作用不大啊,用dict转型过来顺序又变了

defaultdict(暗中同意字典,是给字典中的value值设置私下认可值卡塔 尔(阿拉伯语:قطر‎

  它最大的功利在于永久不会在您使用key获取值的时候报错

  有如下值集合 [``11``,``22``,``33``,``44``,``55``,``66``,``77``,``88``,``99``,``90.``..],将所有大于 ``66 的值保存至字典的第一个key中,将小于 ``66 的值保存至第二个key的值中。

from collections import defaultdict

values = [11, 22, 33,44,55,66,77,88,99,90]

my_dict = defaultdict(list)

for value in  values:
    if value>66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)
print(dict(my_dict))

 

 

 

 

 

  

 

    b、编码难题

#编码问题
import requests
response=requests.get('http://www.autohome.com/news')
# response.encoding='gbk' #汽车之家网站返回的页面内容为gb2312编码的,而requests的默认编码为ISO-8859-1,如果不设置成gbk则中文乱码
print(response.text)

    c、获取二进制

#stream参数:一点一点的取,比如下载视频时,如果视频100G,用response.content然后一下子写到文件中是不合理的

import requests

response=requests.get('https://gss3.baidu.com/6LZ0ej3k1Qd3ote6lo7D0j9wehsv/tieba-smallvideo-transcode/1767502_56ec685f9c7ec542eeaf6eac93a65dc7_6fe25cd1347c_3.mp4',
                      stream=True)

with open('b.mp4','wb') as f:
    for line in response.iter_content():
        f.write(line)

    d、解析json

#解析json
import requests
response=requests.get('http://httpbin.org/get')

import json
res1=json.loads(response.text) #太麻烦

res2=response.json() #直接获取json数据


print(res1 == res2) #True

五、selenium模块

    a、介绍

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题

selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器

from selenium import webdriver
browser=webdriver.Chrome()
browser=webdriver.Firefox()
browser=webdriver.PhantomJS()
browser=webdriver.Safari()
browser=webdriver.Edge()

   b、安装

#安装:selenium+chromedriver
pip3 install selenium
下载chromdriver.exe放到python安装路径的scripts目录中即可,注意最新版本是2.29,并非2.9
国内镜像网站地址:http://npm.taobao.org/mirrors/chromedriver/2.29/
最新的版本去官网找:https://sites.google.com/a/chromium.org/chromedriver/downloads

#注意:
selenium3默认支持的webdriver是Firfox,而Firefox需要安装geckodriver
下载链接:https://github.com/mozilla/geckodriver/releases

六、选择器

   a、基本使用

图片 32图片 33

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
import time

driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
wait=WebDriverWait(driver,10)

try:
    #===============所有方法===================
    # 1、find_element_by_id
    # 2、find_element_by_link_text
    # 3、find_element_by_partial_link_text
    # 4、find_element_by_tag_name
    # 5、find_element_by_class_name
    # 6、find_element_by_name
    # 7、find_element_by_css_selector
    # 8、find_element_by_xpath
    # 强调:
    # 1、上述均可以改写成find_element(By.ID,'kw')的形式
    # 2、find_elements_by_xxx的形式是查找到多个元素,结果为列表

    #===============示范用法===================
    # 1、find_element_by_id
    print(driver.find_element_by_id('kw'))

    # 2、find_element_by_link_text
    # login=driver.find_element_by_link_text('登录')
    # login.click()

    # 3、find_element_by_partial_link_text
    login=driver.find_elements_by_partial_link_text('录')[0]
    login.click()

    # 4、find_element_by_tag_name
    print(driver.find_element_by_tag_name('a'))

    # 5、find_element_by_class_name
    button=wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'tang-pass-footerBarULogin')))
    button.click()

    # 6、find_element_by_name
    input_user=wait.until(EC.presence_of_element_located((By.NAME,'userName')))
    input_pwd=wait.until(EC.presence_of_element_located((By.NAME,'password')))
    commit=wait.until(EC.element_to_be_clickable((By.ID,'TANGRAM__PSP_10__submit')))

    input_user.send_keys('18611453110')
    input_pwd.send_keys('lhf@094573')
    commit.click()

    # 7、find_element_by_css_selector
    driver.find_element_by_css_selector('#kw')

    # 8、find_element_by_xpath

    time.sleep(5)

finally:
    driver.close()

View Code

本文由云顶最新线路检测发布,转载请注明来源

关键词: