一、正则表达式
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) |
%H | 24小时制的小时数(0-23) |
%l | 12小时制的小时数( 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'))