前面讲述了很多关于Python爬取本体Ontology、消息盒InfoBox、虎扑图片等例子,同时讲述了VSM向量空间模型的应用。但是由于InfoBox没有前后文和语义概念,所以效果不是很好,这篇文章主要是爬取百度5A景区摘要信息,再利用Jieba分词工具进行中文分词,最后提出文本聚类算法的一些概念知识。
相关文章:
[Python爬虫] Selenium获取百度百科旅游景点的InfoBox消息盒
[python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈
Python简单实现基于VSM的余弦相似度计算
基于VSM的命名实体识别、歧义消解和指代消解
[python爬虫] Selenium定向爬取PubMed生物医学摘要信息
简单给出Selenium爬取百度百科5A级景区的代码:
# coding=utf-8 """ Created on 2015-12-10 @author: Eastmount """ import time import re import os import sys import codecs import shutil from selenium import webdriver from selenium.webdriver.common.keys import Keys import selenium.webdriver.support.ui as ui from selenium.webdriver.common.action_chains import ActionChains #Open PhantomJS driver = webdriver.PhantomJS(executable_path="G:\phantomjs-1.9.1-windows\phantomjs.exe") #driver = webdriver.Firefox() wait = ui.WebDriverWait(driver,10) #Get the Content of 5A tourist spots def getInfobox(entityName, fileName): try: #create paths and txt files print u'文件名称: ', fileName info = codecs.open(fileName, 'w', 'utf-8') #locate input notice: 1.visit url by unicode 2.write files #Error: Message: Element not found in the cache - # Perhaps the page has changed since it was looked up #解决方法: 使用Selenium和Phantomjs print u'实体名称: ', entityName.rstrip('\n') driver.get("http://baike.baidu.com/") elem_inp = driver.find_element_by_xpath("//form[@id='searchForm']/input") elem_inp.send_keys(entityName) elem_inp.send_keys(Keys.RETURN) info.write(entityName.rstrip('\n')+'\r\n') #codecs不支持'\n'换行 #load content 摘要 elem_value = driver.find_elements_by_xpath("//div[@class='lemma-summary']/div") for value in elem_value: print value.text info.writelines(value.text + '\r\n') #爬取文本信息 #爬取所有段落<div class='para'>的内容 class='para-title'为标题 [省略] time.sleep(2) except Exception,e: #'utf8' codec can't decode byte print "Error: ",e finally: print '\n' info.close() #Main function def main(): #By function get information path = "BaiduSpider\\" if os.path.isdir(path): shutil.rmtree(path, True) os.makedirs(path) source = open("Tourist_spots_5A_BD.txt", 'r') num = 1 for entityName in source: entityName = unicode(entityName, "utf-8") if u'故宫' in entityName: #else add a '?' entityName = u'北京故宫' name = "%04d" % num fileName = path + str(name) + ".txt" getInfobox(entityName, fileName) num = num + 1 print 'End Read Files!' source.close() driver.close() if __name__ == '__main__': main()内容如下图所示,共204个国家5A级景点的摘要信息。这里就不再叙述:
Python中分分词工具很多,包括盘古分词、Yaha分词、Jieba分词等。
中文分词库:http://www.oschina.net/project/tag/264/segment
其中它们的基本用法都相差不大,但是Yaha分词不能处理如“黄琉璃瓦顶”或“圜丘坛”等词,所以使用了结巴分词。
1.安装及入门介绍
参考地址:http://www.oschina.net/p/jieba
下载地址:https://pypi.python.org/pypi/jieba/
Python 2.0我推荐使用"pip install jieba"或"easy_install jieba"全自动安装,再通过import jieba来引用(第一次import时需要构建Trie树,需要等待几秒时间)。
安装时如果出现错误"unknown encoding: cp65001",输入"chcp 936"将编码方式由utf-8变为简体中文gbk。
#encoding=utf-8 import jieba #全模式 text = "我来到北京清华大学" seg_list = jieba.cut(text, cut_all=True) print u"[全模式]: ", "/ ".join(seg_list) #精确模式 seg_list = jieba.cut(text, cut_all=False) print u"[精确模式]: ", "/ ".join(seg_list) #默认是精确模式 seg_list = jieba.cut(text) print u"[默认模式]: ", "/ ".join(seg_list) #新词识别 “杭研”并没有在词典中,但是也被Viterbi算法识别出来了 seg_list = jieba.cut("他来到了网易杭研大厦") print u"[新词识别]: ", "/ ".join(seg_list) #搜索引擎模式 seg_list = jieba.cut_for_search(text) print u"[搜索引擎模式]: ", "/ ".join(seg_list)输出如下图所示:
#encoding=utf-8 import jieba #导入自定义词典 jieba.load_userdict("dict.txt") #全模式 text = "故宫的著名景点包括乾清宫、太和殿和黄琉璃瓦等" seg_list = jieba.cut(text, cut_all=True) print u"[全模式]: ", "/ ".join(seg_list) #精确模式 seg_list = jieba.cut(text, cut_all=False) print u"[精确模式]: ", "/ ".join(seg_list) #搜索引擎模式 seg_list = jieba.cut_for_search(text) print u"[搜索引擎模式]: ", "/ ".join(seg_list)输出结果如下所示,其中专有名词连在一起,即"乾清宫"和"黄琉璃瓦"。
#encoding=utf-8 import jieba import jieba.analyse #导入自定义词典 jieba.load_userdict("dict.txt") #精确模式 text = "故宫的著名景点包括乾清宫、太和殿和午门等。其中乾清宫非常精美,午门是紫禁城的正门,午门居中向阳。" seg_list = jieba.cut(text, cut_all=False) print u"分词结果:" print "/".join(seg_list) #获取关键词 tags = jieba.analyse.extract_tags(text, topK=3) print u"关键词:" print " ".join(tags)输出结果如下,其中"午门"出现3次、"乾清宫"出现2次、"著名景点"出现1次,按照顺序输出提取的关键词。如果topK=5,则输出:"午门 乾清宫 著名景点 太和殿 向阳"。
>>> 分词结果: 故宫/的/著名景点/包括/乾清宫/、/太和殿/和/午门/等/。/其中/乾清宫/非常/精美/,/午门/是/紫禁城/的/正门/,/午门/居中/向阳/。 关键词: 午门 乾清宫 著名景点 >>>
#encoding=utf-8 import sys import re import codecs import os import shutil import jieba import jieba.analyse #导入自定义词典 jieba.load_userdict("dict_baidu.txt") #Read file and cut def read_file_cut(): #create path path = "BaiduSpider\\" respath = "BaiduSpider_Result\\" if os.path.isdir(respath): shutil.rmtree(respath, True) os.makedirs(respath) num = 1 while num<=204: name = "%04d" % num fileName = path + str(name) + ".txt" resName = respath + str(name) + ".txt" source = open(fileName, 'r') if os.path.exists(resName): os.remove(resName) result = codecs.open(resName, 'w', 'utf-8') line = source.readline() line = line.rstrip('\n') while line!="": line = unicode(line, "utf-8") seglist = jieba.cut(line,cut_all=False) #精确模式 output = ' '.join(list(seglist)) #空格拼接 print output result.write(output + '\r\n') line = source.readline() else: print 'End file: ' + str(num) source.close() result.close() num = num + 1 else: print 'End All' #Run function if __name__ == '__main__': read_file_cut()运行结果如下图所示:
#encoding=utf-8 import jieba #去除停用词 stopwords = {}.fromkeys(['的', '包括', '等', '是']) text = "故宫的著名景点包括乾清宫、太和殿和午门等。其中乾清宫非常精美,午门是紫禁城的正门。" segs = jieba.cut(text, cut_all=False) final = '' for seg in segs: seg = seg.encode('utf-8') if seg not in stopwords: final += seg print final #输出:故宫著名景点乾清宫、太和殿和午门。其中乾清宫非常精美,午门紫禁城正门。 seg_list = jieba.cut(final, cut_all=False) print "/ ".join(seg_list) #输出:故宫/ 著名景点/ 乾清宫/ 、/ 太和殿/ 和/ 午门/ 。/ 其中/ 乾清宫/ 非常/ 精美/ ,/ 午门/ 紫禁城/ 正门/ 。
这部分主要参考2008年上海交通大学姚清坛等《基于向量空间模型的文本聚类算法》的论文,因为我的实体对齐使用InfoBox存在很多问题,发现对齐中会用到文本内容及聚类算法,所以简单讲述下文章一些知识。