python基于搜索引擎实现文章查重功能

python基于搜索引擎实现文章查重功能

2023年7月9日发(作者:)

python基于搜索引擎实现⽂章查重功能前⾔⽂章抄袭在互联⽹中普遍存在,很多博主都收受其烦。近⼏年随着互联⽹的发展,抄袭等不道德⾏为在互联⽹上愈演愈烈,甚⾄复制、黏贴后发布标原创屡见不鲜,部分抄袭后的⽂章甚⾄标记了⼀些联系⽅式从⽽使读者获取源码等资料。这种恶劣的⾏为使⼈愤慨。本⽂使⽤搜索引擎结果作为⽂章库,再与本地或互联⽹上数据做相似度对⽐,实现⽂章查重;由于查重的实现过程与⼀般情况下的微博情感分析实现流程相似,从⽽轻易的扩展出情感分析功能(下⼀篇将在此篇代码的基础上完成数据采集、清洗到情感分析的整个过程)。由于近期时间上并不充裕,暂时实现了主要功能,细节上并没有进⾏优化,但是在代码结构上进⾏了⼀些简要的设计,使得之后的功能扩展、升级更为简便。我本⼈也将会持续更新该⼯具的功能,争取让这个⼯具在技术上更加的成熟、实⽤。技术本⽂实现的查重功能为了考虑适配⼤多数站点,从⽽使⽤selenium⽤作数据获取,配置不同搜索引擎的信息,实现较为通⽤的搜索引擎查询,并且不需要考虑过多的动态数据抓取;分词主要使⽤jieba库,完成对中⽂语句的分词;使⽤余弦相似度完成⽂本相似度的对⽐并导出对⽐数据⾄Excel⽂章留作举报信息。微博情感分析基于sklearn,使⽤朴素贝叶斯完成对数据的情感分析;在数据抓取上,实现流程与⽂本查重的功能类似。测试代码获取环境作者的环境说明如下:操作系统:Windows7 SP1 64python 版本:3.7.7浏览器:⾕歌浏览器浏览器版本: 80.0.3987 (64 位)如有错误欢迎指出,欢迎留⾔交流。⼀、实现⽂本查重1.1 selenium安装配置由于使⽤的selenium,在使⽤前需要确保读者是否已安装selenium,使⽤pip命令,安装如下:pip install selenium安装完成 Selenium 还需要下载⼀个驱动。⾕歌浏览器驱动:驱动版本需要对应浏览器版本,不同的浏览器使⽤对应不同版本的驱动,点击下载如果是使⽤⽕狐浏览器,查看⽕狐浏览器版本,点击下载(英⽂不好的同学右键⼀键翻译即可,每个版本都有对应浏览器版本的使⽤说明,看清楚下载即可)安装了selenium后新建⼀python⽂件名为selenium_search,先在代码中引⼊from selenium import webdriver可能有些读者没有把驱动配置到环境中,接下来我们可以指定驱动的位置(博主已配置到环境中):driver = (executable_path=r'F:pythondrchromedriver_')新建⼀个变量url赋值为百度⾸页链接,使⽤get⽅法传⼊url地址,尝试打开百度⾸页,完整代码如下:from selenium import webdriverurl=''driver=()(url)在⼩⿊框中使⽤命令⾏运⾏python⽂件(windows下):运⾏脚本后将会打开⾕歌浏览器并跳转⾄百度⾸页:这样就成功使⽤selenium打开了指定⽹址,接下来将指定搜索关键词查询得到结果,再从结果中遍历到相似数据。1.2 selenium百度搜索引擎关键词搜索在⾃动操控浏览器进⾏关键字键⼊到搜索框前,需要获取搜索框元素对象。使⽤⾕歌浏览器打开百度⾸页,右键搜索框选择查看,将会弹出⽹页元素(代码)查看视窗,找到搜索框元素(使⽤⿏标在元素节点中移动,⿏标当前位置的元素节点将会对应的在⽹页中标蓝):在html代码中,id的值⼤多数情况下唯⼀(除⾮是打错了),在此选择id作为获取搜索框元素对象的标记。selenium提供了find_element_by_id⽅法,可以通过传⼊id获取到⽹页元素对象。input=_element_by_id('kw')获取元素对象后,使⽤send_keys⽅法可传⼊需要键⼊的值:_keys('php基础教程 第⼗⼀步 ⾯向对象')在此我传⼊了 “php基础教程 第⼗⼀步 ⾯向对象”作为关键字作为搜索。运⾏脚本查看是否在搜索框中键⼊了关键字。代码如下:_keys('php基础教程 第⼗⼀步 ⾯向对象')成功打开浏览器并键⼊了搜索关键字:现在还差点击“百度⼀下”按钮完成最终的搜索。使⽤与查看搜索框相同的元素查看⽅法查找“百度⼀下”按钮的id值:使⽤find_element_by_id⽅法获取到该元素对象,随后使⽤click⽅法使该按钮完成点击操作:search_btn=_element_by_id('su')search_()完整代码如下:from selenium import webdriverurl=''driver=()(url)input=_element_by_id('kw')_keys('php基础教程 第⼗⼀步 ⾯向对象')search_btn=_element_by_id('su')search_()浏览器⾃动完成了键⼊搜索关键字及搜索功能:1.3 搜索结果遍历当前已在浏览器中得到了搜索结果,接下来需要获取整个web页⾯内容,得到搜索结果。使⽤selenium并不能很⽅便的获取到,在这⾥使⽤BeautifulSoup对整个web页⾯进⾏解析并获取搜索结果。BeautifulSoup是⼀个HTML/XML解析器,使⽤BeautifulSoup会极⼤的⽅便我们对整个html的信息获取。使⽤BeautifulSoup前需确保已安装。安装命令如下:pip install BeautifulSoup安装后,在当前python⽂件头部引⼊:from bs4 import BeautifulSoup获取html⽂本可以调⽤page_source即可:html=_source得到了html代码后,新建BeautifulSoup对象,传⼊html内容并且指定解析器,这⾥指定使⽤ 解析器:soup = BeautifulSoup(html, "")接下来查看搜索内容,发现所有的结果都由⼀个h标签包含,并且class为t:BeautifulSoup提供了select⽅法对标签进⾏获取,⽀持通过类名、标签名、id、属性、组合查找等。我们发现百度搜索结果中,结果皆有⼀个class =“t”,此时可以通过类名进⾏遍历获取最为简便:search_res_list=('.t')在select⽅法中传⼊类名t,在类名前加上⼀个点(.)表⽰是通过类名获取元素。完成这⼀步后可以添加print尝试打印出结果:print(search_res_list)⼀般情况下,可能输出search_res_list为空列表,这是因为我们在浏览器解析数据渲染到浏览器前已经获取了浏览器当前页的内容,这时有⼀个简单的⽅法可以解决这个问题,但是此⽅法效率却不⾼,在此只是暂时使⽤,之后将会⽤其它效率⾼于此⽅法的代码替换(使⽤time需要在头部引⼊):(2)完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupimport timeurl=''driver=()(url)input=_element_by_id('kw')_keys('php基础教程 第⼗⼀步 ⾯向对象')search_btn=_element_by_id('su')search_()(2)#在此等待 使浏览器解析并渲染到浏览器html=_source #获取⽹页内容soup = BeautifulSoup(html, "")search_res_list=('.t')print(search_res_list)运⾏程序将会输出内容:获取到的结果为所有class为t的标签,包括该标签的⼦节点,并且使⽤点(.)运算发可以获取⼦节点元素。通过浏览器得到的搜索内容皆为链接,点击可跳转,那么只需要获取每⼀个元素下的a标签即可:for el in search_res_list: print(el.a)从结果中很明显的看出搜索结果的a标签已经获取,那么接下来我们需要的是提取每个a标签内的href超链接。获取href超链接直接使⽤列表获取元素的⽅式获取即可:for el in search_res_list: print(el.a['href'])运⾏脚本成功得到结果:细⼼的读者可能会发现,这些获取到的结果中,都是baidu的⽹址。其实这些⽹址可以说是“索引”,通过这些索引再次跳转到真实⽹址。由于这些“索引”不⼀定会变动,并不利于长期存储,在此还是需要获取到真实的链接。我们调⽤js脚本对这些⽹址进⾏访问,这些⽹址将会跳转到真实⽹址,跳转后再获取当前的⽹址信息即可。调⽤execute_script⽅法可执⾏js代码,代码如下:for el in search_res_list: js = '("'+el.a['href']+'")' e_script(js)打开新的⽹页后,需要获取新⽹页的句柄,否则⽆法操控新⽹页。获取句柄的⽅法如下:handle_this=t_window_handle#获取当前句柄handle_all=_handles#获取所有句柄获取句柄后需要把当前操作的对象切换成新的页⾯。由于打开⼀个页⾯后所有页⾯只有2个,简单的使⽤遍历做⼀个替换:handle_exchange=None#要切换的句柄for handle in handle_all:#不匹配为新句柄 if handle != handle_this:#不等于当前句柄就交换 handle_exchange = _(handle_exchange)#切换切换后,操作对象为当前刚打开的页⾯。通过current_url属性拿到新页⾯的url:real_url=t_urlprint(real_url)随后关闭当前页⾯,把操作对象置为初始页⾯:()_(handle_this)#换回最初始界⾯运⾏脚本成功获取到真实url:最后在获取到真实url后使⽤⼀个列表将结果存储:real_url_(real_url)这⼀部分完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupimport timeurl=''driver=()(url)input=_element_by_id('kw')_keys('php基础教程 第⼗⼀步 ⾯向对象')search_btn=_element_by_id('su')search_()(2)#在此等待 使浏览器解析并渲染到浏览器html=_sourcesoup = BeautifulSoup(html, "")search_res_list=('.t')real_url_list=[]# print(search_res_list)for el in search_res_list: js = '("'+el.a['href']+'")' e_script(js) handle_this=t_window_handle#获取当前句柄 handle_all=_handles#获取所有句柄 handle_exchange=None#要切换的句柄 for handle in handle_all:#不匹配为新句柄 if handle != handle_this:#不等于当前句柄就交换 handle_exchange = handle _(handle_exchange)#切换 real_url=t_url print(real_url) real_url_(real_url)#存储结果 () _(handle_this)1.4 获取源⽂本在当前⽂件的⽬录下新建⼀个⽂件夹,命名为textsrc,在该⽬录下创建⼀个txt⽂件,把需要对⽐的⽂本存放⾄该⽂本中。在此我存放的内容为⽂章“php基础教程第⼗⼀步 ⾯向对象”的内容。在代码中编写⼀个函数为获取⽂本内容:def read_txt(path=''): f = open(path,'r') return ()src=read_txt(r'F:')为了⽅便测试,这⾥使⽤是绝对路径。获取到⽂本内容后,编写余弦相似度的对⽐⽅法。1.5 余弦相似度相似度计算参考⽂章《》,本⼈修改⼀部分从⽽实现。本⽂相似度对⽐使⽤余弦相似度算法,⼀般步骤分为分词->向量计算->计算相似度。新建⼀个python⽂件,名为Analyse。新建⼀个类名为Analyse,在类中添加分词⽅法,并在头部引⼊jieba分词库,以及collections统计次数:from jieba import lcutimport eimport collectionsCount⽅法:#分词def Count(self,text): tag = nk(text,topK=20) word_counts = r(tag) #计数统计 return word_countsCount⽅法接收⼀个text变量,text变量为⽂本,使⽤textrank⽅法分词并且使⽤Counter计数。随后添加MergeWord⽅法,使词合并⽅便之后的向量计算:#词合并def MergeWord(self,T1,T2): MergeWord = [] for i in T1: (i) for i in T2: if i not in MergeWord: (i) return MergeWord合并⽅法很简单不再做解释。接下来添加向量计算⽅法:# 得出⽂档向量def CalVector(self,T1,MergeWord): TF1 = [0] * len(MergeWord) for ch in T1: TermFrequence = T1[ch] word = ch if word in MergeWord: TF1[(word)] = TermFrequence return TF1最后添加相似度计算⽅法:def cosine_similarity(self,vector1, vector2): dot_product = 0.0 normA = 0.0 normB = 0.0 for a, b in zip(vector1, vector2):#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现 dot_product += a * b

normA += a ** 2 normB += b ** 2 if normA == 0.0 or normB == 0.0: return 0 else: return round(dot_product / ((normA**0.5)*(normB**0.5))*100, 2)相似度⽅法接收两个向量,随后计算相似度并返回。为了代码冗余度少,在这⾥先简单的添加⼀个⽅法,完成计算流程:def get_Tfidf(self,text1,text2):#测试对⽐本地数据对⽐搜索引擎⽅法 # _this_url(url) T1 = (text1) T2 = (text2) mergeword = ord(T1,T2) return _similarity(tor(T1,mergeword),tor(T2,mergeword))Analyse类的完整代码如下:from jieba import lcutimport eimport collectionsclass Analyse: def get_Tfidf(self,text1,text2):#测试对⽐本地数据对⽐搜索引擎⽅法 # _this_url(url) T1 = (text1) T2 = (text2) mergeword = ord(T1,T2) return _similarity(tor(T1,mergeword),tor(T2,mergeword))

#分词 def Count(self,text): tag = nk(text,topK=20) word_counts = r(tag) #计数统计 return word_counts #词合并 def MergeWord(self,T1,T2): MergeWord = [] for i in T1: (i) for i in T2: if i not in MergeWord: (i) return MergeWord # 得出⽂档向量 def CalVector(self,T1,MergeWord): TF1 = [0] * len(MergeWord) for ch in T1: TermFrequence = T1[ch] word = ch if word in MergeWord: TF1[(word)] = TermFrequence return TF1 #计算 TF-IDF def cosine_similarity(self,vector1, vector2): dot_product = 0.0 normA = 0.0 normB = 0.0 for a, b in zip(vector1, vector2):#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现 dot_product += a * b

normA += a ** 2 normB += b ** 2 if normA == 0.0 or normB == 0.0: return 0 else: return round(dot_product / ((normA**0.5)*(normB**0.5))*100, 2)1.6 搜索结果内容与⽂本做相似度对⽐在selenium_search⽂件中引⼊Analyse,并且新建对象:from Analyse import AnalyseAnalyse=Analyse()在遍历搜索结果中添加获取新打开后的页⾯的⽹页内容:(5)html_2=_source使⽤

(5)是为了等待浏览器能够有时间渲染当前web内容。获取到新打开的页⾯内容后,进⾏相似度对⽐:_Tfidf(src,html_2)由于返回的是⼀个值,使⽤print输出:print('相似度:',_Tfidf(src,html_2))完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupimport timefrom Analyse import Analysedef read_txt(path=''): f = open(path,'r') return ()#获取对⽐⽂件src=read_txt(r'F:')Analyse=Analyse()url=''driver=()(url)input=_element_by_id('kw')_keys('php基础教程 第⼗⼀步 ⾯向对象')search_btn=_element_by_id('su')search_()(2)#在此等待 使浏览器解析并渲染到浏览器html=_sourcesoup = BeautifulSoup(html, "")search_res_list=('.t')real_url_list=[]# print(search_res_list)for el in search_res_list: js = '("'+el.a['href']+'")' e_script(js) handle_this=t_window_handle#获取当前句柄 handle_all=_handles#获取所有句柄 handle_exchange=None#要切换的句柄 for handle in handle_all:#不匹配为新句柄 if handle != handle_this:#不等于当前句柄就交换 handle_exchange = handle _(handle_exchange)#切换 real_url=t_url

(5) html_2=_source print('相似度:',_Tfidf(src,html_2))

print(real_url) real_url_(real_url) () _(handle_this)运⾏脚本:结果显⽰有⼏个⾼度相似的链接,那么这⼏个就是疑似抄袭的⽂章了。以上是完成基本查重的代码,但是相对于说代码⽐较冗余、杂乱,接下来我们优化⼀下代码。⼆、代码优化通过以上的程序编程,简要步骤可以分为:获取搜索内容->获取结果->计算相似度。我们可以新建三个类,分别为:Browser、Analyse(已新建)、SearchEngine。Browser⽤于搜索、数据获取等;Analyse⽤于相似度分析、向量计算等;SearchEngine⽤于不同搜索引擎的基本配置,因为⼤部分搜多引擎的搜索⽅式较为⼀致。2.1Browser 类初始化新建⼀个python⽂件,名为Browser,添加初始化⽅法:def __init__(self,conf): r=() =conf _conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf()r=()为新建⼀个浏览器对象;conf为传⼊的搜索配置,之后进⾏搜索内容由编写配置字典实现;_conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf()为获取搜索引擎的配置,不同搜索引擎的输⼊框、搜索按键不⼀致,通过不同的配置信息实现多搜索引擎搜索。添加搜索⽅法 #搜索内容写⼊到搜素引擎中 def send_keyword(self): input = _element_by_id(_conf['searchTextID']) _keys(['kw'])以上⽅法中_conf['searchTextID']与['kw']通过初始化⽅法得到对应的搜索引擎配置信息,直接获取信息得到元素。点击搜索#搜索框点击 def click_search_btn(self): search_btn = _element_by_id(_conf['searchBtnID']) search_()通过使⽤_conf['searchBtnID']获取搜索按钮的id。获取搜索结果与⽂本#获取搜索结果与⽂本 def get_search_res_url(self): res_link={} WebDriverWait(r,timeout=30,poll_frequency=1).until(ce_of_element_located((, "page"))) #内容通过 BeautifulSoup 解析 content=_source soup = BeautifulSoup(content, "") search_res_list=('.'+_conf['searchContentHref_class']) for el in search_res_list: js = '("'+el.a['href']+'")' e_script(js) handle_this=t_window_handle #获取当前句柄 handle_all=_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不等于当前句柄就交换 handle_exchange = handle _(handle_exchange) #切换 real_url=t_url

(1) res_link[real_url]=_source #结果获取

() _(handle_this) return res_link以上⽅法跟之前编写的遍历搜索结果内容相似,从中添加了WebDriverWait(r,timeout=30,poll_frequency=1).until(ce_of_element_located((, "page")))替代了sleep,⽤于判断ce_of_element_located((, "page"))是否找到id值为page的⽹页元素,id为page的⽹页元素为分页按钮的标签id,如果未获取表⽰当前web页并未加载完全,等待时间为timeout=3030秒,如果已过去则跳过等待。以上代码中并不做相似度对⽐,⽽是通过

res_link[real_url]=_source 将内容与url存⼊字典,随后返回,之后再做相似度对⽐,这样编写利于之后的功能扩展。打开⽬标搜索引擎进⾏搜索 #打开⽬标搜索引擎进⾏搜索 def search(self): (_conf['website']) #打开搜索引擎站点 _keyword() #输⼊搜索kw _search_btn() #点击搜索 return _search_res_url() #获取web页搜索数据最后添加⼀个search⽅法,直接调⽤search⽅法即可实现之前的所有操作,不⽤暴露过多简化使⽤。完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupfrom SearchEngine import EngineConfManagefrom import WebDriverWaitfrom t import expected_conditions as ECfrom import Byimport timeclass Browser: def __init__(self,conf): r=() =conf _conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf() #搜索内容写⼊到搜素引擎中 def send_keyword(self): input = _element_by_id(_conf['searchTextID']) _keys(['kw']) #搜索框点击 def click_search_btn(self): search_btn = _element_by_id(_conf['searchBtnID']) search_() #获取搜索结果与⽂本 def get_search_res_url(self): res_link={} WebDriverWait(r,timeout=30,poll_frequency=1).until(ce_of_element_located((, "page"))) #内容通过 BeautifulSoup 解析 content=_source soup = BeautifulSoup(content, "") search_res_list=('.'+_conf['searchContentHref_class']) for el in search_res_list: js = '("'+el.a['href']+'")' e_script(js) handle_this=t_window_handle #获取当前句柄 handle_all=_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不等于当前句柄就交换 handle_exchange = handle _(handle_exchange) #切换 real_url=t_url

(1) res_link[real_url]=_source #结果获取

() _(handle_this) return res_link

#打开⽬标搜索引擎进⾏搜索 def search(self): (_conf['website']) #打开搜索引擎站点 _keyword() #输⼊搜索kw _search_btn() #点击搜索 return _search_res_url() #获取web页搜索数据2.2SearchEngine 类SearchEngine类主要⽤于不同搜索引擎的配置编写。更加简便的实现搜索引擎或相似业务的扩展。#搜索引擎配置class EngineConfManage: def get_Engine_conf(self,engine_name): if engine_name=='baidu': return BaiduEngineConf() elif engine_name=='qihu360': return Qihu360EngineConf() elif engine_name=='sougou': return SougouEngineConf()class EngineConf: def __init__(self): Conf={} def get_conf(self): return Confclass BaiduEngineConf(EngineConf): engineConf={} def __init__(self): Conf['searchTextID']='kw' Conf['searchBtnID']='su' Conf['nextPageBtnID_xpath_f']='//*[@id="page"]/div/a[10]' Conf['nextPageBtnID_xpath_s']='//*[@id="page"]/div/a[11]' Conf['searchContentHref_class']='t' Conf['website']=''class Qihu360EngineConf(EngineConf): def __init__(self): passclass SougouEngineConf(EngineConf): def __init__(self): pass在此只实现了百度搜索引擎的配置编写。所有不同种类的搜索引擎继承EngineConf基类,使⼦类都有了get_conf⽅法。EngineConfManage类⽤于不同搜索引擎的调⽤,传⼊引擎名即可。2.3如何使⽤⾸先引⼊两个类:from Browser import Browserfrom Analyse import Analyse新建⼀个⽅法读取本地⽂件:def read_txt(path=''): f = open(path,'r') return ()获取⽂件并新建数据分析类:src=read_txt(r'F:')#获取本地⽂本Analyse=Analyse()配置信息字典编写:#配置信息conf={ 'kw':'php基础教程 第⼗⼀步 ⾯向对象', 'engine':'baidu', }新建Browser类,并传⼊配置信息:drvier=Browser(conf)获取搜索结果及内容url_content=()#获取搜索结果及内容遍历结果及计算相似度:for k in url_content: print(k,'相似度:',_Tfidf(src,url_content[k]))完整代码如下:from Browser import Browserfrom Analyse import Analysedef read_txt(path=''): f = open(path,'r') return ()src=read_txt(r'F:')#获取本地⽂本Analyse=Analyse()#配置信息conf={ 'kw':'php基础教程 第⼗⼀步 ⾯向对象', 'engine':'baidu', }

drvier=Browser(conf)url_content=()#获取搜索结果及内容for k in url_content: print(k,'相似度:',_Tfidf(src,url_content[k]))是不是感觉舒服多了?简直不要太清爽。你以为这就完了吗?还没完,接下来扩展⼀下功能。三、功能扩展暂时这个⼩⼯具的功能只有查重这个基础功能,并且这个存在很多问题。如没有⽩名单过滤、只能查⼀篇⽂章的相似度、如果⽐较懒也没有直接获取⽂章列表⾃动查重的功能以及结果导出等。接下来慢慢完善部分功能,由于篇幅关系并不完全把的功能实现在此列出,之后将会持续更新。3.1⾃动获取⽂本新建⼀个python⽂件,名为FileHandle。该类⽤于⾃动获取指定⽬录下txt⽂件,txt⽂件⽂件名为关键字,内容为该名称的⽂章内容。类代码如下:import osclass FileHandle: #获取⽂件内容 def get_content(self,path): f = open(path,"r") #设置⽂件对象 content = () #将txt⽂件的所有内容读⼊到字符串str中 () #将⽂件关闭 return content #获取⽂件内容 def get_text(self): file_path=e(__file__) #当前⽂件所在⽬录 txt_path=file_path+r'textsrc' #txt⽬录 rootdir=(txt_path) #⽬标⽬录内容 local_text={} # 读txt ⽂件 for (dirpath,dirnames,filenames) in (rootdir): for filename in filenames: if xt(filename)[1]=='.txt': flag_file_path=dirpath+''+filename #⽂件路径 flag_file_content=_content(flag_file_path) #读⽂件路径 if flag_file_content!='': local_text[e('.txt', '')]=flag_file_content #键值对内容 return local_text其中有两个⽅法get_content与get_text。get_text为获取⽬录下所有txt⽂件路径,通过get_content获取到详细⽂本内容,返回local_text;local_text键为⽂件名,值为⽂本内容。3.2BrowserManage类在Browser类⽂件中添加⼀个BrowserManage类继承于Browser,添加⽅法:#打开⽬标搜索引擎进⾏搜索 def search(self): (_conf['website']) #打开搜索引擎站点 _keyword() #输⼊搜索kw _search_btn() #点击搜索 return _search_res_url() #获取web页搜索数据添加该类使Browser类的逻辑与其它⽅法分开,便于扩展。3.3Browser类的扩展在Browser类中添加下⼀页⽅法,使搜索内容时能够获取更多内容,并且可指定获取结果条数:#下⼀页 def click_next_page(self,md5): WebDriverWait(r,timeout=30,poll_frequency=1).until(ce_of_element_located((, "page"))) #百度搜索引擎翻页后下⼀页按钮 xpath 不⼀致 默认⾮第⼀页xpath try: next_page_btn = _element_by_xpath(_conf['nextPageBtnID_xpath_s']) except: next_page_btn = _element_by_xpath(_conf['nextPageBtnID_xpath_f']) next_page_() #md5 进⾏ webpag text 对⽐,判断是否已翻页 (暂时使⽤,存在bug) i=0 while md5==5(_(encoding='UTF-8')).hexdigest():#md5 对⽐ (0.3)#防⽌⼀些错误,暂时使⽤强制停⽌保持⼀些稳定 i+=1 if i>100: return False return True百度搜索引擎翻页后下⼀页按钮 xpath 不⼀致 默认⾮第⼀页xpath,出现异常使⽤另外⼀个xpath。随后对页⾯进⾏md5,对⽐md5值,如果当前页⾯没有刷新,md5值将不会改变,等待⼩短时间之后点击下⼀页。3.4get_search_res_url⽅法的修改get_search_res_url⽅法的修改了部分内容,添加了增加结果条数指定、下⼀页内容获取以及⽩名单设置更改过后的代码如下:#获取搜索结果与⽂本 def get_search_res_url(self): res_link={} WebDriverWait(r,timeout=30,poll_frequency=1).until(ce_of_element_located((, "page"))) #内容通过 BeautifulSoup 解析 content=_source soup = BeautifulSoup(content, "") search_res_list=('.'+_conf['searchContentHref_class']) while len(res_link)<['target_page']: for el in search_res_list: js = '("'+el.a['href']+'")' e_script(js) handle_this=t_window_handle #获取当前句柄 handle_all=_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不等于当前句柄就交换 handle_exchange = handle _(handle_exchange) #切换 real_url=t_url if real_url in ['white_list']: #⽩名单 continue (1) res_link[real_url]=_source #结果获取

() _(handle_this) content_md5=5(_(encoding='UTF-8')).hexdigest() #md5对⽐ _next_page(content_md5) return res_linkwhile len(res_link)<['target_page']:为增加了对结果条数的判断。content_md5=5(_(encoding='UTF-8')).hexdigest() #md5对⽐_next_page(content_md5)以上代码增加了当前页⾯刷新后的md5值判断,不⼀致则进⾏跳转。if real_url in ['white_list']: #⽩名单 continue以上代码对⽩名单进⾏了判断,⾃⼰设置的⽩名单不加⼊到条数。3.5新建Manage类新建⼀python⽂件名为Manage,再次封装。代码如下:from Browser import BrowserManagefrom Analyse import Analysefrom FileHandle import FileHandleclass Manage: def __init__(self,conf): =BrowserManage(conf) c=FileHandle().get_text() e=Analyse() def get_local_analyse(self):

resdic={}

for k in c: res={} _kw(k) url_content=()#获取搜索结果及内容 for k1 in url_content: res[k1]=_Tfidf(c[k],url_content[k1]) resdic[k]=res return resdic以上代码初始化⽅法接收⼀个参数,且初始化⽅法中新建了BrowserManage对象、Analyse对象以及获取了⽂本内容。get_local_analyse⽅法遍历⽂本,使⽤⽂件名当作关键字进⾏搜索,并且将搜索内容与当前⽂本做相似度对⽐,最后返回结果。结果如下:博主⽬录下⽂件如下:相似度分析部分以上为主要内容,⼯具之后将会丢GitHub及csdn的代码仓库中,使⽤的⽆头模式,本篇所讲的内容为⼀般实现。所有完整的代码如下Analyse类:from jieba import lcutimport eimport collectionsfrom FileHandle import FileHandleclass Analyse: def get_Tfidf(self,text1,text2):#测试对⽐本地数据对⽐搜索引擎⽅法 # _this_url(url) T1 = (text1) T2 = (text2) mergeword = ord(T1,T2) return _similarity(tor(T1,mergeword),tor(T2,mergeword))

#分词 def Count(self,text): tag = nk(text,topK=20) word_counts = r(tag) #计数统计 return word_counts #词合并 def MergeWord(self,T1,T2): MergeWord = [] for i in T1: (i) for i in T2: if i not in MergeWord: (i) return MergeWord # 得出⽂档向量 def CalVector(self,T1,MergeWord): TF1 = [0] * len(MergeWord) for ch in T1: TermFrequence = T1[ch] word = ch if word in MergeWord: TF1[(word)] = TermFrequence return TF1 #计算 TF-IDF def cosine_similarity(self,vector1, vector2): dot_product = 0.0 normA = 0.0 normB = 0.0 for a, b in zip(vector1, vector2):#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现 dot_product += a * b

normA += a ** 2 normB += b ** 2 if normA == 0.0 or normB == 0.0: return 0 else: return round(dot_product / ((normA**0.5)*(normB**0.5))*100, 2)Browser类:from selenium import webdriverfrom bs4 import BeautifulSoupfrom SearchEngine import EngineConfManagefrom import WebDriverWaitfrom t import expected_conditions as ECfrom import Byimport hashlibimport timeimport xlwtclass Browser: def __init__(self,conf): r=() =conf ['kw']='' _conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf() #搜索内容设置 def set_kw(self,kw): ['kw']=kw #搜索内容写⼊到搜素引擎中 def send_keyword(self): input = _element_by_id(_conf['searchTextID']) _keys(['kw']) #搜索框点击 def click_search_btn(self): search_btn = _element_by_id(_conf['searchBtnID']) search_() #获取搜索结果与⽂本 def get_search_res_url(self): res_link={} WebDriverWait(r,timeout=30,poll_frequency=1).until(ce_of_element_located((, "page"))) #内容通过 BeautifulSoup 解析 content=_source soup = BeautifulSoup(content, "") search_res_list=('.'+_conf['searchContentHref_class']) while len(res_link)<['target_page']: for el in search_res_list: js = '("'+el.a['href']+'")' e_script(js) handle_this=t_window_handle #获取当前句柄 handle_all=_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不等于当前句柄就交换 handle_exchange = handle _(handle_exchange) #切换 real_url=t_url if real_url in ['white_list']: #⽩名单 continue (1) res_link[real_url]=_source #结果获取

() _(handle_this) content_md5=5(_(encoding='UTF-8')).hexdigest() #md5对⽐ _next_page(content_md5) return res_link #下⼀页 def click_next_page(self,md5): WebDriverWait(r,timeout=30,poll_frequency=1).until(ce_of_element_located((, "page"))) #百度搜索引擎翻页后下⼀页按钮 xpath 不⼀致 默认⾮第⼀页xpath try: next_page_btn = _element_by_xpath(_conf['nextPageBtnID_xpath_s']) except: next_page_btn = _element_by_xpath(_conf['nextPageBtnID_xpath_f']) next_page_() #md5 进⾏ webpag text 对⽐,判断是否已翻页 (暂时使⽤,存在bug) i=0 while md5==5(_(encoding='UTF-8')).hexdigest():#md5 对⽐ (0.3)#防⽌⼀些错误,暂时使⽤强制停⽌保持⼀些稳定 i+=1 if i>100: return False return Trueclass BrowserManage(Browser):

#打开⽬标搜索引擎进⾏搜索 def search(self): (_conf['website']) #打开搜索引擎站点 _keyword() #输⼊搜索kw _search_btn() #点击搜索 return _search_res_url() #获取web页搜索数据Manage类:from Browser import BrowserManagefrom Analyse import Analysefrom FileHandle import FileHandleclass Manage: def __init__(self,conf): =BrowserManage(conf) c=FileHandle().get_text() e=Analyse() def get_local_analyse(self):

resdic={}

for k in c: res={} _kw(k) url_content=()#获取搜索结果及内容 for k1 in url_content: res[k1]=_Tfidf(c[k],url_content[k1]) resdic[k]=res return resdicFileHandle类:import osclass FileHandle: #获取⽂件内容 def get_content(self,path): f = open(path,"r") #设置⽂件对象 content = () #将txt⽂件的所有内容读⼊到字符串str中 () #将⽂件关闭 return content #获取⽂件内容 def get_text(self): file_path=e(__file__) #当前⽂件所在⽬录 txt_path=file_path+r'textsrc' #txt⽬录 rootdir=(txt_path) #⽬标⽬录内容 local_text={} # 读txt ⽂件 for (dirpath,dirnames,filenames) in (rootdir): for filename in filenames: if xt(filename)[1]=='.txt': flag_file_path=dirpath+''+filename #⽂件路径 flag_file_content=_content(flag_file_path) #读⽂件路径 if flag_file_content!='': local_text[e('.txt', '')]=flag_file_content #键值对内容 return local_text本⽂最终使⽤⽅法如下:from Manage import Managewhite_list=['/A757291228','/1-bit','/csdnnews']#⽩名单#配置信息conf={ 'engine':'baidu', 'target_page':5 'white_list':white_list, }print(Manage(conf).get_local_analyse())到此这篇关于python基于搜索引擎实现⽂章查重功能的⽂章就介绍到这了,更多相关python⽂章查重内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

发布者:admin,转转请注明出处:http://www.yc00.com/web/1688890492a181648.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信