re模块与爬虫的简单使用
re模块
从字符串里找特定的字符
re的基本语法(匹配规则)
findall
import re
s = '王大炮打炮被大炮打死了 王大炮打炮被大炮大死了'
print(s[1:3], s[6:8])
res = re.findall('大.',s) # 大加后面任意
print(res)
print(re.findall('^王大炮', s)) # ^:开头
print(re.findall('死了$', s)) # $: 结尾
结果为:
大炮 大炮
['大炮', '大炮', '大炮', '大炮', '大死']
['王大炮']
['死了']
s = 'acefghjkacefsdfsdf'
# []: 匹配中间的字符,只要单个字符
print(re.findall('[acef]', s)) # 只要单个字符
# []+^联用: ^对[]内的元素取反
print(re.findall('[^acef]', s))
# .: 任意字符(除了\n)
s = 'abacadaeaf'
print(re.findall('a..', s))
结果为:
['a', 'c', 'e', 'f', 'a', 'c', 'e', 'f', 'f', 'f']
['g', 'h', 'j', 'k', 's', 'd', 's', 'd']
['aba', 'ada']
s = 'abaacaaaaa'
# *: 前面的字符0-无穷个
print(re.findall('a*', s))
# +: 前面的字符1-无穷个
print(re.findall('a+', s))
# ?: 前面的字符0-1个
print(re.findall('a?', s))
# {m}: 前面的字符m个
print(re.findall('a{5}', s))
# {n,m}: 前面的字符2-3个 # 'abaacaaaaa'
# a aa aaa aa
print(re.findall('a{2,5}', s))
结果为:
['a', '', 'aa', '', 'aaaaa', '']
['a', 'aa', 'aaaaa']
['a', '', 'a', 'a', '', 'a', 'a', 'a', 'a', 'a', '']
['aaaaa']
['aa', 'aaaaa']
s = 's 1 s+\n=$\t2_s 3'
# \d: 数字
print(re.findall('\d', s))
# \D: 非数字
print(re.findall('\D', s))
# \w: 数字/字母/下划线
print(re.findall('\w', s))
# \W: 非数字/字母/下划线
print(re.findall('\W', s))
# \s: 空格/\t/\n
print(re.findall('\s', s))
# \S: 非空格/\t/\n
print(re.findall('\S', s))
结果为:
['1', '2', '3']
['s', ' ', ' ', ' ', ' ', ' ', 's', '+', '\n', '=', '$', '\t', '_', 's', ' ', ' ']
['s', '1', 's', '2', '_', 's', '3']
[' ', ' ', ' ', ' ', ' ', '+', '\n', '=', '$', '\t', ' ', ' ']
[' ', ' ', ' ', ' ', ' ', '\n', '\t', ' ', ' ']
['s', '1', 's', '+', '=', '$', '2', '_', 's', '3']
取消意义&.*()|
s = 'aba\d'
# \: 取消意义
print(re.findall(r'a\\d', s))
# .*: 贪婪模式(最大化),找到继续找,让结果最大化
s = 'abbbcabc'
print(re.findall('a.*c', s))
# .*?: 非贪婪模式(最小化),找到就马上停止
print(re.findall('a.*?c', s))
# (): 只要括号内的
s = 'abacad'
print(re.findall('a(.)', s))
# A|B: A和B都要
s = 'abacad'
print(re.findall('a|b', s))
结果为:
['a\\d']
['abbbcabc']
['abbbc', 'abc']
['b', 'c', 'd']
['a', 'b', 'a', 'a']
re模块的方法
'''
修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
'''
import re
s = 'abc123\ndef456'
print(re.findall('\d+',s))
com = re.compile('\d+')
par = '\d+'
com = re.compile('3.',re.S)
print(re.findall(com, s))
print(re.findall('3.', s, re.S))
结果为:
['123', '456']
['3\n']
['3\n']
import re
# re.split(): 按照匹配规则切割
s1 = 'abc324asdfk234lkjsf324lkj'
print(re.split('\d+', s1))
# re.sub(): 按照匹配规则替换(**********)
print(re.sub('\d+', '***', s1))
# re.subn(): 按照匹配规则替换,并计数
print(re.subn('\d+', '***', s1))
# 分组: 一个括号里的叫一个分组, django, 了解
s = 'abc123edf456'
res = re.search('abc(?P<abc>\d+)edf(?P<edf>\d+)', s)
print(res.groupdict())
结果为:
['abc', 'asdfk', 'lkjsf', 'lkj']
abc***asdfk***lkjsf***lkj
('abc***asdfk***lkjsf***lkj', 3)
{'abc': '123', 'edf': '456'}
爬虫
爬虫本质上是为了更加快速的获取某个网站上的某个信息,比如,图片视频等。
简单的爬虫可以利用requests模块以及re模块来批量获取图片,从而节省大量的时间
下面是一个最简单的爬虫
import re
import os
import requests
'http://www.xiaohuar.com/list-2-8.html'
for i in range(1,9):
url = f'http://www.xiaohuar.com/list-2-{i}.html'
res = requests.get(url)
data = res.text
res = re.findall('src="(.*?.jpg)"', data)
for i in res: # type:str
if i.startswith('/d/file'):
i = f'http://www.xiaohuar.com{i}'
img_name = i.split('/')[-1]
img_path = os.path.join('img', img_name)
res = requests.get(i)
img_content = res.content # 针对图片/视频/音频需要用content
with open(img_path, 'wb') as fw:
fw.write(img_content)
fw.flush()
print(f'下载图片{img_name}成功')
collections模块
复杂的数据类型
有名元组
from collections import namedtuple
point = namedtuple('point',['x','y'])
p = point(1,2)
print(p.x) # 1
print(p.y) # 2
默认字典
from collections import defaultdict
# dic = {'a':1}
# print(dic['b']) # 会报错
dic = defaultdict(lambda :'nan') # dic = {} # 如果找不到赋了一个默认值
dic['a'] = 1
print(dic['a']) # 1
print(dic['c']) # 2
双端队列
from collections import deque # 链表
de = deque([1,2,3])
de.append(4)
print(de) # deque([1, 2, 3, 4])
de.appendleft(0)
print(de) deque([0, 1, 2, 3, 4])
de.popleft()
de.popleft()
print(de) deque([2, 3, 4])
计数器
用collections的counter会使计数简单很多
普通计数
s= 'programming'
dic = {}
for i in s:
if i in dic:
dic[i]+=1
else:
dic[i] =1
print(dic)
counter计数
from collections import Counter
s= 'programming'
c = Counter() # 字典
for i in s:
c[i] +=1
print(c)