基于Python Scrapy爬虫改进KNN算法的网站分类系统

发布于:2022-12-23 ⋅ 阅读:(188) ⋅ 点赞:(0)

目 录
摘 要 I
Abstract II
第 1 章 绪 论 1
1.1课题的研究背景和意义 1
1.1.1目前网站分类的研究情况 1
1.1.2现有解决方案的优点与不足 1
1.1.3基于特征熵值分析的网站分类系统的设计目标 2
1.2论文的研究内容与组织结构 2
1.2.1论文的研究内容 2
1.2.2论文的组织结构 3
第 2 章 系统模块组成介绍 4
2.1系统总体架构 4
2.2爬虫模块功能和技术 6
2.3网页处理模块功能和技术 6
2.4特征提取与文本表示模块功能和技术 7
2.5分类器模块功能和技术 7
2.6本章小结 7
第 3 章 爬虫模块和页面处理模块 9
3.1爬虫模块详细设计 9
3.2页面处理模块详细设计 10
3.2.1页面内容价值分析 10
3.2.2页面处理方法 11
3.2.3一种线性时间的正文提取算法 12
3.2.4页面处理关键流程图 13
3.3本章小结 14
第 4 章 特征提取与文本特征表示模块 15
4.1特征提取技术介绍 15
4.1.1传统的卡方检验方法(CHI) 15
4.1.2传统的卡方检验方法的缺陷分析 17
4.1.3一种改进的卡方检验方法 18
4.2文本特征表示介绍 18
4.2.1体现词在文档中权重的关键因素分析 19
4.2.2TF*IDF 方法 19
4.3本章小结 20
第 5 章 KNN 分类器模块 22
5.1传统 KNN 算法介绍 22
5.2传统 KNN 算法的缺陷 22
5.3在运行速度上改进 KNN 算法 23
5.3.1传统 KNN 算法运行速度低下的原因分析 23
5.3.2用 Rocchio 算法进行预选候选类 24
5.3.3根据文本的特征集与每类特征交集再次筛选候选类 25
5.3.4建立倒排索引 25
5.3.5引入位置向量表示法来降低高维向量计算量 26
5.3.6快速 KNN 算法的系统流程 27
5.4属性熵介绍 29
5.4.1熵的定义 29
5.4.2属性熵值的意义 29
5.5在分类精度上改进 KNN 算法 29
5.5.1传统 KNN 算法分类精度低的原因分析 29
5.5.2引入共有特征个数改进相似度计算公式 30
5.5.3引入属性熵值再次改进相似度计算公式 30
5.5.4引入类别平均相似度改进在 K 邻居中各类权重公式 32
5.5.5引入类别贡献度再次改进在 K 邻居中各类权重公式 32
5.5.6高精度 KNN 算法的关键流程 33
5.6本章小结 33
第 6 章 实验测试与评价 34
6.1分类标准和训练数据 34
6.2测试结果 35
6.3本章小结 36
结 论 37
参考文献 38
致 谢 41
1.1.3基于特征熵值分析的网站分类系统的设计目标
设计目标简而言之就是:设计一个高分类速度且高分类精度的网站分类器, 分类速度目标分类速度是毫秒级,目标分类精度是大于 80%。
本设计以实用为出发点对KNN 算法的缺陷产生原因进行分析并进行对算法的改进:在特征提取上引入了基于改进的 CHI 方法使得特征提取更加合理;在 KNN 分类器运行速度的改进方面引入了 Rocchio 算法的思想和一些其他简单的思路对分类器进行速度的提升,使得新的分类器的分类速度得到大幅度提升;在 KNN 分类器分类精度的改进方面,通过在相似度计算上引入了基于属性熵值的相似度改进和基于 KNN 类别加权的改进,使得改进的 KNN 算法又在分类精度上得到了大幅度提高。
在基于上述这些改进后,搭建出了一个真正具备高效、实用的网站分类系统, 分类响应速度达到了毫秒级,分类精度在 3578 个真实测试数据中达到了 85.047%。
1.2论文的研究内容与组织结构
1.2.1论文的研究内容
本文主要研究内容为:对 KNN 算法用于网站分类的各个步骤进行缺陷分析,

引入属性熵值的概念、Rocchio 算法思想以及一些其他策略,对分类中每个步骤进行全面改进和优化,最终建立一个有实用价值的网站分类系统。
1.2.2论文的组织结构
本文内容按照下面的结构进行组织安排:
第一章绪论介绍了研究课题的背景,给出了网站分类技术的发展情况与面临的问题,阐述了现有解决方案的优点与不足,明确了研究的内容与目标。
第二章介绍了系统设计的整体架构和技术需求,以及各个模块的详细功能、涉及技术。
第三章详细介绍了系统的前两个模块的实现:爬虫模块和页面处理模块。对于页面处理模块,介绍了一种线性时间复杂度的正文提取方法,并将其应用于本设计的页面处理模块。
第四章详细介绍了特征提取与文本特征表示模块的技术实现,包括对现有特征提取办法的缺陷分析和改进,以及文本特征表示方法的介绍。
第五章详细介绍了 KNN 分类器模块的实现。从传统 KNN 算法的缺陷入手, 分别从运行速度的改进上提出 4 种办法和分类精度的改进上提出了 4 种办法,并将这些办法组合成最终的新型改进 KNN 分类器。
第六章介绍了最终的新型改进 KNN 分类器在真实网站数据集上的实验结果, 并与传统方法对比,得出本文提出的新型改进 KNN 分类器更加快速和更加准确的结论。

#!/usr/bin/env python
#-*- encoding=utf-8 -*-
import re
import os
import wx
from copy import deepcopy
import UI_Module.filedialog as filedialog
import UI_Module.cfgdialog as cfgdialog
import UI_Module.tipsdialog as tipsdialog
import CSVop_Module.CSVstream as CSVstream
from DB_Module.DBop import DBOP
from Util import Util as myutil

class ProjectFrame(wx.Frame):
	"""docstring for ProjectFrame"""
	mesghead=['[INFO]:','[ERROR]:','[WARNNING]:']
	color=['GREEN','RED','BLUE']
	pattern=re.compile('((https?://)?[^\/\.]+\.[^\/]+)\w*')
	def __init__(self):
		super(ProjectFrame, self).__init__(None,-1,'网站智能识别系统',
			size=(530,410))
		panel=wx.Panel(self,-1)
		#panel.SetBackgroundColour('#FFFFCC')
		rev=wx.StaticText(panel,-1,'网站智能识别系统v0.1',
			pos=(183,8),size=(100,30),style=wx.ALIGN_CENTER)
		font=wx.Font(18,wx.DECORATIVE,wx.ITALIC,wx.NORMAL)
		rev.SetFont(font)

		author=wx.StaticText(panel,-1,'By:李琛轩',
			pos=(350,12),size=(100,30),style=wx.ALIGN_CENTER)
		font=wx.Font(14,wx.DECORATIVE,wx.ITALIC,wx.NORMAL)
		author.SetFont(font)
		author.SetForegroundColour('GRAY')
		self.textarea=wx.TextCtrl(panel,-1,'输入网站URL,一行一个',
			pos=(143,45),size=(350,320),style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_RICH2)
		self.textarea.SetInsertionPoint(0)
		f = wx.Font(3, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
	
		logo=wx.Image('logo.jpg',wx.BITMAP_TYPE_ANY)
		logo=logo.Scale(30,28)
		bm=wx.StaticBitmap(panel,-1,wx.BitmapFromImage(logo),
			pos=(143,8))

		self.importbtn=wx.Button(panel,-1,'导入CSV',
			pos=(20,35),size=(80,30))
		self.Bind(wx.EVT_BUTTON,self.OnImportClick,self.importbtn)
		self.startbtn=wx.Button(panel,-1,'开始分析',
			pos=(20,95),size=(80,30))
		self.Bind(wx.EVT_BUTTON,self.OnStartClick,self.startbtn)

		self.statisbtn=wx.Button(panel,-1,'参数配置',
			pos=(20,155),size=(80,30))
		self.Bind(wx.EVT_BUTTON,self.OnConfigClick,self.statisbtn)

		self.statisbtn=wx.Button(panel,-1,'清空栏目',
			pos=(20,215),size=(80,30))
		self.Bind(wx.EVT_BUTTON,self.OnClearClick,self.statisbtn)

		self.outbtn=wx.Button(panel,-1,'导出结果',
			pos=(20,275),size=(80,30))
		self.Bind(wx.EVT_BUTTON,self.OnOutClick,self.outbtn)

		self.helpbtn=wx.Button(panel,-1,'使用帮助',
			pos=(20,335),size=(80,30))
		self.Bind(wx.EVT_BUTTON,self.OnHelpClick,self.helpbtn)

		self.result_set=[]

	def loadclassifier(self,dialog):
		import Spider_Module.startspider as startspider
		dialog.Update(1)
		import PageExtract_Module.startextractor as startextractor
		dialog.Update(7)
		import Classifier_Module.Filter as cfilter
		dialog.Update(8)
		import Classifier_Module.DistributekNN as knnclassifier
		dialog.Update(14)
		self.classifier=knnclassifier.main()
		self.classifier.next()
		dialog.Update(21)

	def OnStartClick(self,event):
		linesize=self.textarea.GetNumberOfLines()
		urls=[]
		for i in xrange(linesize):
			url=self.textarea.GetLineText(i)
			urls.append(url)
		self.textarea.Clear()
		
		urls=myutil.remove_duplicate(urls)
		self.process_programmer(urls)
	def display_result(self):
		if not self.result_set:return
		self.textarea.Clear()
		self.textarea.SetDefaultStyle(wx.TextAttr('BLACK'))
		for web,cateno in self.result_set:
			self.WritetoFront('%s:%s' % (web,myutil.code2catename(cateno)))
		self.statis_result()
	def process_programmer(self,urls):
		self.result_set=[];domainurls=[]
		for url in urls:
			match=self.pattern.match(url)
			if match:
				url=match.group()
				domainurls.append(url)
				self.WritetoFront('目标 %d url : %s .' % (len(domainurls),url))
			else:
				self.WritetoFront(\
					'忽略%s,因为不是url...' % url,level=2)
		if not len(domainurls):
			self.WritetoFront('没有有效URL输入!',True,1)
			return
		self.WritetoFront('开始下载网页...')
		#check if has existed
		dbapi=None
		try:
			dbapi=DBOP()
		except:
			self.WritetoFront('无法连接数据库,请检查数据库设置!',True,1)
			return
		unknown_urls,urls_known_cate=dbapi.domain(domainurls)
		noconnet_web=[]
		if unknown_urls:
			import Spider_Module.startspider as startspider
			if not startspider.check_linked():
				self.WritetoFront('无法连接网络,请检查网络库设置!',True,1)
				return
			import PageExtract_Module.startextractor as startextractor
			import Classifier_Module.Filter as cfilter
			import Classifier_Module.DistributekNN as knnclassifier
			os.chdir('Spider_Module')
			(download_path,noconnet_web)=startspider.main(unknown_urls)
			self.WritetoFront('下载成功!')
			os.chdir('../')
			parser_results=startextractor.main(download_path)
			self.WritetoFront('页面处理成功!')
			classifier_inputs,unaccess_entity=cfilter.main(parser_results)
			self.WritetoFront('页面过滤成功!')
			#startspider.clear_download()
			for test_entry in classifier_inputs:
				result=self.classifier.send(test_entry)
				self.result_set.append(result)
				self.classifier.send(None)
			self.WritetoFront('分类结束!')
		inserts=deepcopy(self.result_set)
		self.result_set.extend(urls_known_cate)
		self.display_result()
		for web in noconnet_web:
			self.WritetoFront('%s无法连接!' % web)
		dbapi.insertres(inserts)
		dbapi.byebye()
	def OnConfigClick(self,evnet):
		cfgdialog.displaycfg()	
	def OnClearClick(self,event):
		self.textarea.SetDefaultStyle(wx.TextAttr('BLACK'))
		self.textarea.Clear()
	def OnOutClick(self,event):
		filepath=filedialog.display_filedialog()
		if not filepath:return
		if filepath.endswith('.csv'):
			CSVstream.export2csv(filepath,self.result_set)
			self.WritetoFront('导出结果成功!')
		else:
			self.WritetoFront('not CSV file!')
	def OnImportClick(self,event):
		filepath=filedialog.display_filedialog()
		if not filepath:return
		if not filepath.endswith('.csv'):
			tipsdialog.display_tips('注意导入的文件必须是CSV格式')
			return
		sign,urls=CSVstream.importcsv(filepath)
		if sign:
			self.CSVtoBoard(urls)
		else:
			msg=urls
			self.WritetoFront('%s' % msg,True,1)
	def WritetoFront(self,text,clear=False,level=0):
		self.textarea.SetDefaultStyle(wx.TextAttr(self.color[level]))
		if clear:self.textarea.Clear()
		self.textarea.AppendText('%s%s\n' % (self.mesghead[level],text))
	def CSVtoBoard(self,urls):
		self.textarea.SetDefaultStyle(wx.TextAttr('BLACK'))
		self.textarea.Clear()
		for url in urls:
			self.textarea.AppendText('%s\n' % url)
	def OnHelpClick(self,event):
		import ReadMe_Module.helppage as helppage
		helppage.displayhelp()
	def statis_result(self):
		if not self.result_set:return
		results={};results_sum=len(self.result_set)
		for web,cateno in self.result_set:
			if cateno not in results:results[cateno]=0
			results[cateno]+=1
		splitline='*'*10
		self.textarea.AppendText('%s\n' % splitline)
		self.textarea.AppendText('共分析了%d个网址,其中:\n' % results_sum)
		for cateno in results:
			self.textarea.AppendText('%s:%d个\n' % (myutil.code2catename(cateno),results[cateno]))
def main():
	app=wx.PySimpleApp()
	frame=ProjectFrame()
	progressMax=21
	dialog=wx.ProgressDialog('网站智能识别系统', '加载配置...', progressMax,
		style=wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)
	frame.loadclassifier(dialog)
	dialog.Destroy()
	frame.Show()
	app.MainLoop()

if __name__ == '__main__':
	main()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到