python网络爬虫-如何编写代码清洗数据

  到目前为止,我们还没有处理过那些样式不规范的数据。我们的处理方式要么是使用样式规范的数据源,要么是称帝放弃样式不符合我们预期的数据。在网络数据采集中,由于错误的标点符号,大小写字母不一致,断行和拼写错误等问题,凌乱的数据(dirty data)是网络中的大问题。下面我们将通过技术的手段,改变代码的编写方式,帮你从源头控制数据零乱的问题,并且对已经进入数据库的数据进行清洗。

  在语言学中有一个模型叫做n-gram,表示文字或语言中的n个连续的单词组成的序列。在进行自然语言分析时,使用n-gram或者寻找常用词组,可以很容易地把一句话分解成若干个文字片段。下面我们将通过实例代码获取合理的n-gram,下面的代码将返回维基百科词条“Python Programming Language”的2-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("http://en.wikipedia.org/wiki/Python_(programming_language)")
bsObj=BeautifulSoup(html,"html.parser")
content=bsObj.find("div",{"id":"mw-content-text"}).get_text()
ngrams=ngrams(content,2)
print(ngrams)
print("2-grams count is :"+str(len(ngrams)))
代码执行结果如下:

python网络爬虫-如何编写代码清洗数据_第1张图片

   但是,从结果中可以发现,程序执行后会返回一些很有意思同时也很有用的2-gram序列: ['Software', 'Foundation']。同时也会出现一些凌乱的数据:['years', 'ago\xa0(1991-02-20)[1]\n\n\n\n\n\nStable']。下面我们通过一些正则表达式来移除转移字符(\n),再把Unicode字符过滤掉。使用下面的改进后的程序:

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

def ngrams(input,n):
    content=re.sub('\n+'," ",input)
    content=re.sub(' +'," ",content)
    content=bytes(content,"UTF-8")
    content=content.decode("ascii","ignore")
    input=content.split(' ')
    output=[]
    for i in range(len(input)-n+1):
        output.append(input[i:i+n])
    return output

html=urlopen("http://en.wikipedia.org/wiki/Python_(programming_language)")
bsObj=BeautifulSoup(html,"html.parser")
content=bsObj.find("div",{"id":"mw-content-text"}).get_text()
ngrams=ngrams(content,2)
print(ngrams)
print("2-grams count is :"+str(len(ngrams)))
执行结果如下图所示,结果有所改善:

python网络爬虫-如何编写代码清洗数据_第2张图片

但是还有一些小问题,我们继续增加下述的规则来进行数据清理:   

1. 剔除单字符的单词,除非这个字符是“i”或“a”

2. 剔除维基百科的引用标记(方括号包裹的数组,如[1])

3. 剔除标点符号(注意:这个规则其实有点过往矫正了,后续我们会就这个问题继续分析讲解)

现在,清洗任务变得越来越长,我们把规则都移除出来,单独建一个函数,取名了cleanInput,代码内容如下:

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import string

def cleanInput(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")
    cleanInput=[]
    input=input.split(' ')
    for item in input:
        item=item.strip(string.punctuation)
        if(len(item)>1) or (item.lower()=='a' or item.lower()=='i'):
            cleanInput.append(item)
    return cleanInput

def ngrams(input,n):
    input=cleanInput(input)
    output=[]
    for i in range(len(input)-n+1):
        output.append(input[i:i+n])
    return output
    
html=urlopen("http://en.wikipedia.org/wiki/Python_(programming_language)")
bsObj=BeautifulSoup(html,"html.parser")
content=bsObj.find("div",{"id":"mw-content-text"}).get_text()
ngrams=ngrams(content,2)
print(ngrams)
print("2-grams count is :"+str(len(ngrams)))
   代码中,引入了string,并使用了string.punctuation,目的是为了获取到Python所有的标点符号,并去除它们。如想要知道具体包含哪些符号,可在命令行执行print操作。

上述代码执行结果如下图所示,

python网络爬虫-如何编写代码清洗数据_第3张图片

从结果分析发现,挑选结果明显更加干净了。

你可能感兴趣的:(python网络爬虫)