当前位置: 首页 > 后端技术 > Python

爬虫系列:数据清洗

时间:2023-03-26 00:11:57 Python

上一期我们讲解了使用Python读取CSV、PDF、Word文档。前面我们介绍了网络数据采集的一些基础知识,下面我们就进入高级数据采集部分。到目前为止,我们创建的网络爬虫都不是特别强大,如果网络服务器不立即提供特定于样式的信息,爬虫将无法收集正确的数据。如果爬虫只能收集明显的信息,不加处理地存储起来,那么它迟早会被登录表单、网页交互和Javascript困住。总之,目前的爬虫还没有足够的实力收集各种数据,只能处理愿意收集的信息。高级数据收集部分是帮助您分析原始数据并获取隐藏在数据背后的故事——网站的真实故事实际上隐藏在Javascript、登录表单和网站反爬虫措施的背后。数据清洗到目前为止,我们还没有处理过不规范的数据,要么使用规范格式的数据源,要么丢弃不符合我们预期的数据。但是在网络抓取中,你通常不能对你抓取的数据的风??格太过挑剔。由于标点符号错误、大小写不一致、换行符和拼写错误等问题,脏数据是网络上的一个大问题。接下来,我们将通过工具和技术,通过改变代码的编写方式,帮助大家从源头上控制数据乱码的问题,清洗已经存入数据库的数据。编写代码清理数据就像编写异常处理代码一样,您应该学会编写预防性代码来处理意外情况。在语言学中,有一种称为n-gram的模型,它表示文本或语言中n个连续单词的序列。在进行自然语言分析时,您可以通过使用n-gram或查找常用短语轻松地将一个句子分成多个文本片段。在下文中,我们将重点关注如何获得格式良好的n-gram。以下代码返回维基百科条目“Python编程语言”的2克列表:fromutilsimportconnection_utilclassDataCleaning(object):def__init__(self):self._target_url='https://en.wikipedia.org/wiki/python_(programming_language)'self._init_connection=connection_util.ProcessConnection()@staticmethoddefngrams(input_text,n):split_result=input_text.split('')output=[]foriinrange(len(split_result)-n+1):output.append(split_result[i:i+n])returnoutputdefget_result(self):#连接到目标网站并获取内容get_content=self._init_connection.init_connection(self._target_url)ifget_content:content=获取内容。find("div",{"id":"mw-content-text"}).get_text()ngrams=self.ngrams(content,2)print(ngrams)print("2-gramscountis:"+str(len(ngrams)))if__name__=='__main__':DataCleaning().get_result()ngrams函数将待处理的字符串分成单词序列(假设所有的词都用空格隔开),然后添加到n-gram模型中,形成一个以每个词开头的二进制数组。运行程序后,会出现一些乱七八糟的数据,例如:['web','frameworks\nBottle\nCherryPy\nCubicWeb\nDjango\nFastAPI\nFlask\nGrok\nNagare\nNevow\nPylons\nPyramid\nQuixote\nTACTIC\nTornado\nTurboGears\nTwistedWeb\nWebware\nweb2py\nZope']另外,每个词(除了最后一个词)应该有Createa2-gramsequence,所以这个条目中有11680个2-gram序列。这不是一个非常易于管理的数据集!我们首先使用一些正则表达式去除转义字符(\n),然后过滤掉Unicode字符。我们可以使用下面的函数来清理之前输出的内容:)'self._init_connection=connection_util.ProcessConnection()@staticmethoddefngrams(input,n):input=re.sub('\n+',"",input)input=re.sub('+',"",输入)input=bytes(input,"UTF-8")input=input.decode("ascii","ignore")print(input)input=input.split('')output=[]foriinrange(len(input)-n+1):output.append(input[i:i+n])returnoutputdefget_result(self):#连接到目标网站并获取内容get_content=self._init_connection.init_connection(self._target_url)如果get_content:content=get_content.find("div",{"id":"mw-content-text"}).get_text()ngrams=self.ngrams(content,2)print(ngrams)print("2-gramscountis:"+str(len(ngrams)))if__name__=='__main__':DataCleaning().get_result()上面的代码首先将换行符(或多个换行符)放在content)替换为空格,然后将连续的空格替换为一个空格,确保所有单词之间只有一个空格最后,将内容转换为UTF-8格式以消除转义字符。通过以上步骤,我们已经能够大大提高输出结果,但是仍然存在一些问题:ALGOL68,[13]APL,[14]C,[15]C++,[16]CLU,[17]Dylan,[18]Haskell,[19]Icon,[20]Java,[21]Lisp,[22]Modula-3,[16]Perl,StandardML[14]InfluencedApacheGroovy因此,需要添加一些规则处理数据。我们可以自定义一些规则,让数据更加规范:去掉单字符的“words”,除非这个词是“a”或“i”;删除维基百科参考标记(方括号中的数字,输入[1])删除标点符号现在“清理任务”列表越来越长,让我们删除规则并创建一个新函数:importreimportstringdefngrams(self,input,n):input=self.clean_input(input)output=[]foriinrange(len(input)-n+1):output.append(input[i:i+n])返回output@staticmethoddefclean_input(input):input=re.sub('\n+',"",input)input=re.sub('\[[0-9]*\]',"",input)input=re.sub('+',"",input)input=bytes(input,"UTF-8")input=input.decode("ascii","ignore")input=input.split('')clean_input=[]foritemininput:#string.punctuation获取所有标点符号item=item.strip(string.punctuation)iflen(item)>1or(item.lower()=='a'oritem.lower()=='i'):clean_input.append(item)returnclean_input此处使用importstring和string.punctuation获取Python中的所有标点符号。我们可以在Python命令行查看标点符号:importstringprint(string.punctuation)!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~在循环体中使用item.strip(string.punctuation)来清除内容中的所有单词,单词两端的任何标点符号都会被删除,但是带有连字符的单词(连字符在单词内部)会stillbeReserved.本期数据清洗的内容如上,在接下来的内容中,我将讲解数据标准化以及如何清洗存储的数据,以上演示的源码托管在Gihub上,地址:https://github.com/sycct/Scra...如有问题,欢迎issue。