10011311341 吕涛、10011311356
李红
目的:通过熟悉使用火车头采集器,在网络上采取3万条笑话并进行排重,以此来熟悉web文本挖掘的一些知识。
过程:本次学习,主要分成两个部分。第一部分是笑话文本的采集,第二部分是笑话排重。以下是具体过程:
第一部分 笑话抽取
火车头采笑话基本流程:
新建分组新建任务采集网址设置采集内容设置抓数据。
一、新建分组及任务
根据需要设立“课程”分组,以便于以后学习过程中练习使用,又建立了子分组“笑话抽取”。本次采集笑话主要是两个网站“中文幽默王”及“开心驿站”,由于不同的网站html各种功能框架不同,而不同框架结构的采集规则又不同,所以将其分成了两个任务建立“开心驿站”和“中文幽默王”。如图1所示
图1 分组及任务
二、采集网址及内容规则设置
由于本次采集作为课程练习使用,所以不牵扯到发布,因此,任务编辑上面仅设置第一步“采集网址规则”和第二步“采集内容规则”,如图2所示
图2 编辑任务
下面学习过程介绍均以开心驿站为例叙述
第一步:采集网址规则
首先要先添加起始网址http://www.kxx.cc/ 接下来的笑话网址采集就分为两种方式。
第一种就是在“添加开始采集地址”窗体中设置“批量/多页”项,设置“等差数列”方式,即采集的笑话从第一页到最后一页,这些页数是成公差为1的等差数列,如图3所示
图3 批量/多页设置
将“开心驿站”上面各类笑话设置完全,效果图如图3所示
图4 起始网址效果图
当然,如果仅此设置的话,我们一页只能采到一条笑话,实际上,“开心驿站”上面的一页可以显示16条笑话,这样我们还要设置一下“多级网址采集规则”。可以手动分析页面html格式,然后填写规则,这里采用最简单的可视化Xpath方式获取地址。如图5所示
图5
Xpath方式获取地址
我们可以看出多级网址获取方式为get如图6所示
图6 多级网址设置效果图
第二种就是不在设置“批量/多页”,而是直接设置“多级网址获取”,首先获得“开心驿站”上面各个分类的默认打开地址。
例如“校园笑话”http://www.kxx.cc/xiaohua/list4-1.html,这些网址的获取,我们同样采用的是最简单的可视化地址Xpath方式获得。Xpath获得的网址里面有可能不是我们想要的网址,比如list10-1和list13-1分别为图片和视频,所以我们可以进行“结果网址过滤”如图7所示
图7 结果网址过滤设置
接下来就是“列表分页获取”设置,这个就是对每个分类的默认页进行下一页的采集,根据html里面的格式,我们如图8所示设置
图8 列表分页获取设置
至于每一页要采集到16条笑话的网址,这个就和第一种方式是一样的。就此略过。
第二步 采集内容规则
首先我们要设计自己想要的记录属性,采集笑话,需要“标题”“内容”“分类”三个属性,如图9所示内容标签定义
图9 内容标签定义
具体到各个标签的规则定义如下图10-13:
图10 前后截取方式抽取标题
图11
可视化抽取内容
需要注意的是,在内容抽取过程中可能会遇到一些html标签残留,或者是双引号,感叹号以及省略号等等不显示,这时候我们可以根据需要进行html标签排除和一些字符的替换。
图12
可视化提取分类
图13 规则测试
三、抓数据
通过以上“网址采集规则”和“内容采集规则”的设置,就可以开始任务了。经过一段时间,数据采集完成,我们可以对任务进行右单击选择“打开Data下任务文件夹”,就可以看到默认为Access的数据文件,当然也可以转换为Excel格式。由于排重的时候我们是以Excel格式进行数据输入的,所以我们将其转换为Excel格式。
第二部分 笑话排重
算法思想:本次笑话排重,主要是从内容上判断。采用MD5摘要算法,我们选取第一个句话前后7个字符进行MD5码运算,就是中文“。”和英文“.”前面4个后面两个再加本身7个字符进行MD5运算,没有中文句号和英文句号的暂时定为不重复。然后对比比每条笑话的前七个字符的MD5码。根据“select
*,count(distinct Md5)from mo1 group by Md5”将和现有的笑话重复的笑话排除掉。
算法描述:MD5对以512位为单位的输入进行变换最终以32位为单位4个的压缩信息组输出。根据运算结果的唯一性,我们可以每条笑话的第一个句号的前7个字符进行相同MD5运算,比对之后进行确认是否相同。
MD5过程描述如图14
图14 MD5过程
算法实现:
1、input
import MySQLdb
import xlrd
conn = MySQLdb.connect(host='localhost' , user = 'root'
,passwd='root' ,db = 'joke' ,use_unicode=True
,charset='utf8')
cursor = conn.cursor()
data = xlrd.open_workbook('E:\joke1.xls')
table = data.sheets()[0]
cursor.execute("select *,count(distinct Md5)from mo1 group by
Md5;")
rows = cursor.fetchall()
for row in rows:
k = row[0]
a =
int(table.cell(k,0).value)
b =
table.cell(k,1).value
c =
table.cell(k,2).value
d =
table.cell(k,3).value
e =
table.cell(k,4).value
f =
table.cell(k,5).value
g =
table.cell(k,6).value
sql = "INSERT INTO jo1
values(%s,%s,%s,%s,%s,%s,%s)"
cursor.execute(sql,(a,b,c,d,e,f,g))
cursor.close()
conn.commit()
2、MD5算法代码实现
# -*- coding: UTF-8 -*-
import xlrd
import re
import hashlib
import MySQLdb
data = xlrd.open_workbook('E:\joke1.xls')
table = data.sheets()[0]
conn = MySQLdb.connect(host='localhost' , user = 'root'
,passwd='root' ,db = 'joke' ,use_unicode=True
,charset='utf8')
cursor = conn.cursor()
for n in range(1,table.nrows):
a =
table.cell(n,4).value
print n
md
=''
for i in
range(len(a)):
s = ''
if a[i] == u'.':
a[i]
if i ==
len(a)-1:
j = len(a)
elif i ==
len(a)-2:
j = len(a)
else:
j = i+3
for k in
range(j-7,j):
s = s+a[k]
m =
hashlib.md5(s.encode("utf8"))
md =
m.hexdigest()
break
elif a[i] == u'。':
a[i]
if i ==
len(a)-1:
j = len(a)
elif i ==
len(a)-2:
j = len(a)
else:
j = i+3
for k in
range(j-7,j):
s = s+a[k]
m =
hashlib.md5(s.encode("utf8"))
md =
m.hexdigest()
break
if md == '':
md = str(n)
sql = "INSERT INTO mo1
values(%s,%s)"
cursor.execute(sql,(n,md))
cursor.close()
conn.commit()
报告总结
本次课程作业进行过程当中,遇到了很多问题,有些解决了有些目前还没有,火车头是门学问,各种规则的书写学习路还很漫长,在以后的学习过程中慢慢积累经验。
排重的算法上也还有不足,在今后的学习当中应该再接再厉。
总之,本次课程学习,学到了很多东西。特别是在学习方法上,自己吃不透的地方可以向别人请教,可以通过别的渠道获取知识。学习是个任道重远的事情,自己的能力也有触及不到的地方,日后的工作也会更多的依赖团队的合作,所以,要更加注重合作的重要性。