当前位置:主页 > 技术文章 >

技术文章

Technical articles

python 手把手教你基于搜索引擎实现文章查重

时间:2022-08-03 06:04 点击次数:
  本文摘要:前言文章抄袭在互联网中普遍存在,许多博主都收受其烦。近几年随着互联网的生长,抄袭等不道品德为在互联网上愈演愈烈,甚至复制、黏贴后公布标原创屡见不鲜,部门抄袭后的文章甚至标志了一些联系方式从而使读者获取源码等资料。 这种恶劣的行为使人愤慨。本文使用搜索引擎效果作为文章库,再与当地或互联网上数据做相似度对比,实现文章查重;由于查重的实现历程与一般情况下的微博情感分析实现流程相似,从而轻易的扩展出情感分析功效(下一篇将在此篇代码的基础上完成数据收罗、清洗到情感分析的整个历程)。

欧宝体育app官网

前言文章抄袭在互联网中普遍存在,许多博主都收受其烦。近几年随着互联网的生长,抄袭等不道品德为在互联网上愈演愈烈,甚至复制、黏贴后公布标原创屡见不鲜,部门抄袭后的文章甚至标志了一些联系方式从而使读者获取源码等资料。

这种恶劣的行为使人愤慨。本文使用搜索引擎效果作为文章库,再与当地或互联网上数据做相似度对比,实现文章查重;由于查重的实现历程与一般情况下的微博情感分析实现流程相似,从而轻易的扩展出情感分析功效(下一篇将在此篇代码的基础上完成数据收罗、清洗到情感分析的整个历程)。由于近期时间上并不丰裕,暂时实现了主要功效,细节上并没有举行优化,可是在代码结构上举行了一些简要的设计,使得之后的功效扩展、升级更为轻便。我本人也将会连续更新该工具的功效,争取让这个工具在技术上越发的成熟、实用。

技术本文实现的查重功效为了思量适配大多数站点,从而使用selenium用作数据获取,设置差别搜索引擎的信息,实现较为通用的搜索引擎查询,而且不需要思量过多的动态数据抓取;分词主要使用jieba库,完成对中文语句的分词;使用余弦相似度完成文底细似度的对比并导出对比数据至Excel文章留作举报信息。微博情感分析基于sklearn,使用朴素贝叶斯完成对数据的情感分析;在数据抓取上,实现流程与文本查重的功效类似。测试代码获取 codechina 代码堆栈:https://codechina.csdn.net/A757291228/s-analysetooldemo情况作者的情况说明如下:操作系统:Windows7 SP1 64python 版本:3.7.7浏览器:谷歌浏览器浏览器版本: 80.0.3987 (64 位)如有错误接待指出,接待留言交流。

一、实现文本查重1.1 selenium安装设置由于使用的selenium,在使用前需要确保读者是否已安装selenium,使用pip下令,安装如下:pip install selenium安装完成 Selenium 还需要下载一个驱动。谷歌浏览器驱动:驱动版本需要对应浏览器版本,差别的浏览器使用对应差别版本的驱动,点击下载如果是使用火狐浏览器,检察火狐浏览器版本,点击GitHub火狐驱动下载地址下载(英文欠好的同学右键一键翻译即可,每个版本都有对应浏览器版本的使用说明,看清楚下载即可)安装了selenium后新建一python文件名为selenium_search,先在代码中引入from selenium import webdriver可能有些读者没有把驱动设置到情况中,接下来我们可以指定驱动的位置(博主已设置到情况中):driver = webdriver.Chrome(executable_path=r'F:pythondrchromedriver_win32chromedriver.exe')新建一个变量url赋值为百度首页链接,使用get方法传入url地址,实验打开百度首页,完整代码如下:from selenium import webdriverurl='https://www.baidu.com'driver=webdriver.Chrome()driver.get(url)在小黑框中使用下令行运行python文件(windows下):运行剧本后将会打开谷歌浏览器并跳转至百度首页:这样就乐成使用selenium打开了指定网址,接下来将指定搜索关键词查询获得效果,再从效果中遍历到相似数据。1.2 selenium百度搜索引擎关键词搜索在自动操控浏览器举行关键字键入到搜索框前,需要获取搜索框元素工具。使用谷歌浏览器打开百度首页,右键搜索框选择检察,将会弹出网页元素(代码)检察视窗,找到搜索框元素(使用鼠标在元素节点中移动,鼠标当前位置的元素节点将会对应的在网页中标蓝):在html代码中,id的值大多数情况下唯一(除非是打错了),在此选择id作为获取搜索框元素工具的标志。

selenium提供了find_element_by_id方法,可以通过传入id获取到网页元素工具。input=driver.find_element_by_id('kw')获取元素工具后,使用send_keys方法可传入需要键入的值:input.send_keys('php基础教程 第十一步 面向工具')在此我传入了 “php基础教程 第十一步 面向工具”作为关键字作为搜索。

运行剧本检察是否在搜索框中键入了关键字。代码如下:input.send_keys('php基础教程 第十一步 面向工具')乐成打开浏览器并键入了搜索关键字:现在还差点击“百度一下”按钮完成最终的搜索。

使用与检察搜索框相同的元素检察方法查找“百度一下”按钮的id值:使用find_element_by_id方法获取到该元素工具,随后使用click方法使该按钮完成点击操作:search_btn=driver.find_element_by_id('su')search_btn.click()完整代码如下:from selenium import webdriverurl='https://www.baidu.com'driver=webdriver.Chrome()driver.get(url)input=driver.find_element_by_id('kw')input.send_keys('php基础教程 第十一步 面向工具')search_btn=driver.find_element_by_id('su')search_btn.click()浏览器自动完成了键入搜索关键字及搜索功效:1.3 搜索效果遍历当前已在浏览器中获得了搜索效果,接下来需要获取整个web页面内容,获得搜索效果。使用selenium并不能很利便的获取到,在这里使用BeautifulSoup对整个web页面举行剖析并获取搜索效果。BeautifulSoup是一个HTML/XML剖析器,使用BeautifulSoup会极大的利便我们对整个html的信息获取。

使用BeautifulSoup前需确保已安装。安装下令如下:pip install BeautifulSoup安装后,在当前python文件头部引入:from bs4 import BeautifulSoup获取html文本可以挪用page_source即可:html=driver.page_source获得了html代码后,新建BeautifulSoup工具,传入html内容而且指定剖析器,这里指定使用 html.parser 剖析器:soup = BeautifulSoup(html, "html.parser")接下来检察搜索内容,发现所有的效果都由一个h标签包罗,而且class为t:BeautifulSoup提供了select方法对标签举行获取,支持通过类名、标签名、id、属性、组合查找等。我们发现百度搜索效果中,效果皆有一个class =“t”,此时可以通过类名举行遍历获取最为轻便:search_res_list=soup.select('.t')在select方法中传入类名t,在类名前加上一个点(.)表现是通过类名获取元素。

完成这一步后可以添加print实验打印出效果:print(search_res_list)一般情况下,可能输出search_res_list为空列表,这是因为我们在浏览器剖析数据渲染到浏览器前已经获取了浏览器当前页的内容,这时有一个简朴的方法可以解决这个问题,可是此方法效率却不高,在此只是暂时使用,之后将会用其它效率高于此方法的代码替换(使用time需要在头部引入):time.sleep(2)完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupimport timeurl='https://www.baidu.com'driver=webdriver.Chrome()driver.get(url)input=driver.find_element_by_id('kw')input.send_keys('php基础教程 第十一步 面向工具')search_btn=driver.find_element_by_id('su')search_btn.click()time.sleep(2)#在此等候 使浏览器剖析并渲染到浏览器html=driver.page_source #获取网页内容soup = BeautifulSoup(html, "html.parser")search_res_list=soup.select('.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 = 'window.open("'+el.a['href']+'")' driver.execute_script(js)打开新的网页后,需要获取新网页的句柄,否则无法操控新网页。

获取句柄的方法如下:handle_this=driver.current_window_handle#获取当前句柄handle_all=driver.window_handles#获取所有句柄获取句柄后需要把当前操作的工具切换成新的页面。由于打开一个页面后所有页面只有2个,简朴的使用遍历做一个替换:handle_exchange=None#要切换的句柄for handle in handle_all:#不匹配为新句柄 if handle != handle_this:#不即是当前句柄就交流 handle_exchange = handledriver.switch_to.window(handle_exchange)#切换切换后,操作工具为当前刚打开的页面。通过current_url属性拿到新页面的url:real_url=driver.current_urlprint(real_url)随后关闭当前页面,把操作工具置为初始页面:driver.close()driver.switch_to.window(handle_this)#换回最初始界面运行剧本乐成获取到真实url:最后在获取到真实url后使用一个列表将效果存储:real_url_list.append(real_url)这一部门完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupimport timeurl='https://www.baidu.com'driver=webdriver.Chrome()driver.get(url)input=driver.find_element_by_id('kw')input.send_keys('php基础教程 第十一步 面向工具')search_btn=driver.find_element_by_id('su')search_btn.click()time.sleep(2)#在此等候 使浏览器剖析并渲染到浏览器html=driver.page_sourcesoup = BeautifulSoup(html, "html.parser")search_res_list=soup.select('.t')real_url_list=[]# print(search_res_list)for el in search_res_list: js = 'window.open("'+el.a['href']+'")' driver.execute_script(js) handle_this=driver.current_window_handle#获取当前句柄 handle_all=driver.window_handles#获取所有句柄 handle_exchange=None#要切换的句柄 for handle in handle_all:#不匹配为新句柄 if handle != handle_this:#不即是当前句柄就交流 handle_exchange = handle driver.switch_to.window(handle_exchange)#切换 real_url=driver.current_url print(real_url) real_url_list.append(real_url)#存储效果 driver.close() driver.switch_to.window(handle_this)1.4 获取源文本在当前文件的目录下新建一个文件夹,命名为textsrc,在该目录下建立一个txt文件,把需要对比的文本存放至该文本中。

欧宝体育app官网

在此我存放的内容为文章“php基础教程 第十一步 面向工具”的内容。在代码中编写一个函数为获取文本内容:def read_txt(path=''): f = open(path,'r') return f.read()src=read_txt(r'F:tooltextsrcsrc.txt')为了利便测试,这里使用是绝对路径。获取到文本内容后,编写余弦相似度的对例如法。1.5 余弦相似度相似度盘算参考文章《python实现余弦相似度文本比力》,本人修改一部门从而实现。

本文相似度对比使用余弦相似度算法,一般步骤分为分词->向量盘算->盘算相似度。新建一个python文件,名为Analyse。

新建一个类名为Analyse,在类中添加分词方法,并在头部引入jieba分词库,以及collections统计次数:from jieba import lcutimport jieba.analyseimport collectionsCount方法:#分词def Count(self,text): tag = jieba.analyse.textrank(text,topK=20) word_counts = collections.Counter(tag) #计数统计 return word_countsCount方法吸收一个text变量,text变量为文本,使用textrank方法分词而且使用Counter计数。随后添加MergeWord方法,使词合并利便之后的向量盘算:#词合并def MergeWord(self,T1,T2): MergeWord = [] for i in T1: MergeWord.append(i) for i in T2: if i not in MergeWord: MergeWord.append(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[MergeWord.index(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):#测试对比当地数据对比搜索引擎方法 # self.correlate.word.set_this_url(url) T1 = self.Count(text1) T2 = self.Count(text2) mergeword = self.MergeWord(T1,T2) return self.cosine_similarity(self.CalVector(T1,mergeword),self.CalVector(T2,mergeword))Analyse类的完整代码如下:from jieba import lcutimport jieba.analyseimport collectionsclass Analyse: def get_Tfidf(self,text1,text2):#测试对比当地数据对比搜索引擎方法 # self.correlate.word.set_this_url(url) T1 = self.Count(text1) T2 = self.Count(text2) mergeword = self.MergeWord(T1,T2) return self.cosine_similarity(self.CalVector(T1,mergeword),self.CalVector(T2,mergeword)) #分词 def Count(self,text): tag = jieba.analyse.textrank(text,topK=20) word_counts = collections.Counter(tag) #计数统计 return word_counts #词合并 def MergeWord(self,T1,T2): MergeWord = [] for i in T1: MergeWord.append(i) for i in T2: if i not in MergeWord: MergeWord.append(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[MergeWord.index(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()在遍历搜索效果中添加获取新打开后的页面的网页内容:time.sleep(5)html_2=driver.page_source使用 time.sleep(5)是为了等候浏览器能够有时间渲染当前web内容。

获取到新打开的页面内容后,举行相似度对比:Analyse.get_Tfidf(src,html_2)由于返回的是一个值,使用print输出:print('相似度:',Analyse.get_Tfidf(src,html_2))完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupimport timefrom Analyse import Analysedef read_txt(path=''): f = open(path,'r') return f.read()#获取对比文件src=read_txt(r'F:tooltextsrcsrc.txt')Analyse=Analyse()url='https://www.baidu.com'driver=webdriver.Chrome()driver.get(url)input=driver.find_element_by_id('kw')input.send_keys('php基础教程 第十一步 面向工具')search_btn=driver.find_element_by_id('su')search_btn.click()time.sleep(2)#在此等候 使浏览器剖析并渲染到浏览器html=driver.page_sourcesoup = BeautifulSoup(html, "html.parser")search_res_list=soup.select('.t')real_url_list=[]# print(search_res_list)for el in search_res_list: js = 'window.open("'+el.a['href']+'")' driver.execute_script(js) handle_this=driver.current_window_handle#获取当前句柄 handle_all=driver.window_handles#获取所有句柄 handle_exchange=None#要切换的句柄 for handle in handle_all:#不匹配为新句柄 if handle != handle_this:#不即是当前句柄就交流 handle_exchange = handle driver.switch_to.window(handle_exchange)#切换 real_url=driver.current_url time.sleep(5) html_2=driver.page_source print('相似度:',Analyse.get_Tfidf(src,html_2)) print(real_url) real_url_list.append(real_url) driver.close() driver.switch_to.window(handle_this)运行剧本:效果显示有几个高度相似的链接,那么这几个就是疑似抄袭的文章了。以上是完成基本查重的代码,可是相对于说代码比力冗余、杂乱,接下来我们优化一下代码。二、代码优化通过以上的法式编程,简要步骤可以分为:获取搜索内容->获取效果->盘算相似度。

我们可以新建三个类,划分为:Browser、Analyse(已新建)、SearchEngine。Browser用于搜索、数据获取等;Analyse用于相似度分析、向量盘算等;SearchEngine用于差别搜索引擎的基本设置,因为大部门搜索引擎的搜索方式较为一致。

2.1Browser 类初始化新建一个python文件,名为Browser,添加初始化方法:def __init__(self,conf): self.browser=webdriver.Chrome() self.conf=confself.engine_conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf()self.browser=webdriver.Chrome()为新建一个浏览器工具;conf为传入的搜索设置,之后举行搜索内容由编写设置字典实现;self.engine_conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf()为获取搜索引擎的设置,差别搜索引擎的输入框、搜索按键纷歧致,通过差别的设置信息实现多搜索引擎搜索。添加搜索方法#搜索内容写入到搜素引擎中 def send_keyword(self): input = self.browser.find_element_by_id(self.engine_conf['searchTextID']) input.send_keys(self.conf['kw'])以上方法中self.engine_conf['searchTextID']与self.conf['kw']通过初始化方法获得对应的搜索引擎设置信息,直接获取信息获得元素。点击搜索#搜索框点击 def click_search_btn(self): search_btn = self.browser.find_element_by_id(self.engine_conf['searchBtnID']) search_btn.click()通过使用self.engine_conf['searchBtnID']获取搜索按钮的id。

获取搜索效果与文本#获取搜索效果与文本 def get_search_res_url(self): res_link={} WebDriverWait(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page"))) #内容通过 BeautifulSoup 剖析 content=self.browser.page_source soup = BeautifulSoup(content, "html.parser") search_res_list=soup.select('.'+self.engine_conf['searchContentHref_class']) for el in search_res_list: js = 'window.open("'+el.a['href']+'")' self.browser.execute_script(js) handle_this=self.browser.current_window_handle #获取当前句柄 handle_all=self.browser.window_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不即是当前句柄就交流 handle_exchange = handle self.browser.switch_to.window(handle_exchange) #切换 real_url=self.browser.current_url time.sleep(1) res_link[real_url]=self.browser.page_source #效果获取 self.browser.close() self.browser.switch_to.window(handle_this) return res_link以上方法跟之前编写的遍历搜索效果内容相似,从中添加了WebDriverWait(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page")))替代了sleep,用于判断EC.presence_of_element_located((By.ID, "page"))是否找到id值为page的网页元素,id为page的网页元素为分页按钮的标签id,如果未获取表现当前web页并未加载完全,等候时间为timeout=3030秒,如果已已往则跳过等候。以上代码中并不做相似度对比,而是通过 res_link[real_url]=self.browser.page_source 将内容与url存入字典,随后返回,之后再做相似度对比,这样编写利于之后的功效扩展。打开目的搜索引擎举行搜索#打开目的搜索引擎举行搜索 def search(self): self.browser.get(self.engine_conf['website']) #打开搜索引擎站点 self.send_keyword() #输入搜索kw self.click_search_btn() #点击搜索 return self.get_search_res_url() #获取web页搜索数据最后添加一个search方法,直接挪用search方法即可实现之前的所有操作,不用袒露过多简化使用。完整代码如下:from selenium import webdriverfrom bs4 import BeautifulSoupfrom SearchEngine import EngineConfManagefrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.by import Byimport timeclass Browser: def __init__(self,conf): self.browser=webdriver.Chrome() self.conf=conf self.engine_conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf() #搜索内容写入到搜素引擎中 def send_keyword(self): input = self.browser.find_element_by_id(self.engine_conf['searchTextID']) input.send_keys(self.conf['kw']) #搜索框点击 def click_search_btn(self): search_btn = self.browser.find_element_by_id(self.engine_conf['searchBtnID']) search_btn.click() #获取搜索效果与文本 def get_search_res_url(self): res_link={} WebDriverWait(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page"))) #内容通过 BeautifulSoup 剖析 content=self.browser.page_source soup = BeautifulSoup(content, "html.parser") search_res_list=soup.select('.'+self.engine_conf['searchContentHref_class']) for el in search_res_list: js = 'window.open("'+el.a['href']+'")' self.browser.execute_script(js) handle_this=self.browser.current_window_handle #获取当前句柄 handle_all=self.browser.window_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不即是当前句柄就交流 handle_exchange = handle self.browser.switch_to.window(handle_exchange) #切换 real_url=self.browser.current_url time.sleep(1) res_link[real_url]=self.browser.page_source #效果获取 self.browser.close() self.browser.switch_to.window(handle_this) return res_link #打开目的搜索引擎举行搜索 def search(self): self.browser.get(self.engine_conf['website']) #打开搜索引擎站点 self.send_keyword() #输入搜索kw self.click_search_btn() #点击搜索 return self.get_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): self.engineConf={} def get_conf(self): return self.engineConfclass BaiduEngineConf(EngineConf): engineConf={} def __init__(self): self.engineConf['searchTextID']='kw' self.engineConf['searchBtnID']='su' self.engineConf['nextPageBtnID_xpath_f']='//*[@id="page"]/div/a[10]' self.engineConf['nextPageBtnID_xpath_s']='//*[@id="page"]/div/a[11]' self.engineConf['searchContentHref_class']='t' self.engineConf['website']='http://www.baidu.com'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 f.read()获取文件并新建数据分析类:src=read_txt(r'F:tooltextsrcsrc.txt')#获取当地文本Analyse=Analyse()设置信息字典编写:#设置信息conf={ 'kw':'php基础教程 第十一步 面向工具', 'engine':'baidu', }新建Browser类,并传入设置信息:drvier=Browser(conf)获取搜索效果及内容url_content=drvier.search()#获取搜索效果及内容遍历效果及盘算相似度:for k in url_content: print(k,'相似度:',Analyse.get_Tfidf(src,url_content[k]))完整代码如下:from Browser import Browserfrom Analyse import Analysedef read_txt(path=''): f = open(path,'r') return f.read()src=read_txt(r'F:tooltextsrcsrc.txt')#获取当地文本Analyse=Analyse()#设置信息conf={ 'kw':'php基础教程 第十一步 面向工具', 'engine':'baidu', } drvier=Browser(conf)url_content=drvier.search()#获取搜索效果及内容for k in url_content: print(k,'相似度:',Analyse.get_Tfidf(src,url_content[k]))是不是感受舒服多了?简直不要太清爽。你以为这就完了吗?还没完,接下来扩展一下功效。三、功效扩展暂时这个小工具的功效只有查重这个基础功效,而且这个存在许多问题。

如没有白名单过滤、只能查一篇文章的相似度、如果比力懒也没有直接获取文章列表自动查重的功效以及效果导出等。接下来逐步完善部门功效,由于篇幅关系并不完全把的功效实现在此列出,之后将会连续更新。3.1自动获取文本新建一个python文件,名为FileHandle。该类用于自动获取指定目录下txt文件,txt文件文件名为关键字,内容为该名称的文章内容。

类代码如下:import osclass FileHandle: #获取文件内容 def get_content(self,path): f = open(path,"r") #设置文件工具 content = f.read() #将txt文件的所有内容读入到字符串str中 f.close() #将文件关闭 return content#获取文件内容 def get_text(self): file_path=os.path.dirname(__file__) #当前文件所在目录 txt_path=file_path+r'textsrc' #txt目录 rootdir=os.path.join(txt_path) #目的目录内容 local_text={} # 读txt 文件 for (dirpath,dirnames,filenames) in os.walk(rootdir): for filename in filenames: if os.path.splitext(filename)[1]=='.txt': flag_file_path=dirpath+'\'+filename #文件路径 flag_file_content=self.get_content(flag_file_path) #读文件路径 if flag_file_content!='': local_text[filename.replace('.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): self.browser.get(self.engine_conf['website']) #打开搜索引擎站点 self.send_keyword() #输入搜索kw self.click_search_btn() #点击搜索 return self.get_search_res_url() #获取web页搜索数据添加该类使Browser类的逻辑与其它方法离开,便于扩展。

3.3Browser类的扩展在Browser类中添加下一页方法,使搜索内容时能够获取更多内容,而且可指定获取效果条数:#下一页 def click_next_page(self,md5): WebDriverWait(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page"))) #百度搜索引擎翻页后下一页按钮 xpath 纷歧致 默认非第一页xpath try: next_page_btn = self.browser.find_element_by_xpath(self.engine_conf['nextPageBtnID_xpath_s']) except: next_page_btn = self.browser.find_element_by_xpath(self.engine_conf['nextPageBtnID_xpath_f']) next_page_btn.click() #md5 举行 webpag text 对比,判断是否已翻页 (暂时使用,存在bug) i=0 while md5==hashlib.md5(self.browser.page_source.encode(encoding='UTF-8')).hexdigest():#md5 对比 time.sleep(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(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page"))) #内容通过 BeautifulSoup 剖析 content=self.browser.page_source soup = BeautifulSoup(content, "html.parser") search_res_list=soup.select('.'+self.engine_conf['searchContentHref_class']) while len(res_link)<self.conf['target_page']: for el in search_res_list: js = 'window.open("'+el.a['href']+'")' self.browser.execute_script(js) handle_this=self.browser.current_window_handle #获取当前句柄 handle_all=self.browser.window_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不即是当前句柄就交流 handle_exchange = handle self.browser.switch_to.window(handle_exchange) #切换 real_url=self.browser.current_url if real_url in self.conf['white_list']: #白名单 continue time.sleep(1) res_link[real_url]=self.browser.page_source #效果获取 self.browser.close() self.browser.switch_to.window(handle_this) content_md5=hashlib.md5(self.browser.page_source.encode(encoding='UTF-8')).hexdigest() #md5对比 self.click_next_page(content_md5) return res_linkwhile len(res_link)<self.conf['target_page']:为增加了对效果条数的判断。content_md5=hashlib.md5(self.browser.page_source.encode(encoding='UTF-8')).hexdigest() #md5对比self.click_next_page(content_md5)以上代码增加了当前页面刷新后的md5值判断,纷歧致则举行跳转。

if real_url in self.conf['white_list']: #白名单continue以上代码对白名单举行了判断,自己设置的白名单不加入到条数。3.5新建Manage类新建一python文件名为Manage,再次封装。代码如下:from Browser import BrowserManagefrom Analyse import Analysefrom FileHandle import FileHandleclass Manage: def __init__(self,conf): self.drvier=BrowserManage(conf) self.textdic=FileHandle().get_text() self.analyse=Analyse() def get_local_analyse(self): resdic={} for k in self.textdic: res={} self.drvier.set_kw(k) url_content=self.drvier.search()#获取搜索效果及内容 for k1 in url_content: res[k1]=self.analyse.get_Tfidf(self.textdic[k],url_content[k1]) resdic[k]=res return resdic以上代码初始化方法吸收一个参数,且初始化方法中新建了BrowserManage工具、Analyse工具以及获取了文本内容。

get_local_analyse方法遍历文本,使用文件名看成关键字举行搜索,而且将搜索内容与当前文本做相似度对比,最后返回效果。效果如下:博主目录下文件如下:相似度分析部门以上为主要内容,工具之后将会丢GitHub及csdn的代码堆栈中,使用的无头模式,本篇所讲的内容为一般实现。所有完整的代码如下Analyse类:from jieba import lcutimport jieba.analyseimport collectionsfrom FileHandle import FileHandleclass Analyse: def get_Tfidf(self,text1,text2):#测试对比当地数据对比搜索引擎方法 # self.correlate.word.set_this_url(url) T1 = self.Count(text1) T2 = self.Count(text2) mergeword = self.MergeWord(T1,T2) return self.cosine_similarity(self.CalVector(T1,mergeword),self.CalVector(T2,mergeword)) #分词 def Count(self,text): tag = jieba.analyse.textrank(text,topK=20) word_counts = collections.Counter(tag) #计数统计 return word_counts #词合并 def MergeWord(self,T1,T2): MergeWord = [] for i in T1: MergeWord.append(i) for i in T2: if i not in MergeWord: MergeWord.append(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[MergeWord.index(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 selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.by import Byimport hashlibimport timeimport xlwtclass Browser: def __init__(self,conf): self.browser=webdriver.Chrome() self.conf=conf self.conf['kw']='' self.engine_conf=EngineConfManage().get_Engine_conf(conf['engine']).get_conf() #搜索内容设置 def set_kw(self,kw): self.conf['kw']=kw #搜索内容写入到搜素引擎中 def send_keyword(self): input = self.browser.find_element_by_id(self.engine_conf['searchTextID']) input.send_keys(self.conf['kw']) #搜索框点击 def click_search_btn(self): search_btn = self.browser.find_element_by_id(self.engine_conf['searchBtnID']) search_btn.click() #获取搜索效果与文本 def get_search_res_url(self): res_link={} WebDriverWait(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page"))) #内容通过 BeautifulSoup 剖析 content=self.browser.page_source soup = BeautifulSoup(content, "html.parser") search_res_list=soup.select('.'+self.engine_conf['searchContentHref_class']) while len(res_link)<self.conf['target_page']: for el in search_res_list: js = 'window.open("'+el.a['href']+'")' self.browser.execute_script(js) handle_this=self.browser.current_window_handle #获取当前句柄 handle_all=self.browser.window_handles #获取所有句柄 handle_exchange=None #要切换的句柄 for handle in handle_all: #不匹配为新句柄 if handle != handle_this: #不即是当前句柄就交流 handle_exchange = handle self.browser.switch_to.window(handle_exchange) #切换 real_url=self.browser.current_url if real_url in self.conf['white_list']: #白名单 continue time.sleep(1) res_link[real_url]=self.browser.page_source #效果获取 self.browser.close() self.browser.switch_to.window(handle_this) content_md5=hashlib.md5(self.browser.page_source.encode(encoding='UTF-8')).hexdigest() #md5对比 self.click_next_page(content_md5) return res_link #下一页 def click_next_page(self,md5): WebDriverWait(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page"))) #百度搜索引擎翻页后下一页按钮 xpath 纷歧致 默认非第一页xpath try: next_page_btn = self.browser.find_element_by_xpath(self.engine_conf['nextPageBtnID_xpath_s']) except: next_page_btn = self.browser.find_element_by_xpath(self.engine_conf['nextPageBtnID_xpath_f']) next_page_btn.click() #md5 举行 webpag text 对比,判断是否已翻页 (暂时使用,存在bug) i=0 while md5==hashlib.md5(self.browser.page_source.encode(encoding='UTF-8')).hexdigest():#md5 对比 time.sleep(0.3)#防止一些错误,暂时使用强制停止保持一些稳定 i+=1 if i>100: return False return Trueclass BrowserManage(Browser): #打开目的搜索引擎举行搜索 def search(self): self.browser.get(self.engine_conf['website']) #打开搜索引擎站点 self.send_keyword() #输入搜索kw self.click_search_btn() #点击搜索 return self.get_search_res_url() #获取web页搜索数据Manage类:from Browser import BrowserManagefrom Analyse import Analysefrom FileHandle import FileHandleclass Manage: def __init__(self,conf): self.drvier=BrowserManage(conf) self.textdic=FileHandle().get_text() self.analyse=Analyse() def get_local_analyse(self): resdic={} for k in self.textdic: res={} self.drvier.set_kw(k) url_content=self.drvier.search()#获取搜索效果及内容 for k1 in url_content: res[k1]=self.analyse.get_Tfidf(self.textdic[k],url_content[k1]) resdic[k]=res return resdicFileHandle类:import osclass FileHandle: #获取文件内容 def get_content(self,path): f = open(path,"r") #设置文件工具 content = f.read() #将txt文件的所有内容读入到字符串str中 f.close() #将文件关闭 return content#获取文件内容 def get_text(self): file_path=os.path.dirname(__file__) #当前文件所在目录 txt_path=file_path+r'textsrc' #txt目录 rootdir=os.path.join(txt_path) #目的目录内容 local_text={} # 读txt 文件 for (dirpath,dirnames,filenames) in os.walk(rootdir): for filename in filenames: if os.path.splitext(filename)[1]=='.txt': flag_file_path=dirpath+'\'+filename #文件路径 flag_file_content=self.get_content(flag_file_path) #读文件路径 if flag_file_content!='': local_text[filename.replace('.txt', '')]=flag_file_content #键值对内容 return local_text 本文最终使用方法如下:from Manage import Managewhite_list=['blog.csdn.net/A757291228','www.cnblogs.com/1-bit','blog.csdn.net/csdnnews']#白名单#设置信息conf={ 'engine':'baidu', 'target_page':5 'white_list':white_list, }print(Manage(conf).get_local_analyse())。


本文关键词:欧宝app,python,手把手,教你,基于,搜索引擎,实现,文章

本文来源:欧宝app-www.gerbertradefinance.com

Copyright © 2000-2021 www.gerbertradefinance.com. 欧宝app科技 版权所有 备案号:ICP备95133827号-6

在线客服 联系方式 二维码

服务热线

038-92295073

扫一扫,关注我们