博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

python内置模块,正则爬取红牛分公司信息

Posted on 2021-11-25 20:30  ~sang  阅读(104)  评论(0)    收藏  举报

取消转义

在原生的正则表达式中取消转义推荐使用\(每个\只能取消一个字符的转义)

在python中取消转义推荐使用r'\n\a\t'(也可以使用\)

python内置模块之re模块

# 在python要想使用正则必须借助于模块 re就是其中之一

***

findall匹配所有满足条件的结果,结果是一个列表,如果没有字符串匹配则是空列表;’search和match是通过调用group()方法,找到第一个符合条件的就结束,如果没有字符串匹配,则返回None。但match是在字符串开始处进行匹配

***

import re

"""常用"""
# re.findall('正则表达式','带匹配的文本') 返回所有满足匹配条件的结果,放在列表里
res=re.findall('a','eva jason jackson')
print(res) # ['a','a','a'] 结果是一个列表(要么有元素,要么空列表)

"""常用"""
# 通过调用group()方法,找到第一个符合条件的就结束,如果字符串没有匹配,则返回None
ret=re.search('a','eva egon yuan').group()
print(ret) # 结果是a

"""常用"""
# 同search,不过尽在字符串开始处进行匹配
ret=re.match('a','abc').group()
print(ret) # 结果a

# 先按a分割得到''和'bcd',再对''和'bcd'分别按b分割
ret=re.split('[a,b]','abcd')
print(ret) # 结果['','','cd']

#将数字替换成H,参数1表示只替换1个
ret=re.sub('\d','H','eva3egon4yuan4',1)
print(ret) #结果evaHegon4yuan4

# 将数字替换成H,返回元组(替换结果,替换了多少次)
ret=re.subn('\d','H','eva3egon4yuan4')
print(ret) #结果('evaHegonHyuanH',3)

"""常用"""
# 将正则表达式编译成为一个正则表达式对象,规则要匹配的是3个数字
obj=re.compile('\d{3}')
ret=obj.search('abc123eeee') # 正则表达式对象调用search,参数为待匹配的字符串
ret1=obj.match('456aaddf4')
ret2=obj.findall('345fdfjj556jj2')
print(ret.group()) # 结果123
print(ret1.group()) # 结果456
print(ret2) # 结果['345','556']

"""常用"""
# finditer返回一个存放匹配结果的迭代器
ret=re.finditer('\d','ds3sy4784a')
print(ret) # <callable_iterator object at 0x0000025946911208>
print(next(ret).group()) # 查看第一个结果 3
print(next(ret).group()) # 查看第二个结果 4
print(next(ret).group()) # 查看第三个结果 7
print([i.group() for i in ret]) # 查看剩余的左右结果 ['8','4']

findall的分组优先展示及split的匹配部分加()的使用

import re

# findall针对分组优先展示  无名分组
res = re.findall("^[1-9]\d{14}(\d{2}[0-9x])?$",'110105199812067023')
print(res) # 结果['023']
# 取消分组优先展示  ?:
res1=re.findall("^[1-9]\d{14}(?:\d{2}[0-9x])?$",'110105199812067023')
print(res1) # 结果['110105199812067023']

# 有名分组 ?P<名字>
ret=re.search('^[1-9](?P<xxx>\d{14})(?P<ooo>\d{2}[0-9x])?$','110105199812067023')
print(ret.group()) # 结果110105199812067023
print(ret.group(1)) # 结果10105199812067 无名分组的取值方式(索引取值)
print(ret.group('xxx')) # 结果10105199812067
print(ret.group('ooo')) # 结果023

# split的优先级查询
ret=re.split('\d+','eva3egon4yuan')
print(ret) # 结果['eva', 'egon', 'yuan']

ret=re.split('(\d+)','eva3egon4yuan')
print(ret) # 结果['eva', '3', 'egon', '4', 'yuan']
# 在匹配部分加上()之后所切出的结果是不同的,
# 没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
# 这个在某些需要保留匹配部分的使用过程是非常重要的

正则爬取红牛分公司信息

# 读取待匹配的数据
import re

with open(r'a.txt','r',encoding='utf8') as f:
     data= f.read()
# 利用正则匹配数据
# 分公司名称
title_list=re.findall('<h2>(.*?)</h2>',data)
# print(title_list)
# 分公司地址
address_list=re.findall("<p class='mapIco'>(.*?)</p>",data)
# 分公司邮箱
email_list=re.findall("<p class='mailIco'>(.*?)</p>",data)
# 分公司电话
phone_list=re.findall("<p class='telIco'>(.*?)</p>",data)

res=zip(title_list,address_list,email_list,phone_list)
# for data_tuple in res:
#      # print("""
#      # 公司名称:%s
#      # 公司地址:%s
#      # 公司邮箱:%s
#      # 公司电话:%s
#      # """ % (data_tuple[0],data_tuple[1],data_tuple[2],data_tuple[3]))
with open(r'a1.txt','wt',encoding='utf8') as f1:
     for data_tuple in res:
          data_a = """
          公司名称:%s
          公司地址:%s
          公司邮箱:%s
          公司电话:%s
          """ % (data_tuple[0], data_tuple[1], data_tuple[2], data_tuple[3])
          f1.write(data_a)

collections模块

1.namedtuple:具名元组,生成可以使用名字来访问元素内容的tuple

from collections import namedtuple
"""
namedtuple('名称',[名字1,名字2,...])
namedtuple('名称','名字1 名字2 ...')
"""
point=namedtuple('坐标',['x','y'])
res=point(11,22)
print(res) # 坐标(x=11, y=22)
print(res.x) # 11
print(res.y) # 22

card=namedtuple('扑克','花色 点数')
card1=card('','A')
card2=card('','K')
print(card1) # 扑克(花色='♠', 点数='A')
print(card1.花色) #
print(card2.点数) # K

2.queue:队列

import queue # 内置队列模块:FIFO
# 初始化队列
q=queue.Queue()
# 往队列中添加模块
q.put('first')
q.put('second')
q.put('shird')
# 从队列中获取元素
print(q.get()) # first
print(q.get()) # second
print(q.get()) # shird
print(q.get()) # 值没了就会原地等待

3.deque:双端队列,可以快速的从另外一侧追加和推出对象

from collections import deque
q=deque([11,22,33])
q.append(44) # 从右边添加
q.appendleft(55) # 重左边添加
print(q) # deque([55, 11, 22, 33, 44])
print(q.pop()) # 从右边取值 44
print(q.popleft()) # 从左边取值 55

4.OrderedDict:有序字典

from collections import OrderedDict
order_dict=OrderedDict([('name','jason'),('pwd',123),('hobby','study')])
print(order_dict)
# OrderedDict([('name', 'jason'), ('pwd', 123), ('hobby', 'study')])
order_dict['xxx']=111
print(order_dict)
# OrderedDict([('name', 'jason'), ('pwd', 123), ('hobby', 'study'), ('xxx', 111)])
normal_dict['yyy']=222
print(normal_dict)
# {'name': 'jason', 'pwd': 123, 'hobby': 'study', 'yyy': 222}

5.defaultdict:带有默认值的字典

from collections import defaultdict
values=[11,22,33,44,55,66,77,88,99,90]
my_dict=defaultdict(list)
for value in values:
    if value>60:
        my_dict['K1'].append(value)
    else:
        my_dict['K2'].append(value)
print(my_dict)
# defaultdict(<class 'list'>, {'K2': [11, 22, 33, 44, 55], 'K1': [66, 77, 88, 99, 90]})

6.Counter:计数器,主要用来计数

res='abcdeabcdabcaba'
# 统计字符串中每个元素出现的次数
# new_dict={}
# for i in res:
#     if i not in new_dict:
#         new_dict[i]=1
#     else:
#         new_dict[i]+=1
# print(new_dict)
from collections import Counter # 计数器
ret=Counter(res)
print(ret)
# Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

time模块

***

时间三种表现形式

  1.时间戳(秒数)

  2.结构化时间(一般是给机器看的)

  3.格式化时间(一般是给人看的)

***

1.time.sleep() # 原地阻塞指定的秒数

2.time.time() # 获取时间戳时间

import time
#格式化时间
print(time.strftime('%Y-%m-%d')) # 2021-11-25
print(time.strftime('%Y-%m-%d %H:%M:%S')) # 2021-11-25 19:55:27
print(time.strftime('%Y-%m-%d %X')) # 2021-11-25 19:56:15

print(time.localtime())
print(time.gmtime(1111111))

datetime模块

import datetime
print(datetime.date.today()) # 2021-11-25
print(datetime.datetime.today()) # 2021-11-25 20:03:50.874346
res=datetime.datetime.today()
print(res.year) # 2021
print(res.month) # 11
print(res.day) # 25
print(res.weekday()) # 3 获取星期(weekday星期是0-6) 0表示周一
print(res.isoweekday()) # 4 获取星期(weekday星期是1-7) 1表示周一
"""时间差(timedelta)"""
ctime=datetime.datetime.today()
time_tel=datetime.timedelta(days=3)
print(ctime) # 2021-11-25 20:10:16.803960
print(ctime-time_tel) # 2021-11-22 20:10:16.803960
print(ctime+time_tel) # 2021-11-28 20:10:16.803960
"""
日期对象=日期对象 +/- timedelta对象
timedelta对象=日期对象 +/- 日期对象
"""
ret=ctime+time_tel
print(ret)
print(ret-ctime) # 3 days, 0:00:00
print(ctime-ret) # -3 days, 0:00:00

birthday=datetime.date(1997,7,21)
now_data=datetime.date.today()
days=birthday-now_data
print('距离生日还有天',format(days))

# UTC时间与我们的东八区时间差八个小时
print(datetime.datetime.now()) # 2021-11-25 20:20:29.686118
print(datetime.datetime.utcnow()) # 2021-11-25 12:20:29.686118