第二部分 高级数据采集
这部分内容就是要帮你分析原始数据,获取隐藏在数据背后的故事——网站的真实故事其实都隐藏在 JavaScript、登录表单和网站反抓取措施的背后。
通过这部分内容的学习,你将掌握如何用网络爬虫测试网站,自动化处理,以及通过更多的方式接入网络。最后你将学到一些数据采集的工具,帮助你在不同的环境中收集和操作任意类型的网络数据,深入互联网的每个角落。
第7章 数据清洗
本章将介绍一些工具和技术,通过改变代码的编写方式,帮你从源头控制数据零乱的问题,并且对已经进入数据库的数据进行清洗。
7.1 编写代码清洗数据
介绍如何获取格式合理的 n-gram
from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import string
def cleanSentence(sentence):
"""
在循环体中用 item.strip(string.punctuation) 对内容中的所有单词进行清洗
单词两端的任何标点符号都会被去掉
但带连字符的单词(连字符在单词内部)仍然会保留
剔除单字符的“单词”,除非这个字符是“i”或“a”
"""
sentence = sentence.split(' ')
sentence = [word.strip(string.punctuation+string.whitespace) for word in sentence]
sentence = [word for word in sentence if len(word) > 1 or (word.lower() == 'a' or word.lower() == 'i')]
return sentence
def cleanInput(content):
"""
忽略字母大小写的区别
用正则表达式来移除转义字符(\n),
把内容转换成 UTF-8 格式以消除转义字符
再把 Unicode 字符过滤掉
"""
content = content.upper()
content = re.sub('\n|[[\d+\]]', ' ', content)
content = bytes(content, "UTF-8")
content = content.decode("ascii", "ignore")
sentences = content.split('. ')
return [cleanSentence(sentence) for sentence in sentences]
def getNgramsFromSentence(content, n):
"""
ngrams 函数把一个待处理的字符串分成单词序列(假设所有单词按照空格分开),
然后增加到 n-gram 模型(本例中是 2-gram)里形成以每个单词开始的二元数组。
"""
output = []
for i in range(len(content)-n+1):
output.append(content[i:i+n])
return output
def getNgrams(content, n):
content = cleanInput(content)
ngrams = []
for sentence in content:
ngrams.extend(getNgramsFromSentence(sentence, n))
return(ngrams)
html = urlopen('http://en.wikipedia.org/wiki/Python_(programming_language)')
bs = BeautifulSoup(html, 'html.parser')
content = bs.find('div', {'id':'mw-content-text'}).get_text()
print(len(getNgrams(content, 2)))
from collections import Counter
def getNgrams(content, n):
"""
统计每个词组出现的次数
"""
content = cleanInput(content)
ngrams = Counter()
ngrams_list = []
for sentence in content:
newNgrams = [' '.join(ngram) for ngram in getNgramsFromSentence(sentence, n)]
ngrams_list.extend(newNgrams)
ngrams.update(newNgrams)
return(ngrams)
print(getNgrams(content, 2))
7.2 数据存储后再清洗
OpenRefine 不仅可以快速简单地清理数据,还可以让非编程人员轻松地看见和使用你的数据。
使用 OpenRefine 可以数据执行筛选、排序、变换或删除等操作。
筛选 数据筛选可以通过两种方法实现:过滤器(filter)和切片器(facet)。
过滤器可以用正则表达式筛选数据,通过操作框轻松地组合、编辑和增加数据,还可以和切片器配合使用。
切片器可以很方便地对一列的部分数据进行包含和不包含的筛选。它们都有内置的筛选工具。例如,数值筛选功能会为你提供一个数值滑动窗口,让你选择需要的数值区间。
经过选过的数据结果可以被导成任意一种 OpenRefine 支持的数据文件格式,包括 CSV、 HTML(HTML 表格)、Excel 以及其他格式。
清洗 只有当数据一开始就比较干净时,数据筛选才可以直接快速地完成。
OpenRefine 的数据变换功能是通过 OpenRefine 表达式语言(Expression Language)实现的,被称为 GREL(“G”是 OpenRefine 之前的名字 GoogleRefine)。这个语言通过创建规则简单的 lambda 函数来实现数据的转换。例如:
if(value.length() != 4, "invalid", value)
OpenRefine 还有许多关于单元格编辑和 GERL 数据变换的方法。详细介绍在 OpenRefine 的 GitHub 页面。