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)))
代码执行结果如下:


   但是,从结果中可以发现,程序执行后会返回一些很有意思同时也很有用的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)))
执行结果如下图所示,结果有所改善:


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

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操作。

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


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

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值