5.1 存储
1. 文件
为了长期持续地存储数据,Python必须把数据以文件的方式存储在磁盘中。Python借助文本对象来读写文件。
内置函数open()创建文件对象:
f = open(文件名,方式)
文件名是文件存在于磁盘的名字
方式:
"r" #读取已经存在的文件
"w" #新建文件并写入
"a" #文件存在则写入文件尾,不存在则新建并写入
当新建文件或者打开文件之后,可以对文件进行读取:
s = f.read(4) #读取4个字节的数据
s = f.readline() #读取一行
s = f.readlines() #读取所有行,储存在列表,一行一个元素
当以“w”或“a”的方式打开文件,我们可以对文件进行写入文本,调用write()函数即可
Windows中的换行符是"\r\n"
UNIX中的换行符是"\n"
打开文件,读取之后,记得调用close()函数关闭文件,以节省计算机资源占用。
2. 上下文管理器
上下文管理器用了with...as...结构,其作用是通过缩进表明文件操作行为的起始与结束,它能自动关闭文件,而不需要f.close()属性进行关闭,能让程序员意识到那些阶段文件需要打开进行操作。示例:
with open("hhh.txt","w") as f:
f.write("hello,world!")
print(f.closed) #结果为True
上下文管理器基于对象的_exit_()特殊方法,当使用上下文管理器语法时,就会自动调用文件对象的_enter_()和_exit_()方法,一个是程序块开始之前调用,一个是结束时调用。
3.pickle包
对于文本,我们能够进行文件存储,而对象的存储我们则要使用pickle包进行序列化再将其存储于文件中进行保留。如何对敌?如下:
import pickle
class Bird(object):
have_feather = True
reproduction_method = "egg"
summer = Bird()
with open("summer.pkl","w") as f:
pickle.dump(summer,f) #序列化对象且保存
dump()函数是用以序列化的。
以上是对象的存储,下面讲对象的读取,它们的过程刚好相反。步骤是:
1、从文件中读取文本
2、用pickle的loads()方法将字符串形式的文本转换为对象
注意,对象属于类,先要有类的定义,才能够读取对象。
5.2 一寸光阴
1. time包
在硬件上,计算机可以提供挂钟时间,即从某个固定时间起点到现在的时间间隔。
所谓的处理器时间,即是当CPU实际运行时,计算机测量的时间,以测量性能。
软件上,我们现在通过Python编程来管理时间和日期。time包便提供了此类功能。整合如下:
time.time() #挂钟时间,单位为秒
time.clock() #测量程序运行时间(首尾调用clock()方法围住的程序的运行时间)Windows系统返回挂钟时间,而UNIX返回的是处理器时间
time.sleep() #让程序休息,括号内填秒数
time.gmtime() #返回struct_time格式的UTC时间
time.localtime() #返回struct_time格式的当地时间
time.mktime(st) #将struct_time格式转换为挂钟时间
struct_time对象可以将挂钟时间转换为年、月、日、时、分、秒等,并存储在该对象的各个属性中。(tm_year、tm_mon、tm_today......)
2. datetime包
datetime包是time包的一个高级包。即date + time = 年月日 + 时分秒毫秒。
于是datetime模块分为time和date两类。
datetime.datetime() #date类和time类一起使用
代表时间间隔的类:timedelta
一个时间间隔加上一个具体时间,可以得到新的时间点。
即调用timedelta()设定时间间隔(括号内可设置秒、星期、天、小时、毫秒、微妙),再用其与先定义的datetime时间进行加减,即可得到新的时间点。
两个datetime对象之间还可以进行比较运算,以确定哪个时间更长。
3. 日期格式
不同时间信息的格式化:
%Y——年份
%m——月份
%d——日
%H——24小时制的小时
%M——分钟
%S——秒
通过strptime()方法,将对应的时间信息的格式化(用format进行定义)填入其中,就可以打印出相应的格式。例如:
from datetime import datetime
str = "1999-10-31-140020"
format = "%Y-%m-%d-%H%M%S"
t = datetime.strptime(str,format)
print(t)
strftime()方法可以将一个datetime对象转换为特定格式字符串。
from datetime import datetime
format = "%Y-%m-%d,%H:%M:%S"
t = datetime(2020,1,11,23,22,50)
print(t.strftime(format))
5.3 看起来像那样的东西
1. 正则表达式 and 2.写一个正则表达式
对于这里,我认为先学习正则表达式的书写,了解正则表达式是什么,才去看格式应用,会比较好。那么何为正则表达式,顾名思义就是一种表达式,它可以用来达成某种目的,至于是什么目的,看下面:
正则表达式的常用语法:
. #任意一个字符
a | b #字符a或字符b
[afg] #a或f或g的一个字符
[0-4] #0-4范围内的一个字符
[a-f] #a-f范围的一个字符
[^m] #不是m的一个字符
\s #一个空格
\S #一个非空格
\d #一个数字即[0-9]
\D #一个非数字
\w #数字或字母
\W #非数字非字母
* #重复超过0次
+ #重复1次或超过1次
? #重复0或1次
{m} #重复m次
{m,n} #重复m到n次
由这些正则表达式的常用语法我们可以得知,正则表达式是用来规定某种或某些元素的出现形式和范围的,进而进行搜索并且可进行替换。
re包便是用来处理正则表达式的,简单应用:
import re
m = re.search("[0-9]","abcd4ef")
print(m.group(0))
除了search方法还有match方法,它们的区别在于match必须从字符串的第一个字符就符合正则表达式,否则返回None
对搜索到的字符串进行替换(sub方法):
str = re.sub(pattern, replacement, string)
其他方法:
re.split() #根据正则表达式分割字符串,将生成的子字符串放在列表中返回
re.findall() #根据正则表达式搜索字符串,将符合的子字符串放在列表中返回
3.进一步提取
对于搜索到的信息,要进一步的提炼,就需要对正则表达式进行修改。例如:
对str="abcd_aesd_output_2020_asbf_1999_aaas"
"output_\d(4)"用search方法可以找到"output_2020",那如果我只想要2020这一数字结果,那就要进一步提取,于是我们在正则表达式中用括号括起来我们想要提取的部分,目标便可以被提取出来。即output_(\d(4))。被括号括起来的部分我们称之为“群”,一个正则表达式中可以有多个群。
对群的命名格式:?P<name>......
方便用group("name")进行调用
5.4 Python有网瘾
1. HTTP通信
参与通信的个体总要遵守特定的协议,相当于语法、规则。HTTP协议是最常见的一种网络协议,即超文本传输协议。其过程便是请求、回复。
2. http.client包
Python是如何进行HTTP通信的呢?其标准库中有个http.client包,可以发出HTTP请求。示例:
import http.client
local = http.client.HTTPConnection("www.baidu.com") #主机地址
local.request("GET","/") #请求方法和资源路径
response = local.getresponse() #获得回复
print(response.status,response.reason) #回复的状态码和状态描述
content = response.read() #回复的主体内容
print(content)
5.5 写一个爬虫
根据前四个小节的内容,就可以写一个较为简单的程序了,以扒取网页上的一些信息。
对于本书本章利用http.client包发送请求,扒取网页信息,似乎不是太妥(按书本来,实现不了,是我太菜了),若是针对只能用标准库,我更倾向于使用urllib包。所以我决定使用request库获取页面信息然后用bs4进行提取:
import requests
import re
from bs4 import BeautifulSoup
def getHTMLText(url):
try:
a = requests.get(url, timeout = 20)
a.raise_for_status() #状态码不是200就会产生异常,即请求得不到回应
a.encoding = 'gb2312' #将字符编码设置成'gb2312',根据网站所用的字符编码修改,才能显示出文本信息
return a.text
except:
return "无法获得信息"
def findHTMLText(text):
soup = BeautifulSoup(text,"html.parser") #返回BeautifulSoup对象
return soup.find_all(string = re.compile(r"(.*分析):")) #通过正则表达式,实现字符串匹配
url = "http://www.southmoney.com/gupiao/scfx/"
text = getHTMLText(url)
r = findHTMLText(text)
#以下是对提取的信息进行处理
ls = list(r)
ls = [i for i in ls if len(i) < 40 ]
mate = ''
for s in ls:
mate = mate+s+'\n'
print(mate)
以上提取到的结果是:
美国非农就业数据分析:2019年就业人数创8年新低 长期就业前景仍稳健
A股市场行情分析:北上资金6个交易日净流入超310亿 周期股成新宠
乘用车市场分析:2019年狭义乘用车销量减少7.4% 机构预测进入短期底部
网红经济市场分析:日出东方遭遇黑天鹅 网红经济概念暂退烧
宠物行业市场分析:2019年吸金超22.37亿元 食品、用品领域投资活跃
物流业市场分析:上月中国物流业景气指数有所回落 但仍在高景气区间
疫苗行业分析:国产PCV13获批上市 接种人群较辉瑞沛儿13有所扩大
半导体行业市场分析:费城半导体指数年内暴涨63% 十年翻了约十倍
医药研发行业分析:ADC药物接连获批上市 业内纷纷加码布局
券商股投资价值分析:中信证券成交破百亿 打造航母级券商
猪肉行情分析:猪价较高峰下滑近两成 生猪存栏量13个月来首次环比转正
快递行业分析:北京市快递业价格行为规则出台
书本上的不知道是不是我代码打错了,样例实现不了,枯了。(新手上路,大佬莫怪)