爬虫数据清洗中一些常用的方式

鳄鱼君

发表文章数:615

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » 爬虫数据清洗中一些常用的方式

爬虫从网页中采集的数据大多数都是杂乱无章的,就像我们在百度搜索某个关键词出来的结果一样。这时候就需要对采集的数据加工清洗,去掉一些无用的垃圾数据,得到我么想要的数据。对数据的清洗有几种常用的方式:字符串操作、正则表达式第三方模块库。三种方法适用于不同的场景,爬虫开发者需要取长补短,根据实际情况选择合理的清洗方法。

字符串操作

常见的字符串操作有:截取、替换、查找和分割,我们分别进行介绍说明:

● 截取:格式:字符串 [开始位置:结束位置:间隔位置]

开始位置是0,正数代表从左边位置开始,负数代表从右边位置开始,默认代表从0开始。结束位置是被截取的字符串位置,空值默认取到字符串尾部。间隔位置默认为1,截取的内容不做处理;如果设置为2,就将截取的内容在隔1取数,例如:

# 字符串截取
str_intercept="ABCDEFG"
# 截取第一位到第三位的字符
print("截取第一位到第三位的字符:%s" % str_intercept[:3])
# 截取字符串的全部字符
print("截取字符串的全部字符:%s" % str_intercept[::])
# 截取第五个字符到结尾
print("截取第五个字符到结尾:%s" % str_intercept[4::])
# 从开始到倒数第三个字符之间
print("从开始到倒数第三个字符之间:%s" % str_intercept[0:-3:])
# 截取第三个字符
print("截取第三个字符:%s" % str_intercept[2])
# 截取倒数第三位到结尾
print("截取倒数第三位到结尾:%s" % str_intercept[-3:])
# 截取倒数第三位与倒数第一之间的字符
print("截取倒数第三位与倒数第一之间的字符:%s" % str_intercept[-3:-1])
# 与原字符串顺序相反的字符串
print("与原字符串顺序相反的字符串:%s" % str_intercept[::-1])
# 逆序截取
print("逆序截取:%s" % str_intercept[:-5:-2])

● 替换:格式:字符串.replace(“被替换内容”,”替换后内容”)

使用replace替换字符串后仅为临时变量,需要重新赋值才能保存。列如:

# 字符串替换
str_replace="ABCDEFG"
# 单个内容替换
print(str_replace.replace('C','V')) #ABVDEFG
# 字符串替换
print(str_replace.replace('ABC','VNM')) #VNMDEFG
# 替换为特殊符号
print(str_replace.replace('ABC',' ')) # DEFG

● 查找:格式:字符串.find(“要查找的内容”[,开始位置,结束位置])

开始位置结束位置表示要查找的范围,若为空值,则表示查找所有。找到目标后会返回目标第一位内容所在的位置,位置从0开始,如果没有找到,就返回-1.例如:

# 字符串查找
str_find="ABCDEFG"
# 查找全部
print(str_find.find("A")) #输出0
# 从字符串第4个开始查找
print(str_find.find("D",3)) #输出3
# 从字符串第2个到第6个开始查找
print(str_find.find("E",1,5)) #输出4
# 查找不存在的内容
print(str_find.find("K")) #输出-1

除了使用find函数查找字符串中某个内容外,index函数也能实现同样的功能。index是在字符串里查找字符串第一次出现的位置,类似于字符串的find方法,如果查不到字符串,就会抛出异常,而不是返回-1。例如:

# 字符串查找
str_index="ABCDEFG"
# 查找全部
print(str_index.index("A")) #输出0
# 从字符串第4个开始查找
print(str_index.index("D",3)) #输出3
# 从字符串第2个到第6个开始查找
print(str_index.index("E",1,5)) #输出4
# 查找不存在的内容
print(str_index.index("K")) #报错:ValueError: substring not found

● 分割:格式:字符串.split(“分隔符”,分割次数)

如果存在分割次数,就仅分割成“分割次数+1”个字符串;如果为空,就默认全部分割。分割后,返回一个列表类型数据。例如:

# 字符串分割
str_split="ABCDEFGBA"
# 分割全部
print(str_split.split('B')) # 输出['A', 'CDEFG', 'A']

# 分割一次
print(str_split.split('B',1)) # 输出['A', 'CDEFGBA']

字符串操作是数据清洗的基本,可以解析HTML,但是纯字符串解析HTML会导致代码冗余,不便维护,一般不会这样使用。字符串清洗主要用于个别数据清洗,且数据具有一定的规律特性。一般常用的是替换分割

正则表达式

正则表达式适用于处理字符串的强大工具,拥有自己独特的语法及一个独立处理的引擎,效率上可能不如字符串处理方法,但是功能十分强大。在提供了正则表达式的语言里,其语法基本都是一样的,区别只在于不同编程语言实现支持的语法数量不同。

学习正则表达式主要从两个方面入手:正则语法正则处理函数

● 正则语法:也称元字符,符合正则规则,通常表示一些不寻常的匹配操作,或者通过重复、修改匹配意义来影响正则模式的其它部分。常用语法如下:

正则表达式元字符和语法:

爬虫数据清洗中一些常用的方式

正则表达式特殊序列说明:

特殊表达式序列 说明
\A 只在字符串开头进行匹配
\b 匹配位于开头或者结尾的空字符符串
\B 匹配不位于开头或者结尾的空字符串
\d 匹配任意十进制数,相当于[0-9]
\D 匹配任意非数字字符,相当于[^0-9]
\s 匹配任意空白字符,相当于[\t\n\r\f\v]
\S 匹配任意非空白字符,相当于[^\t\n\r\f\v]
\w 匹配任意数字和字母及下划线,相当于[a-zA-Z0-9_]
\W 匹配任意非数字和字母及下划线,相当于[^a-zA-Z0-9_]
\Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z 匹配字符串结束
\G 匹配最后匹配完成的位置。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。

● 正则处理函数:Python的正则模块是re,该模块含有多种正则处理函数,常用的功能函数包括:match、search、findall和sub。

re.match函数

re.match函数尝试从字符串的开头开始匹配一个模式,如果匹配成功,就返回一个匹配成功的对象,否则返回None。其基本语法如下:

re.match(pattern,string,flags=0)
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写、是否多行匹配等。
参数flags的可选值如下:
re.I (re.IGNORECASE):忽略大小写
re.M (re.MULTILINE):多行模式,改变'^'和'$'的行为
re.S (re.DOTALL):此模式下的'.'匹配不受限制,可匹配任何字符,包括换行符。
re.L (re.LOCALE):字符集本地化,为了支持多语言版本的字符集使用环境,例如转义符\w
re.U (re.UNICODE):使用预定字符类\w\W\b\B\s\S\d\D取决于unicode定义的字符属性。
re.X (re.VERBOSE):详细模式。在这个模式下,正则表达式可以是多行,忽略空白字符,并可以添加注释。

该函数匹配之后,得出一个match对象类型,如果要返回结果,可以使用group()或groups()匹配对象函数来获取匹配后的结果,例如:

import re
html="Welcome to crocodile Ba"
res=re.match('(.*) to (.*?) .*',html,re.M | re.I)
if res:
    print("res.group() :",res.group())
    print("res.group(1) :",res.group(1))
    print("res.group(2) :",res.group(2))
    print("res.groups() :",res.groups())
else:
    print("Not Match")
# res.group() : Welcome to crocodile Ba
# res.group(1) : Welcome
# res.group(2) : crocodile
# res.groups() : ('Welcome', 'crocodile')

代码中的“(.*)”,“.”代表匹配任意字符,“*”代表匹配前一个字符0次或多次,两者结合匹配出“Welcome”;在“to”后面的“(.*?).*”代表获取to后面的全部数据,其中小括号匹配结果,“.*?”用于匹配一个单词“crocondile”,而括号外的“.*”用于匹配任意字符,但不返回给匹配结果。

re.search函数

re.search函数扫描整个字符串并返回第一次成功匹配的对象,如果匹配失败,就返回None。其基本语法如下:

re.search(pattern,string,flags=0)
参数解释:
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写、是否多行匹配等。可选值与match一样

匹配结果跟re.match函数一样,使用group()groups()方法来获取。

将上面的re.match的例子修改为re.search,得出的结果是一样的。search和match的使用方法类似,以至于很多初学者混迹。两者的主要区别:re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,匹配就会失败,函数返回None
re.search匹配整个字符串,直到找到一个匹配的字符串,否则也返回None。所以说能用search就不要match!

re.findall函数

re.findall函数用于获取字符串中所有匹配的字符串,并以列表的形式返回。列表中的元素有以下几种情况:

(1)当正则表达式中含有多个圆括号时,返回的列表元素为多个字符串组成的元组,而且元组中的字符串个数与圆括号对数相同,并且字符串排放数序跟圆括号出现的顺序一致,字符串的内容与每个括号内的正则表达式相对应。

(2)当正则表达式中只带有一个圆括号时,返回的列表元素为字符串,并且该字符串的内容与括号中的正则表达式相对应。返回的列表(字符串)只是圆括号的内容,不是整个正则表达式所匹配的内容。

(3)当正则表达式中没有圆括号时,返回的列表中的字符串表示整个正则表达式匹配到的内容

其基本语法格式为:

re.findall(partten,string,flags=0)
参数解释:
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写、是否多行匹配等。可选值与match一样

匹配结果不需要使用group()和groups()获取,例如:

import re
# 当正则表达式中没有圆括号时,列表中的字符串表示整个正则表达式匹配的内容
find_value=re.findall('\w*oo\w*','aoo this woo is too')
print(find_value) # ['aoo', 'woo', 'too']
# 当正则表达式中只有一个圆括号时,列表中的元素为字符串
find_value=re.findall('.*?(\d+).*?','ias2918jsij3ae2uw821esad')
print(find_value) # ['2918', '3', '2', '821']
# 正则表达式有多个圆括号时,返回匹配成功的列表中的每一个元素都是由一次匹配成功后,正表达式中所有括号中匹配的内容组成的元组
html='https://www.e1yu.com/9841.html and other https://www.e1yu.com/'
find_value=re.findall('((w{3}\.)(\w+\.)+(com|html))',html)
print(find_value)# [('www.e1yu.com', 'www.', 'e1yu.', 'com'), ('www.e1yu.com', 'www.', 'e1yu.', 'com')]

re.sub函数

re.sub函数用于替换字符串中的匹配项,如果没有匹配的项,则返回没有匹配的字符串,其基本语法为:

re.sub(pattern,repl,string,count=0,flags=0)
参数解释:
pattern:匹配的正则表达式
repl:用于替换的字符串
string:要被替换的字符串
count:替换的次数
flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写、是否多行匹配等。可选值与match一样

匹配结果不需要使用group()和groups()方法来获取,例如:

import re
replace_str=re.sub('\d{4}$','0000','1367330772')
print(replace_str) #1367330000
replace_str=re.sub('#.*$','','name=www.e1yu.com # 鳄鱼君Ba')
print(replace_str) #name=www.e1yu.com 

其它函数

● re.split(pattern, string[, maxsplit]):用匹配pattern的子串来分割字符串。
● re.subn(pattern, repl, string[, count]):与sub()函数一样,只是返回结果是一个元组。
● re.escape(string):把字符串里除了字母和数字以外的字符都加上反斜杆。
● re.finditer(pattern, string[, flags]):搜索字符串,按顺序返回每一个匹配结果的迭代器。

BeautifulSoup

参考:BeautifulSoup

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《爬虫数据清洗中一些常用的方式》 发布于2020-06-02

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

5 + 9 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册