共计 3881 个字符,预计需要花费 10 分钟才能阅读完成。
上一期咱们解说了应用 Python 读取 CSV、PDF、Word 文档相干内容。
后面咱们曾经介绍了网络数据采集的一些基础知识,当初咱们将进入 高级数据采集 局部。到目前为止,咱们创立的网络爬虫都不是特地给力,如果网络服务器不能立刻提供款式标准的信息,爬虫就不能采集正确的数据。如果爬虫只能采集那些不言而喻的信息,不通过解决就存储起来,那么迟早要被登录表单、网页交互以及 Javascript 困住手脚。总之,目前爬虫还没有足够的实力去采集各种数据,只能解决那些违心被采集的信息。
在 高级数据采集 局部就是要帮你剖析原始数据,获取暗藏在数据背地的故事——网站的实在故事其实都暗藏在 Javascript、登录表单和网站反爬措施背地。
数据荡涤
到目前为止,咱们都没有解决过那些款式不标准的数据,要么应用的是款式标准的数据源,要么就是放弃款式不合乎咱们预期的数据。但在网络数据采集中,你通常无奈对采集的数据款式太挑剔。
因为谬误的标点符号、大小写字母不统一、断行和拼写错误等问题,凌乱的数据(dirty data)是网络中的大问题。上面咱们就通过工具和技术,通过扭转代码的编写形式,帮你从源头控制数据凌乱的问题,并且对曾经入库的数据经行荡涤。
编写代码荡涤数据
和编写异样解决代码一样,你应该学会编写预防型代码来解决意外状况。
在语言学中有一个模型叫 n-gram,示意文本或语言中的 n 个间断的单词组成的序列。再进行自然语言剖析时,用 n-gram 或者寻找罕用词组,就能够很容易的把一句话分成若干个文字片段。
在接下来的内容咱们将重点介绍如何获取格局正当的 n-gram。
上面的代码返回维基百科词条“Python programming language”的 2-gram 列表:
from utils import connection_util
class DataCleaning(object):
def __init__(self):
self._target_url = 'https://en.wikipedia.org/wiki/python_(programming_language)'
self._init_connection = connection_util.ProcessConnection()
@staticmethod
def ngrams(input_text, n):
split_result = input_text.split(' ')
output = []
for i in range(len(split_result) - n + 1):
output.append(split_result[i:i + n])
return output
def get_result(self):
# 连贯指标网站,获取内容
get_content = self._init_connection.init_connection(self._target_url)
if get_content:
content = get_content.find("div", {"id": "mw-content-text"}).get_text()
ngrams = self.ngrams(content, 2)
print(ngrams)
print("2-grams count is:" + 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']
另外,应为每个单词(除了最初一个单词)都要创立一个 2-gram 序列,所以这个词条里共有 11680 个 2-gram 序列。这并不是一个十分便于管理的数据集!
咱们首先应用一些正则表达式来移除转义字符(\n), 再把 Unicode 字符过滤掉。咱们能够通过上面的函数对之前输入的内容经行清理:
import re
from utils import connection_util
class DataCleaning(object):
def __init__(self):
self._target_url = 'https://en.wikipedia.org/wiki/python_(programming_language)'
self._init_connection = connection_util.ProcessConnection()
@staticmethod
def ngrams(input, n):
input = re.sub('\n+', " ", input)
input = re.sub('+', " ", input)
input = bytes(input, "UTF-8")
input = input.decode("ascii", "ignore")
print(input)
input = input.split(' ')
output = []
for i in range(len(input) - n + 1):
output.append(input[i:i + n])
return output
def get_result(self):
# 连贯指标网站,获取内容
get_content = self._init_connection.init_connection(self._target_url)
if get_content:
content = get_content.find("div", {"id": "mw-content-text"}).get_text()
ngrams = self.ngrams(content, 2)
print(ngrams)
print("2-grams count is:" + str(len(ngrams)))
if __name__ == '__main__':
DataCleaning().get_result()
下面的代码首先将内容中的换行符(或者多个换行符)替换成空格,而后把间断的多个空格替换成一个空格,确保所有单词之间只有一个空格。最初,把内容转换成 UTF-8 格局以打消转义字符。
通过下面的几步,咱们曾经能够大大改善输入后果了,然而还是有一些问题:
ALGOL 68,[13] APL,[14] C,[15] C++,[16] CLU,[17] Dylan,[18] Haskell,[19] Icon,[20] Java,[21] Lisp,[22] Modula-3,[16] Perl, Standard ML[14]InfluencedApache Groovy
因而,须要减少一些规定来解决数据。咱们能够定制一些规定让数据变得更标准:
- 剔除单字符的“单词”,除非这个单词是“a”或“i”;
- 剔除维基百科的援用标记(方括号包裹的数字,入[1])
- 剔除标点符号
当初“荡涤工作”列表变得越来越长,让咱们把规定都移出来,新建一个函数:
import re
import string
def ngrams(self, input, n):
input = self.clean_input(input)
output = []
for i in range(len(input) - n + 1):
output.append(input[i:i + n])
return output
@staticmethod
def clean_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 = []
for item in input:
# string.punctuation 获取所有的标点符号
item = item.strip(string.punctuation)
if len(item) > 1 or (item.lower() == 'a' or item.lower() == 'i'):
clean_input.append(item)
return clean_input
这里用 import string 和 string.punctuation 来获取 Python 所有的标点符号。咱们能够在 Python 命令行外面查看标点符号有哪些:
import string
print(string.punctuation)
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
在循环体中用 item.strip(string.punctuation)
对内容中的所有单词进行荡涤,单词两端的任何标点符号都会被去掉,但带连字符的单词(连字符在单词外部)任然会保留。
本期对于数据荡涤就是如上内容,在接下来的内容中我会解说数据标准化,以及存储的数据如何荡涤。
以上的演示源代码托管于 Gihub,地址:https://github.com/sycct/Scra…
如果有任何问题,欢送大家 issue。