Python清洗数据

/ 0评 / 0

    之前在采集的时候我曾经遇到过一个问题:一旦传输过来的页面不能提供样式规范的信息我就变得束手无策(比如Bilibli的主页,百度的主页,采用js动态生成我就彻底没有办法了)但是如果创建的爬虫只能采集那些显而易见的信息,不经过任何处理就存储起来,那怕是要被前面所说的js或者登陆表单、网页交互这些东西彻底困住,也就是说我前面所写的那些程序只能采集那些对爬虫友好的信息。

尝试清洗数据

    之前的数据由于我刻意的选择,基本上都是css固定化严重(也就是非常符合编码规范的一些网页),其中也遇到一些问题:由于错误的标点符号、大小写、断行、拼写错误这些个问题导致一些非常凌乱的数据出现,这个时候书本和网络指了一条明路:

    在语言学当中有一个模型叫做n-gram,表示文字或者语言当中的n个连续单词组成的序列,在进行自然语言分析的时候,使用n-gram或者寻找常用词组,可以很容易的把一段话分解成若干个文字片段。

from urllib.request import urlopen
from bs4 import BeautifulSoup
def ngrams(input, n):
    input = input.split(' ')
    output = []
    for i in range(len(input) - n + 1):
        output.append(input[i:i + n])
    return output
html = urlopen("https://baike.baidu.com/item/Python")
bsObj = BeautifulSoup(html,"html.parser")
content = bsObj.find("div", {"class":"main-content"}).get_text()
ngrams = ngrams(content, 2)
print(ngrams)
print("2-grams count is: "+str(len(ngrams)))

    ngrams函数把一个待处理的字符串分成单词序列,然后增加到n-grams模型里形成以每个单词开始的二元数组。当然上面的这段代码可以生成一些序列但同时也会有些凌乱的数据:


    显然得想办法过滤掉\n和Unicode字符:

content = re.sub('\n+', " ", content)
content = re.sub(' +', " ", content)
content = bytes(content, "UTF-8")
content = content.decode("UTF-8", "ignore")

上面的程序是先将\n转换为空格,然后把连续的多个空格转换为一个空格,确保单词之间只有一个空格,最后再转成UTF-8的格式字符。

    但是此刻还有一个问题就是上面的字典当中还有百度百科的标签(说白了就是强迫症)

content = re.sub('\[[0-9]*\]', "", content)

     这样一来数据就非常干净了。

数据标准化

    这里概念就比较宽泛了,而定义也比较活跃。标准化的标准十分多变,也是视具体情况而言,其中涵盖Min-Max、Z-score、Decimal scaling小数定标标准化,对于这一情况请参考 数据标准化-百科词条,而在这篇博客里标准化作为参考内容,就如上文的去\n以及去除百度的索引标签数字之类,也有可能要用的去除重复排序之类:python当中的字典是无序的,并不能像数组一样直接对n-grams序列频率进行排序,而字典内部的元素位置也不是固定的,排序之后再次使用还是会变化,除非把排序过的字典里的值复制到其他类型中进行排序。在python的collections库里就有一个orderedDict可以解决这个问题:

from collections import OrderedDict
...
ngrams = ngrams(content, 2)
ngrams = OrderedDict(sorted(ngrams.items(), key=lambda t: t[1], reverse=True))
print(ngrams)

     上面的程序段中有sorted的使用,是python 的排序函数(https://docs.python.org/3/howto/sorting.html)把序列频率转化为orderedDict对象,再按照频率排序。

先存储再清洗

    在编写代码的同时加入 数据清洗或者规定一些常用的不反人类的标准,但其实大多情况下在处理数据的时候是采集完成之后来对数据进行二次处理,或者有时你接手了其他人的数据 。这样在清洗的时候我们的第一反应就是获取数据->处理数据->返回结果。这样一来就成了再写一次脚本或者程序来完成这件事情。但是也发现了一些比较强大的第三方工具:OpenRefine

    openRefine的安装和使用(引用自网友)

其中也有 许多关于单元格编辑和GERL数据变换的方法:详细请戳:OpenRefine的Github

    

    

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注