python 基于搜索引擎实现文章查重
前言
文章抄袭在互联网中普遍存在,很多博主都收受其烦。近几年随着互联网的发展,抄袭等不道德行为在互联网上愈演愈烈,甚至复制、黏贴后发布标原创屡见不鲜,部分抄袭后的文章甚至标记了一些联系方式从而使读者获取源码等资料。这种恶劣的行为使人愤慨。
本文使用搜索引擎结果作为文章库,再与本地或互联网上数据做相似度对比,实现文章查重;由于查重的实现过程与一般情况下的微博情感分析实现流程相似,从而轻易的扩展出情感分析功能(下一篇将在此篇代码的基础上完成数据采集、清洗到情感分析的整个过程)。
由于近期时间上并不充裕,暂时实现了主要功能,细节上并没有进行优化,但是在代码结构上进行了一些简要的设计,使得之后的功能扩展、升级更为简便。我本人也将会持续更新该工具的功能,争取让这个工具在技术上更加的成熟、实用。
技术
微博情感分析基于sklearn,使用朴素贝叶斯完成对数据的情感分析;在数据抓取上,实现流程与文本查重的功能类似。
测试代码获取
CSDN codechina 代码仓库:https://codechina.csdn.net/A757291228/s-analysetooldemo
环境
一、实现文本查重
1.1 selenium安装配置
由于使用的selenium,在使用前需要确保读者是否已安装selenium,使用pip命令,安装如下:
pip install selenium
- 谷歌浏览器驱动:驱动版本需要对应浏览器版本,不同的浏览器使用对应不同版本的驱动,点击下载
- 如果是使用火狐浏览器,查看火狐浏览器版本,点击
GitHub火狐驱动下载地址
下载(英文不好的同学右键一键翻译即可,每个版本都有对应浏览器版本的使用说明,看清楚下载即可)
安装了selenium后新建一python文件名为selenium_search,先在代码中引入
from selenium import webdriver
可能有些读者没有把驱动配置到环境中,接下来我们可以指定驱动的位置(博主已配置到环境中):
driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
新建一个变量url赋值为百度首页链接,使用get方法传入url地址,尝试打开百度首页,完整代码如下:
from selenium import webdriverurl='https://www.baidu.com'
driver=webdriver.Chrome()
driver.get(url)
1.2 selenium百度搜索引擎关键词搜索
input=driver.find_element_by_id('kw')
获取元素对象后,使用send_keys方法可传入需要键入的值:
input.send_keys('php基础教程 第十一步 面向对象')
在此我传入了 “php基础教程 第十一步 面向对象”作为关键字作为搜索。运行脚本查看是否在搜索框中键入了关键字。代码如下:
input.send_keys('php基础教程 第十一步 面向对象')
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
from bs4 import BeautifulSoup
html=driver.page_source
soup = BeautifulSoup(html, "html.parser")
search_res_list=soup.select('.t')
在select方法中传入类名t,在类名前加上一个点(.)表示是通过类名获取元素。
完成这一步后可以添加print尝试打印出结果:
print(search_res_list)
time.sleep(2)
from selenium import webdriver
from bs4 import BeautifulSoup
import 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)
for el in search_res_list:print(el.a)
从结果中很明显的看出搜索结果的a标签已经获取,那么接下来我们需要的是提取每个a标签内的href超链接。获取href超链接直接使用列表获取元素的方式获取即可:
for el in search_res_list:print(el.a['href'])
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 = handle
driver.switch_to.window(handle_exchange)#切换
切换后,操作对象为当前刚打开的页面。通过current_url属性拿到新页面的url:
real_url=driver.current_url
print(real_url)
driver.close()
driver.switch_to.window(handle_this)#换回最初始界面
运行脚本成功获取到真实url:
最后在获取到真实url后使用一个列表将结果存储:
real_url_list.append(real_url)
from selenium import webdriver
from bs4 import BeautifulSoup
import 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')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 = handledriver.switch_to.window(handle_exchange)#切换real_url=driver.current_urlprint(real_url)real_url_list.append(real_url)#存储结果driver.close()driver.switch_to.window(handle_this)
1.4 获取源文本
def read_txt(path=''):f = open(path,'r')return f.read()
src=read_txt(r'F:\tool\textsrc\src.txt')
为了方便测试,这里使用是绝对路径。
获取到文本内容后,编写余弦相似度的对比方法。
1.5 余弦相似度
相似度计算参考文章《python实现余弦相似度文本比较》,本人修改一部分从而实现。
from jieba import lcut
import jieba.analyse
import collections
#分词
def Count(self,text):tag = jieba.analyse.textrank(text,topK=20)word_counts = collections.Counter(tag) #计数统计return word_counts
Count方法接收一个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 = chif word in MergeWord:TF1[MergeWord.index(word)] = TermFrequencereturn TF1
def cosine_similarity(self,vector1, vector2):dot_product = 0.0normA = 0.0normB = 0.0for a, b in zip(vector1, vector2):#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现dot_product += a * b normA += a ** 2normB += b ** 2if normA == 0.0 or normB == 0.0:return 0else: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))
from jieba import lcut
import jieba.analyse
import 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 = chif word in MergeWord:TF1[MergeWord.index(word)] = TermFrequencereturn TF1#计算 TF-IDFdef cosine_similarity(self,vector1, vector2):dot_product = 0.0normA = 0.0normB = 0.0for a, b in zip(vector1, vector2):#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现dot_product += a * b normA += a ** 2normB += b ** 2if normA == 0.0 or normB == 0.0:return 0else:return round(dot_product / ((normA**0.5)*(normB**0.5))*100, 2)
1.6 搜索结果内容与文本做相似度对比
在selenium_search文件中引入Analyse,并且新建对象:
from Analyse import Analyse
Analyse=Analyse()
time.sleep(5)
html_2=driver.page_source
使用 time.sleep(5)
是为了等待浏览器能够有时间渲染当前web内容。获取到新打开的页面内容后,进行相似度对比:
Analyse.get_Tfidf(src,html_2)
print('相似度:',Analyse.get_Tfidf(src,html_2))
from selenium import webdriver
from bs4 import BeautifulSoup
import time
from Analyse import Analysedef read_txt(path=''):f = open(path,'r')return f.read()#获取对比文件
src=read_txt(r'F:\tool\textsrc\src.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_source
soup = 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 = handledriver.switch_to.window(handle_exchange)#切换real_url=driver.current_urltime.sleep(5)html_2=driver.page_sourceprint('相似度:',Analyse.get_Tfidf(src,html_2))print(real_url)real_url_list.append(real_url)driver.close()driver.switch_to.window(handle_this)
运行脚本:
结果显示有几个高度相似的链接,那么这几个就是疑似抄袭的文章了。
以上是完成基本查重的代码,但是相对于说代码比较冗余、杂乱,接下来我们优化一下代码。
二、代码优化
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()
#搜索内容写入到搜素引擎中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_sourcesoup = 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 = handleself.browser.switch_to.window(handle_exchange) #切换real_url=self.browser.current_urltime.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() #输入搜索kwself.click_search_btn() #点击搜索return self.get_search_res_url() #获取web页搜索数据
最后添加一个search方法,直接调用search方法即可实现之前的所有操作,不用暴露过多简化使用。
完整代码如下:
from selenium import webdriver
from bs4 import BeautifulSoup
from SearchEngine import EngineConfManage
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import timeclass Browser:def __init__(self,conf):self.browser=webdriver.Chrome()self.conf=confself.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_sourcesoup = 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 = handleself.browser.switch_to.window(handle_exchange) #切换real_url=self.browser.current_urltime.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() #输入搜索kwself.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 Browser
from Analyse import Analyse
def read_txt(path=''):f = open(path,'r')return f.read()
src=read_txt(r'F:\tool\textsrc\src.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]))
from Browser import Browser
from Analyse import Analysedef read_txt(path=''):f = open(path,'r')return f.read()src=read_txt(r'F:\tool\textsrc\src.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
3.2BrowserManage类
在Browser类文件中添加一个BrowserManage类继承于Browser,添加方法:
#打开目标搜索引擎进行搜索def search(self):self.browser.get(self.engine_conf['website']) #打开搜索引擎站点self.send_keyword() #输入搜索kwself.click_search_btn() #点击搜索return self.get_search_res_url() #获取web页搜索数据
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 不一致 默认非第一页xpathtry: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=0while md5==hashlib.md5(self.browser.page_source.encode(encoding='UTF-8')).hexdigest():#md5 对比time.sleep(0.3)#防止一些错误,暂时使用强制停止保持一些稳定i+=1if i>100:return Falsereturn True
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_sourcesoup = 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 = handleself.browser.switch_to.window(handle_exchange) #切换real_url=self.browser.current_urlif real_url in self.conf['white_list']: #白名单continuetime.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
while 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 BrowserManage
from Analyse import Analyse
from 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]=resreturn resdic
所有完整的代码如下
from jieba import lcut
import jieba.analyse
import collections
from 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 = chif word in MergeWord:TF1[MergeWord.index(word)] = TermFrequencereturn TF1#计算 TF-IDFdef cosine_similarity(self,vector1, vector2):dot_product = 0.0normA = 0.0normB = 0.0for a, b in zip(vector1, vector2):#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现dot_product += a * b normA += a ** 2normB += b ** 2if normA == 0.0 or normB == 0.0:return 0else:return round(dot_product / ((normA**0.5)*(normB**0.5))*100, 2)
from selenium import webdriver
from bs4 import BeautifulSoup
from SearchEngine import EngineConfManage
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import hashlib
import time
import xlwtclass Browser:def __init__(self,conf):self.browser=webdriver.Chrome()self.conf=confself.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_sourcesoup = 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 = handleself.browser.switch_to.window(handle_exchange) #切换real_url=self.browser.current_urlif real_url in self.conf['white_list']: #白名单continuetime.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 不一致 默认非第一页xpathtry: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=0while md5==hashlib.md5(self.browser.page_source.encode(encoding='UTF-8')).hexdigest():#md5 对比time.sleep(0.3)#防止一些错误,暂时使用强制停止保持一些稳定i+=1if i>100:return Falsereturn True
class BrowserManage(Browser): #打开目标搜索引擎进行搜索def search(self):self.browser.get(self.engine_conf['website']) #打开搜索引擎站点self.send_keyword() #输入搜索kwself.click_search_btn() #点击搜索return self.get_search_res_url() #获取web页搜索数据
from Browser import BrowserManage
from Analyse import Analyse
from 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]=resreturn resdic
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())
此文转载请注明原文地址:https://blog.csdn.net/A757291228
CSDN:@1_bit
python 基于搜索引擎实现文章查重相关推荐
- python文章抄袭检测_CSDN文章被洗稿、抄袭严重!用Python做一个“基于搜索引擎的文章查重工具”,解决!...
前言 文章抄袭在互联网中普遍存在,很多博主.号主深受其烦. 近几年随着互联网的发展,抄袭等不道德行为在互联网上愈演愈烈,甚至复制.黏贴后发布标原创屡见不鲜,部分抄袭后的文章,甚至标记了一些联系方式从而 ...
- python 手把手教你基于搜索引擎实现文章查重
前言 文章抄袭在互联网中普遍存在,很多博主都收受其烦.近几年随着互联网的发展,抄袭等不道德行为在互联网上愈演愈烈,甚至复制.黏贴后发布标原创屡见不鲜,部分抄袭后的文章甚至标记了一些联系方式从而使读者获 ...
- CSDN文章被洗稿、抄袭严重!用Python做一个“基于搜索引擎的文章查重工具”,解决!...
公众号后台回复"图书",了解更多号主新书内容 作者: 1_bit 原文链接:http://suo.im/5V1JpX 前言 文章抄袭在互联网中普遍存在,很多博主.号主深受其烦. 近 ...
- 做自媒体进行文章查重的工具哪个好?操作方便快捷吗?
做自媒体不仅要学会内容输出,还需要学会使用工具,使用工具能够让你的工作效率事半功倍,其实当你选择做了自媒体,那么就要在这块领域深耕,不断去学习,不断去进步,这样你才会发展的越来越好. 其实做自媒体,没 ...
- opencv图像配准_Milvus 实战 | 基于 Milvus 的图像查重系统
背景介绍 由于巨大的利益,论文造假屡见不鲜,在部分国家或地区甚至形成了论文造假的产业链.目前大部分论文查重系统只能检查论文文字,不能检查图片.因此,论文图片查重已然成为了学术论文原创性检测的重要部分. ...
- 毕业设计基于Springboot框架作业查重系统2.0版本
作业查重系统2.0版本 文章目录 作业查重系统2.0版本 前言 一.摘要 二.相关技术 1.系统框架 2.查重功能简介 3.相似度检测算法简介 4.系统功能架构图 三.系统功能运行图 1.登录 2.学 ...
- Milvus 实战 | 基于 Milvus 的图像查重系统
背景介绍 由于巨大的利益,论文造假屡见不鲜,在部分国家或地区甚至形成了论文造假的产业链.目前大部分论文查重系统只能检查论文文字,不能检查图片.因此,论文图片查重已然成为了学术论文原创性检测的重要部 ...
- Python 计算MD5值 图片查重去重
MD5 MD5 即 Message-Digest Algorithm 5(信息-摘要算法5).摘要算法又称哈希算法.散列算法. 它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进 ...
- 【NLP】Python实例:基于文本相似度对申报项目进行查重设计
Python实例:申报项目查重系统设计与实现 作者:白宁超 2017年5月18日17:51:37 摘要:关于查重系统很多人并不陌生,无论本科还是硕博毕业都不可避免涉及论文查重问题,这也对学术不正之风起 ...
最新文章
- 电源符号VCC、VDD、VEE、VSS都是什么意思?有何区别?
- jupyter notebook上完美运行tensorflow、keras
- 液态金属和Liquidmetal公司
- 谈论Java原子变量和同步的效率 -- 颠覆你的生活
- MyEclipse生成Javadoc帮助文档
- MATLAB GUI如何创建Callback函数
- 第三次小组实践作业小组每日进度汇报:2017-12-3
- 让数据可视化告诉你,中秋吃这样的月饼绝对没错
- Storm入门学习随记
- Visual Studio 链接 Sql Sever 提示启动进程时出错 -解决方案
- Tip: Unicode Debug和Debug有什么区别?
- python 高斯烟羽模型_高斯扩散模型-高斯烟羽大气污染扩散模型
- ofd阅读器qt_OFD编辑器实例
- 大数据智能算法及测评技术
- 【R语言】rep用法(自用)
- Kent Beck揭秘Facebook开发部署流程
- 报考华为认证考试流程
- could not write file:C:\Users\user\Desktop\KunMing40m\KunMing40m\.classpath
- 【考研英语语法】状语从句精讲
- 测试打呼噜的软件,打呼噜人群福音!这款app能检测鼾声并提供一站式止鼾方案...