软件开发规范:
比如开发一个shop程序,下面得有一些目录,bin是可执行文件目录,conf(配置文件),core(主逻辑文件),data(数据文件),logs(写日志),README.txt(markdown语法,http://www.jianshu.com/p/1e402922ee32/入门指南)
PS 1:如果在这些目录下的文件里调用这些目录的其他文件,需要把shop这个目录加入到环境变量里,加入方法:
Import os,sys
path=os.path.dirname (os.path.dirname(__file__)) #把当前文件的父目录的父目录(在这里指shop)赋值给path
sys.path.append(path) #把shop加入到环境变量里,就可以调用shop下的python模块
PS 2:
If __name==’__main__’:
Print(‘XXXXXXXXX’) #意思是只有当在自己文件里运行的时候,才走这个判断语句;如果是别的文件调用这个模块,则不走这个if判断语句;一般自测的时候用这个
正则表达式
re模块
在python中,如果使用正则表达式的话,需要导入re模块,re模块是一个内置模块,直接import就可以使用
import re
s='besttest is good'
1.print(re.match(r'best',s)) #字符串前面加r,代表原字符、不转义
#match方法接收3个参数,第一个是匹配的规则,也就是正则表达式,第二个是要查找的字符串,第三个参数不是必填的,用于控制正则表达式的匹配方式,看下面正则表达式的匹配模式。PS:是从字符串的第一个字符中匹配字符串(即从第一个字符开始匹配,比较麻烦),如果匹配到就返回一个对象,如果匹配不到,则返回None
#输出结果是:>>><_sre.SRE_Match object; span=(0, 4), match='best'>
print(re.match(r'best',s).group()) #加了group,输出结果是best
2.print(re.search('best',s))
#search方法的参数和match一样,和match方法不一样的是,match是从字符串里面的第一个字符开始找,而search方法则是从字符串的整个内容里面找,如果找到了就返回第一个(之后的不返回),找不到就返回None
#输出结果是:>>><_sre.SRE_Match object; span=(0, 4), match='best'>
3.print(re.findall(r'best',s))
#findall方法的参数上面的match、search一样,和他们不一样的是,findall会返回所有一个list,把所有匹配到的字符串,放到这个list里面,如果找不到的话,就返回一个空的list
#输出结果:>>> ['best']
4.print(re.sub(r'best','Best',s))
#sub方法和字符串的replace方法一样,是用来替换字符串的,把匹配到的值替换成一个新的字符串,接收3个参数,第一个是正则表达式,第二个是要替换成什么,第三个就是要查找的字符串,会返回一个新的字符串,如果匹配不到的话,返回原来的字符串
# 不会改变原来的字符串的值,只是返回一个新字符串
#输出结果:>>> Besttest is good
5.print(re.split('best',s))
#split 方法和字符串的split方法一样,是用来分割字符的,按照匹配到的字符串进行分割,返回的是一个list,如果匹配不到的话,那返回的list中还是原来的字符串
#输出结果:>>> ['', 'test is good']
正则表达式常用符号:
1.数量词
'*' 匹配*前的这个字符0次或多次;*前的这个字符可有可无,无的话匹配空,有1个或多个的话就匹配1次或多次,其他字符必须有,没有的话返回为空。
例如:print(re.findall(r'be*s','beesttest very bestb bs besss'))
>>>['bees', 'bes', ‘bs’,'bes']
'+' 匹配+前的这个字符1次或多次,至少出现一次
print(re.findall(r'st+','besttest is best'))
>>> ['stt', 'st', 'st']
'?' 匹配?前一个字符1次或0次,只是?前面的一个字符
print(re.findall(r'st?','besttest is best'))
>>> ['st', 'st', ‘s’, 'st']
'{m}' 匹配{}前的一个字符m次
print(re.findall(r't{2}','besttest is best'))
>>> ['tt']
'{n,m}' 匹配{}前一个字符n到m次
print(re.findall(r't{1,2}','besttest is best'))
>>> ['tt', 't', 't']
2.一般字符
'.' 默认匹配除\n之外的任意一个字符
print(re.findall(r'b.','besttest is good'))
>>> ['be']
print(re.findall(r's.','besttest is good'))
>>> ['st', 'st', 's']
'\' 转译符,前面的* + ?这样的字符都有特殊含义了,如果你想就想找它的话,那就得转译了,意思就是说如果你想让特殊字符失去以前的含义,那么就得给它前面加上\
print(re.findall(r'\?','besttest is best????'))
>>> ['?', '?', '?', '?']
'|' 匹配|左或|右的字符串,不是字符
print(re.findall(r'best|is','besttest is best'))
>>> ['best', 'is', 'best']
'[]' 字符集合,某些字符的集合,匹配的时候是这个集合里面的任意一个字符就行
print(re.findall(r'be[stacj]','besttest is best bejson'))
>>>['bes', 'bes', 'bej']
在[]里面如果用‘^’ 在[]里面如果用^的话代表取反,也就是不包括的[]里这些字符串的字符
print(re.findall(r'be[^stac]','besttest is best bejson'))
>>>[ 'bej']
3.边界匹配(开头和结尾)
'^' 匹配以什么字符开头,多行情况下匹配每一行的开头,比如判断一个网站是不是以https开头
print(re.findall(r'^b','besttest is good\nbest'))
>>> ['b']
print(re.findall(r'^b','besttest is good\nbest',re.M)) #多行模式要加第三个参数re.M
>>> ['b','b']
'$' 匹配以什么字符结尾,多行情况下匹配每一行的结尾,比如判断图片是不是以jpg、gif等结尾
print(re.findall(r'd$','besttest is good'))
>>> ['d']
print(re.findall(r'd$','besttest is good\nbest is good',re.M))#多行模式
>>>['d','d']
'\A' 仅以什么字符开头,和^不同的是它不能用多行模式
print(re.findall(r'\Ab','besttest is good'))
>>> ['b']
'\Z' 仅以什么字符结尾,和$不同的是它不能用多行模式
print(re.findall(r'd\Z','besttest is good'))
>>> ['d']
4.预定义字符集合
'\d' 匹配数字0-9
print(re.findall(r'\d','sdf2342312sdfs'))
>>>['2', '3', '4', '2', '3', '1', '2']
print(re.findall(r'\d+','sdf2342312sdfs'))
>>> ['2342312']
'\D' 匹配非数字,包括字母、特殊字符等
print(re.findall(r'\D','sdf2342312sdfs'))
>>> ['s', 'd', 'f', 's', 'd', 'f', 's']
print(re.findall(r'\D+','sdf2342312sdfs'))
>>>['sdf', 'sdfs']
'\w' 匹配所有的字母和数字、汉字
print(re.findall(r'\w+','sdf234%^2312sdfs&你好'))
>>> ['sdf234', '2312sdfs', '你好']
'\W' 匹配不是字母和数字、汉字,指特殊符号和空格(匹配不了汉字)
print(re.findall(r'\W','sdf234%^2312sdfs&'))
>>>['%', '^', '&']
'\s' 匹配空白字符、\t、\n、\r,空格#\t指一个tab键
print(re.findall('\s','axss\n\tsdf\t\r\t'))
>>> ['\n', '\t', '\t', '\r', '\t',’ ‘]
'\S' 匹配非空白字符,不是\t、\n、\r,空格
print(re.findall('\S','axss\n\tsdf\t\r\t'))
>>> ['a', 'x', 's', 's', 's', 'd', 'f']
PS:[A-z] 所有的大小写字母
[a-z] 所有的小写字母
[A-Z] 所有的大写字母
[0-9] 所有的数字
5.分组匹配
分组匹配,就是把相同的规则写在一个组里,这样就可以直接对这个组进行一些匹配了。
例子:匹配ip地址(192.168.5.1,每一段都是1位或者3位的数字,后面有个点)
print(re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}',"192.168.1.3")) #\d{1,3}指匹配1-3次的数字
>>> ['192.168.1.3'] #不分组匹配的话得这么写,比较麻烦,但我们可以发现规律,除了第一个,后面的全都是'\.\d{1,3}',这样的话就可以用分组了,就把'\.\d{1,3}'当做一个整体,然后让他们出现3次就ok了,可以改成下面这样的:
print(re.search(r'\d{1,3}(\.\d{1,3}){3}',"192.168.1.3").group())
>>> 192.168.1.3 #这个是用search方法的,结果和上面的一样的,加group是让结果更直观,只有search和match有group方法
print(re.findall(r'\d{1,3}(\.\d{1,3}){3}',"192.168.1.3"))
>>> ['.3'] #改成findall,发现结果错误。用match方法和search方法都是正常的,但findall方法这里有个坑。如果findall方法里面有分组的话,那结果就只是分组里面的内容(即小括号里的内容)。如果想让结果正确的话,就在分组最前面写上'?:',一个问号和一个冒号就好了,启用“不捕捉模式”:
print(re.findall(r'\d{1,3}(?:\.\d{1,3}){3}',"192.168.1.3"))
>>>['192.168.1.3'] #findall方法加上?:结果就正确了
爬虫需要用的知识:
html是浏览器能解析的代码
requests模块
import requests
req=requests.get(‘http://baidu.com’) #发get请求,打开一个url
print(req.text) #获取网站返回的内容,即html
print(req.encoding) #获取网站的编码,不同的网站编码不同,有UTF-8、ISO-8859-1等;在读写文件的时候需要用到编码