Python高级编程

一、正则表达式

1.match方法

  • 正则表达式:用来处理文本的,将一组类似的字符串进行抽象,形成的文本模式字符串——>匹配一类指定的字符串
  • 只要用了则正表达式就导入re模块
  • re.match(a,b)方法检测一个字符串b是否满足这个正则表达式a
  • 待匹配的字符串的前缀可以匹配正则表达式,系统也认为是匹配的

2.search方法

  • re.search(a,b) 在一个长的字符串b中搜索符合正则表达式a的字符串
    -re.group()方法返回查找到的结果,也就是子字符串的内容

3.匹配字符串

  • 特殊符号择一匹配符: |
import re
s='Python|Ruby|Java|Swift'
m=re.match(s,'PythonRuby')
print(m)
  • (.):点,可以匹配任意单个字符
import re

s = '.ind'
m = re.match(s, 'bind')
if m is not None:
    print(m.group())		#bind
m = re.match(s,'binding')
print( m)		#<re.Match object; span=(0, 4), match='bind'>
m = re.match(s,'bin')
print(m)		#None

m = re.search(s,'<bind>')
print(m.group())#bind
print(m)#<re.Match object; span=(1, 5), match='bind'>

s1 = '3\.14'	#反斜杠转义字符
						#代表(.)这个符号只是字符串的一部分
m = re.match(s1, '3.14')
print(m)#<re.Match object; span=(0, 4), match='3.14'>
m = re.match(s1, '3314')
print(m)			#None
  • 针对单个字符的择一选择:[ ]
  • 重复、可选字符:* + ? {}
符号作用
*单个字符出现0次到任意次,写在此字符后
+单个字符至少出现一次,写在此字符后
?单个字符可有可无,写在此字符后
{ }代表此字符的个数,有了就设定了有多少个了
()把一组字符括起来,若括号后面有*+?,只能设置括号内第一个字符
\w代表所有字符
\d代表任意一个数字
import re
# email
email = '\w+@(\w+\.)*\w+\.com'
emailList = ['abc@126.com','test@mail.geekori.com','test-abc@geekori.com','abc@geekori.com.cn']
while True:
    a=input('请输入邮箱,以0结尾')
    emailList.append(a)
    if a== '0':
        break
for value in emailList:    
    m = re.match(email,value)
    if m is not None:
        print(m.group())
    else:
        print('{}不匹配{}'.format(value,email))
strValue = '我的email是lining@geekori.com,请发邮件到这个邮箱'
m = re.search(email, strValue)
print(m)
email = '[a-zA-Z0-9]+@(\w+\.)*\w+\.com'
m = re.search(email, strValue)
print(m)

在这里插入图片描述

4.分组

 只有被圆括号括起来的部分才是一个分组
函数作用
group()返回满足该正则表达式的结果
group(1)返回该正则表达式第一个分组
groups()获取所有组的值,返回每个组 组成的元组
groups()[0]获取第1组的值

5.匹配字符串的起始和结尾以及单词边界

符号作用
^匹配字符串的开始,在字符串前面加^
$匹配字符串的结束,在字符串后面加$
\b匹配单词边界,边界有空格或者符号,放在左边是左边界),右边是右边界,字符串开始、结尾都算边界。要在正则表达式前加r防止\b转义
import re
m = re.search('^The', 'The end.')
if m is not None:
    print(m.group())	#The
m = re.search('^The', 'end. The')
if m is not None:
    print(m.group())
else :
    print(m)				#none

m = re.search('The$', 'end. The')
print(m.group())			#The
m = re.search('The$', 'The end.')
if m is not None:
    print(m.group())
else:
    print(m)				#none

m = re.search(r'\bthis\b', "What's this?")
print(m.group())			#this
m = re.search(r'\bthis\b', "What's thisa")
if m is not None:
    print(m.group())
else:				
    print(m)			#none

6.findall和finditer

  • re.findall(a,b) 通过列表返回所有字符串b中满足条件a的字符串
  • re.finditer(a,b) 将搜索结果通过一个迭代器返回所有字符串b中满足条件a的字符串,用来迭代
  • 第三个参数re.I,可以忽略大小写
import re
s = '12-a-abc54-a-xyz---78-A-ytr'
result = re.findall(r'(\d\d)-a-([a-z]{3})',s,re.I)
print(result)

it = re.finditer(r'(\d\d)-a-([a-z]{3})',s,re.I)
for result in it:
    print(result.group(),end=' < ')
    groups = result.groups()
    for i in groups:
        print(i,end = ' ')
    print('>')

在这里插入图片描述

7.sub和subn

  • re.sub(a,b,c)返回用b替换字符串c中满足正则表达式a的新字符串,全部替换
  • re.sub(a,b,c)返回用b替换字符串c中满足正则表达式a的新字符串和替换次数的元组
  • b可以是字符串,可以是正则表达式,还可以是函数
  • 可以使用(\数字)来直接取出第几个分组,从1开始,可以达到添加组与组之间元素的目的
import re
def fun():
    return r'产品编码(\1-\2)'
result = re.subn('([0-9])([a-z]+)', fun(),'01-1abc,02-2xyz,03-9hgf')
print(result[0]) #01-产品编码(1-abc),02-产品编码(2-xyz),03-产品编码(9-hgf)
#这里就是在数字前面添加了"产品编码(",在字母后面添加了“)”
print('替换总数','=',result[1])
#替换总数 = 3

8.使用split分割字符串

  • re.split(a,b)返回一个用a分割b的结果的列表
  • a可以是字符串,正则表达式
  • 注意在正则表达式中要常在前加字母r取消转义
  • 第三个参数可以用maxsplit关键字参数来指定最大分割次数
result = re.split('[a-z]{3}-[0-9]{2}',\
'testabc-4312productxyz-43abill',\
maxsplit=1) #只分割一次
print(result)   #用a来分割,所以a不见了
#['test', '12productxyz-43abill']

常用的正则表达式:

email = '[0-9a-zA-Z]+@[0-9a-zA-Z]+\.[a-zA-Z]{2,3}'
ipv4 = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
url = 'https?:/{2}\w.+'

二、常用模块

1.随机数random

函数作用
randint(m,n)产生m到n之间的随机整数,包括m和n
random()用于产生0到1之间的随机浮点数,左开右闭
uniform(m,n)用于产生m到n之间的随机浮点数,m和n可以是浮点数,包括m和n
randrange(m,n,step)在一个递增的序列中随机选择一个整数。其中step是步长
choice(seq)从seq指定的序列中随机选择一个元素值,seq指定的列表元素可以是任意类型的值
sample(seq,k)从seq指定的序列中随机选取k个元素,然后生成一个新的序列
shuffle(seq)把指定的序列中元素顺序打乱,该函数直接修改原有的序列,生成一个新序列

2.数学math

元素作用
math.pi圆周率
math.e自然常数
math.fabs()取绝对值
math.ceil()向上取整
math.floor()向下取整
math.pow(3,5)计算3的5次方
math.sqrt()计算开方
math.sin() math.cos() math.tan()计算sin,cos,tan的三角函数

3.sys模块

3.1.导入模块的相对路径:(将模块所在的路径添加到sys.path列表中)

  sys.path.append('./子目录')
  然后就可以调用子目录下文件的内容、函数
  • path是模块的路径列表
  • modules是已经装载模块的列表

3.2.输出当前文件的完整路径:

  print(sys.argv[0])

3.3.命令行参数

	sys.argv[1]表示第一个命令行参数

3.4.输入输出流

	s=sys.stdin.read(6) #标准输入流
	sys.stdout.writelines("hello,world") #标准输出流
	sys.stderr.writelines("error")  #标准错误流

	sys.exit(123)#调用当前脚本的返回值

4.集合、堆和双端队列

4.1.集合

  • 无序性:集合中的每一个元素都是平等的,无序的
  • 互异性:集合中的任意两个元素都是不同的,每个元素只能在一个集合中出现一次
  • 确定性:集合中每一个元素的值都是确定的。对于每一个集合的值,要么属于该集合,要么不属于。
  • 集合的操作:创建集合、合并集合、集合相交、集合的差
a = set((1,2,3))
b = set([3,5,1,7])
c = set([2,3])
d = set([1,2,3])

set1 = set(range(10))#创建一个十个元素的集合

print(a.union(b))#集合的并集
print(a | b)#集合的并集

print(a & b)#集合的交集
print(a.intersection(b))#集合的交集

print(c.issubset(a))#c是否是a的子集合
print(a.issubset(c))#a是否是c的子集合

print(c.issuperset(a))#c是否是a的超集
print(a.issuperset(c))#c是否是a的超集

print(a == d)#判断是否相等

print(a.difference(b))#a-b的差,在集合a中删除b的元素
print(a - b)#a-b的差,在集合a中删除b的元素

#计算集合之间的对称差,只在一个集合中有的元素
print(a.symmetric_difference(b))
print(a ^ b)
print((a - b) | (b - a))

x = a.copy()#拷贝集合
print(x is a)#x是否是a
x.add(30)#向集合中添加元素

4.2.将集合作为集合的元素(列表和集合都是可变的)

   frozenset(a)返回只读的集合
   然后就可以将只读的集合添加入其他集合

4.3.堆(Heap)(一种数据结构)

  • 导入heapq模块
  • 堆就是列表,只是通过heapq模块中的函数利用堆算法改变列表中的元素。
  • 优先队列——堆能以任意顺序增加元素值,并能快速找到最值,或前n个最值,这比min、max函数更高效
函数描述
heappush(heap,value)将value加入堆
heappop(heap)将堆中的最小值弹出
heapify(heap)将列表转换成堆,重新安排列表中元素的顺序
heapreplace(heap,value)将堆中的最小值弹出,并同时将value入堆
nalargest(n,iter)返回可迭代对象的前n个最大值,以列表形式返回
nsmallest(n,iter)返回可迭代对象的前n个最小值,以列表形式返回

5.时间、日期和日历time

  • 导入time模块

5.1.时间元组

  • 时间用一个元组表示,表示时间的元组有9个元素,这9个元素都有其对应的属性,所以时间元组中的每一个元素,既可以通过属性获得,也可以通过索引获得。

     import time 
     
     tm_year=2021
     tm_mon=11
     tm_mday=13
     tm_hour=16
     tm_min=54
     tm_sec=37     #年  月  日  时  分  秒  
     tm_wday=5    #一周的第几天
     tm_yday=317 #一年的第几天
     tm_isdst=0	   #夏令时,1表示是,0表示不是,-1是默认值表示未知
    

5.2.strftime()函数

  • 第一个参数是格式化参数,第二个参数是时间元组
格式化符号描述
%y两位数的年份(00-99)
%Y四位数的年份c0000-9999)
%m两位数的月份(01-12)
%d月内的某一天(0-31)
%H24小时制的小时数(0-23)
%l12小时制的小时数( 1-12)
%M分钟数(0-59)
%S秒(0-59)
%a本地简化星期名称
%A本地完整星期名称
%b本地简化月份名称
%B本地完整月份名称
%c本地日期和时间
%j年中的第几天(0-366)
%p本地 A.M .或 P . M .的等价符号,一般与12小时制的小时数一起使用
%U一年中的星期数,星期日为一个星期的开始
%w星期(0~6),星期日为一个星期的开始
%W一年中的星期数,星期一为一个星期的开始
%x本地日期
%X本地时间
%Z当前时区的名称
%%%号本身
import time
#时间戳的增量和时间的格式化
time1 = time.time()
time2 = time1 + 60             # 1分钟
time3 = time1 + 60 * 60         # 1小时
time4 = time1 - 60 * 60 * 24    # 1天
time1 = time.localtime(time1)
time2 = time.localtime(time2)
time3 = time.localtime(time3)
time4 = time.localtime(time4)
print (time.strftime("%Y-%m-%d %H:%M:%S", time1))
print (time.strftime("%Y-%m-%d %H:%M:%S", time2))
print (time.strftime("%Y-%m-%d %H:%M:%S", time3))
print (time.strftime("%Y-%m-%d %H:%M:%S", time4))

在这里插入图片描述
5.3.计算日期与时间的差值 datetime模块

  • 导入datetime模块
  • 分别定义两个datetime日期
  • 利用.days.seconds等函数计算差值
import datetime
d1 = datetime.datetime(2017, 4, 12,10,10,40)
d2 = datetime.datetime(2018, 12, 25,10,10,20)
print(d2 - d1)
print((d2 - d1).days)
print((d2 - d1).seconds)
d1 = datetime.datetime.now()

d2 = d1 + datetime.timedelta(hours=10)
print(d2)
import time
d2 = time.localtime(d2.timestamp())
#将时间戳转换为时间元组
print (time.strftime("%Y-%m-%d %H:%M:%S", d2))

在这里插入图片描述

三、文件和流

1.打开文件

1.1打开文件

  • open()函数,第一个参数指定打开的文件名,可以是相对路径也可以是绝对路径,第二个参数用于指定文件模式,返回一个文件对象
  • r+:文件可读写,如果文件不存在,会抛出异常。如果文件存在,会从当前位置写入新内容,通过seek函数可以改变当前位置,也就是改变文件的指针
  • w+:文件可读写,如果文件不存在,会创建一个新文件,如果文件存在,会清空文件,并写入新内容
  • a+:文件可读写,如果文件不存在,会创建一个新文件,如果文件存在,会将要写入的内容添加到文件最后
  • a=open(’./file/test1.txt’,‘w+’)
文件模式描述
‘r’读模式(默认)
‘w’写模式
‘x’排他的写模式(只能自己写)
‘a’追加模式
‘b’二进制模式(可添加到其他的模式中使用)
‘t’文本模式(默认值,可添加到其他模式中)
‘+’读写模式(必须与其他文件模式一起使用)

2.操作文件的方法

2.1.读文件和写文件

方法描述
write(string)向文件内写入内容,返回写入文件的字节数
read([n])返回读取的数据,n代表从文件指针位置一直读到n字节,不指定就读所有字节
seek(n)重新设置文件指针
close()关闭文件,读写之后要习惯关闭
  • 不管是write还是read,都改变了文件指针的位置
try:
    f = open('./files/test2.txt','r+')
    #若不存在test2,则会出现异常
except Exception as e:
    print(e)

f = open('./files/test2.txt', 'a+')
print(f.write('hello'))
f.close()

f = open('./files/test2.txt', 'a+')
print(f.read())#此时指针 已经被a+移动到了最后面
f.seek(0)#将指针重新置为0
print(f.read())
f.close()

try:
    f = open('./files/test2.txt', 'w+')
    print(f.read())#此时整个文件已经被w+清空了
    f.write('How are you?')
    f.seek(0)#将指针重新置为0
    print(f.read())
finally:
    f.close()

2.2.读行和写行

  • 1.先导入os模块
  • 2.用open打开文件
  • 3.用readline()读取一整行文本,包括行结束符
  • 添加一行文本:f.write(‘http://baidu.com’+os.linesep)
  • 读取全部文本:f.readlines()
import os
f = open('./files/urls.txt','r+')
url = ''
while True:
    url = f.readline()
    url = url.rstrip()
    if url == '':
        break;
    else:
        print(url)
print('-----------')
f = open('./files/urls.txt','a+')
urlList = ['https://geekori.com' + os.linesep, 'https://www.google.com' + os.linesep]
f.writelines(urlList)
f.seek(0)
print(f.readlines())
f.close()
  • 总结:如果要向文件中写入内容,则就是把输出语句全部换成write语句。

3.使用FileInput对象读取文件

  • 导入fileinput模块
  • fileinput.input()返回一个fileinput对象
  • fileinput.readline()所占内存小
'''
编写程序,要求从当前目录中读取一个文件的所有内容
并统计集中每个单词出现的次数,单词之间用逗号、
分号、或者空格分割了,将统计结果保存至字典,并输出结果
'''
import re
f=open('wods.txt','r')
words=f.read()
wordlist=re.split('[ ,;]+',words)
print(wordlist)
coutDict={}
for word in wordlist:
    if coutDict.get(word) == None:
        coutDict[word] = 1
    else:
        coutDict[word] = int (coutDict[word]) + 1
for (key,value) in coutDict.items():
    print(key,'=',value)
f.close()

四、数据储存

1.处理XML格式的数据

1.1.读取与检索XML文件

  • 导入xml.etree.ElementTree import parse
  • 用parse打开xml文件
  • doc.iterfind(‘product’) 迭代每一个节点
  • findtext()函数用于读取每一个节点的具体信息

2.处理JSON格式的数据

2.2.将JSON字符串与字典相互转换
1.dict–>json

  • 导入JSON模块的dumps函数
  • dumps()函数通过参数传入字典,返回json格式字符串

2.json–>dict

  • 使用json模块的loads函数,该函数通过参数传入json字符串,然后返回与该字符串对应的字典
  • 使用eval函数将json格式字符串当作普通的Python代码执行,eval函数会直接返回与json格式字符对应的字典

2.3.将JSON字符串与类转换

  • 指定类:loads函数会自动创建指定类的实例,将由json字符串转换成的字典通过类的构造方法传入类实例

json–>dict

  • dumps()用default关键字参数指定的回调函数将类实例转换为字典,再将字典转换为json字符串

3.将JSON字符转换为XML字符串

json–>dict–>xml

  • 使用dicttoxml模块中的dicttoxml()函数将字典转换为XML
import json
import dicttoxml
f = open('files/products.json','r',encoding='utf-8')
jsonStr = f.read()
d = json.loads(jsonStr)
print(d)
xmlStr = dicttoxml.dicttoxml(d).decode('utf-8')
print(xmlStr)
f.close()

4.SQLiet数据库(重要)

  • 将数据保存在SQLite数据库中,是本地储存的最佳方案。将下载后的数据经过整理之后保存到SQLite数据库中,或者干脆将原始数据保存到SQLite数据库中然后再做数据清洗

4.1.用Python操作SQLite数据库
增删改查操作

  • 导入sqlite3模块
import sqlite3
import os

dbPath = 'data.sqlite'#定义一个路径,没有sqliet扩展名也可以
#sqlite数据库就是一个单独的二进制文件
if not os.path.exists(dbPath):#如果文件不存在就创建,存在就打开
    conn = sqlite3.connect(dbPath)#创建数据库
    c = conn.cursor()#获取sqlite3.cursor对象
    #创建一个名为persons的表:
    c.execute('''CREATE TABLE persons
       (id INT PRIMARY KEY     NOT NULL,
       name           TEXT    NOT NULL,
       age            INT     NOT NULL,
       address        CHAR(50),
       salary         REAL);''')
    conn.commit()#修改数据库之后必须调用commit方法提交才能生效
    conn.close()#关闭数据库连接
    print('创建数据成功')

conn = sqlite3.connect(dbPath)
c = conn.cursor()
c.execute('delete from persons')#删除persons表中所有数据
#向persons表中插入四条数据:
c.execute("INSERT INTO persons (id,name,age,address,salary) \
      VALUES (1, 'Paul', 32, 'California', 20000.00 )");
c.execute("INSERT INTO persons (id,name,age,address,salary) \
      VALUES (2, 'Allen', 25, 'Texas', 15000.00 )");

c.execute("INSERT INTO persons (id,name,age,address,salary) \
      VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )");

c.execute("INSERT INTO persons (id,name,age,address,salary) \
      VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 )");    
conn.commit()

print('插入数据成功')
#查询persons表中的所有记录,并按age升序排列
persons = c.execute("select name,age,address,\
salary from persons order by age")
print(type(persons))
result = []
for person in persons:#将sqlite3.cursor对象中的数据转换为列表形式
    value = {}
    value['name'] = person[0]
    value['age'] = person[1]
    value['address'] = person[2]
    result.append(value)
conn.close() 
print(type(result))
print(result)#输出查询结果

import json
#将查询结果转换为字符串形式,
#如果要将数据通过网络传输
#就要首先转换为字符串形式
resultStr = json.dumps(result)
print(type(resultStr))
print(resultStr)

5.MySQL数据库

  • 基于网络的关系型数据库
  • 导入pymysql模块(pip install pymysql来安装)
方法描述
connect()连接数据库,返回Connect对象
cursor()获取操作数据库的Cursor
execute()用于执行SQL语句,返回Cursor对象
commit()修改数据库后,需要调用该方法提交对数据库的修改,返回Cursor对象
rollback()若修改数据库失败,一般需要调用来对数据库进行回滚,将数据库还原
from pymysql import *
import json
def connectDB():
#打开mysql数据库,分别是ip地址,用户名,密码。meituan是数据库名
    db=connect("127.0.0.1","root","12345678","meituan",charset='utf8')
    return db
db = connectDB()
print(type(db))
def createTable(db):    
    cursor=db.cursor()    
    sql='''CREATE TABLE persons
       (id INT PRIMARY KEY     NOT NULL,
       name           TEXT    NOT NULL,
       age            INT     NOT NULL,
       address        CHAR(50),
       salary         REAL);'''
    try:   
        cursor.execute(sql)
         # 提交到数据库执行
        db.commit()
        return True
    except:
        # 如果发生错误则回滚
        db.rollback()
    return False


def insertRecords(db):   
    cursor=db.cursor()    
    try:   
        cursor.execute('DELETE FROM persons')
        cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
          VALUES (1, 'Paul', 32, 'California', 20000.00 )");
        cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
          VALUES (2, 'Allen', 25, 'Texas', 15000.00 )");
    
        cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
          VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )");
    
        cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
          VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 )"); 
        # 提交到数据库执行
        db.commit()
        return True
    except Exception as e:
        print(e)
        # 如果发生错误则回滚
        db.rollback()
    return False
def selectRecords(db):
    cursor=db.cursor()  
    sql='SELECT name,age,salary FROM persons ORDER BY age DESC'
    cursor.execute(sql)
    results=cursor.fetchall()
    print(results)
    fields = ['name','age','salary']
    records=[]
    for row in results:
        records.append(dict(zip(fields,row)))
    return json.dumps(records)    
    
    

if createTable(db):
    print('成功创建persons表')
else:
    print('persons表已经存在')

if insertRecords(db):
    print('成功插入记录')
else:
    print('插入记录失败')
print(selectRecords(db))
db.close()

6.非关系型数据库

  • 关系型数据库将数据保存在二维表中
  • NoSQL类型:对象数据库、键-值数据库、文档数据库、图形数据库、表格数据库
  • MongoDB:文档数据库
  • 连接MongoDB数据库需要创建MongoClient类的实例,连接MongoDB之后,可按文档的方式操作数据库

五、网络高级编程

1.urllib3模块

  • 导入urllib3模块
  • 编码中文:form urllib3.parse import urlencode

1.1.发送HTTP GET请求

  • 关闭警告
  • 创建PoolManager对象
  • 组合的方式生成一个需要请求的url:url='http://www.baidu.com/s?'+urlcode('wd':'亚洲图片')
  • 发送请求:http.request(‘GET’,url)(http是PoolManager对象)
  • 解码:.decode(‘UTF-8’)
    request()函数的第三个参数可以指定请求:
    http.request(‘GET’,url,fields =(‘wd’:‘亚洲图片’))
from urllib3 import *
from urllib.parse import urlencode

disable_warnings()
http = PoolManager()
url = 'http://www.baidu.com/s?' + urlencode({'wd':'亚洲图片'})
print(url)
#response = http.request('GET', url)
url = 'http://www.baidu.com/s'
response = http.request('GET', url,fields={'wd':'亚洲图片'})
data = response.data.decode('UTF-8')
print(data)

1.2.发送HTTP POST请求

  • 编写一个HTTP服务器,来接收post请求,用flask框架安装
  • 导入flask模块
  • 先创建一个flask对象,传入当前模块的名字
  • 再写一个路由,这个路由里可以处理HTTP POST请求
from flask import Flask, request

app = Flask(__name__)#创建一个flask对象,传入当前模块的名字

@app.route('/')
def helloworld():
    return 'hello world'
#设置一个/register路由,这个路由里可以处理HTTP POST请求
@app.route('/register', methods=['POST'])
def register():
    print(request.form.get('name'))#请求的字段名name
    print(request.form.get('age'))#请求的字段名age
    return '注册成功'

if __name__ == '__main__':#若当前模块(当前py程序)等于主模块,防止其他py程序调用这个程序
    app.run()#启动
  • 通过urllib3发送POST请求,和发送GET请求差不多
  • 创建PoolManager对象
  • 生成一个需要请求的url:url='http:/127.0.0.1:5000/register'
  • 用request函数发送请求,第三个参数指定请求类型
from urllib3 import *


disable_warnings()
http = PoolManager()

url = 'http://localhost:5000/register'
response = http.request('POST', url,fields={'name':'李宁','age':18})
data = response.data.decode('UTF-8')
print(data)

1.3.HTTP请求头

将淘宝的请求头复制下来,然后传递这个请求头

from urllib3 import *
import re
disable_warnings()#关闭警告
http = PoolManager()#创建PoolManager对象
#定义天猫的搜索页面url:
url = 'https://list.tmall.com/search_product.htm?spm=a220m.1000858.1000724.4.53ec3e72bTyQhM&q=%D0%D8%D5%D6&sort=d&style=g&from=mallfp..pc_1_searchbutton#J_Filter'
#定义一个函数,
# 从file文件里获取http的请求头,并转换为字典
def str2Headers(file):
    headerDict = {}
    f = open(file,'r')
    headersText = f.read()#读取file中的所有内容
    headers = re.split('\n',headersText)#把每一行分开
    for header in headers:#以每一行第一个冒号进行分割
        result = re.split(':',header,maxsplit = 1)
        headerDict[result[0]] = result[1]
    f.close()
    return headerDict#求出请求头字典
#调用这个函数:
headers = str2Headers('headers.txt')
#请求天猫的搜索页面,并传递HTTP请求头:
response = http.request('GET', url,headers=headers)
#将服务器返回的数据按GB18030格式解码:
data = response.data.decode('GB18030')
print(data)

1.4HTTP 响应头

  • 使用HTTPResponse.info方法获取HTTP响应头的信息,HTTPResponse对象是request方法的返回值
from urllib3 import *
disable_warnings()
http = PoolManager()
url = 'https://www.baidu.com'
#url = 'http://httpbin.org/delay/3'
response = http.request('GET',\
 url,timeout=Timeout(connect=2,read=4))
#输出HTT响应头信息(以字典形式返回HTTP响应头信息):
print(response.info())
print('------------')
#输出HTTP响应头中Content-Length字段的值:
print(response.info()['Content-Length'])

1.5 上传文件

  • 上传的文件用multipart/form-data格式进行编码
#http是PoolManager类的实例
#上传任意类型的文件:
http.request('POST',url,fields = {'file': (filename,fileData) } ) 
#上传文本格式的文件:
http.request('POST',url,fields = {'file': (filename,fileData,'text/plain') } ) 
#上传jpeg格式的文件:
http.request('POST',url,fields = {'file': (filename,fileData,'image/jpeg') } ) 

上传文件的客户端程序:

from urllib3 import *
disable_warnings()
http = PoolManager()
url = 'http://localhost:5000'
while True:
    filename = input('请输入要上传的文件名字(必须在当前目录下):')
    if not filename:
        break
#用二进制的方式打开要上传的文件名,然后读取文件的所有内容,使用with语句会自动关闭打开的文件
    with open(filename,'rb') as fp:
        fileData = fp.read()
#上传文件:
    response = http.request('POST',url,fields={'file':(filename,fileData)})
#输出服务器的返回结果:
    print(response.data.decode('utf-8'))

2.twisted框架

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值