• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

利用Python制作文章查重系统

python 搞java代码 3年前 (2022-05-21) 31次浏览 已收录 0个评论
文章目录[隐藏]

本文使用搜索引擎结果作为文章库,再与本地或互联网上数据做相似度对比,实现文章查重;由于查重的实现过程与一般情况下的微博情感分析实现流程相似,从而轻易的扩展出情感分析功能(下一篇将在此篇代码的基础上完成数据采集、清洗到情感分析的整个过程)。

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771

由于近期时间上并不充裕,暂时实现了主要功能,细节上并没有进行优化,但是在代码结构上进行了一些简要的设计,使得之后的功能扩展、升级更为简便。我本人也将会持续更新该工具的功能,争取让这个工具在技术上更加的成熟、实用。

技术

本文实现的查重功能为了考虑适配大多数站点,从而使用 selenium 用作数据获取,配置不同搜索引擎的信息,实现较为通用的搜索引擎查询,并且不需要考虑过多的动态数据抓取;分词主要使用 jieba 库,完成对中文语句的分词;使用余弦相似度完成文本相似度的对比并导出对比数据至 Excel 文章留作举报信息。

微博情感分析基于 sklearn ,使用朴素贝叶斯完成对数据的情感分析;在数据抓取上,实现流程与文本查重的功能类似。

测试代码获取

CSDN codechina 代码仓库: https://codechina.csdn.net/A757291228/s-analysetooldemo

环境

作者的环境说明如下:

  • 操作系统:Windows7 SP1 64
  • python 版本:3.7.7
  • 浏览器:谷歌浏览器
  • 浏览器版本: 80.0.3987 (64 位)

如有错误欢迎指出,欢迎留言交流。

一、实现文本查重

1.1 selenium安装配置

由于使用的 selenium ,在使用前需要确保读者是否已安装 selenium ,使用 pip 命令,安装如下:

<span class="hljs-attribute">pip install selenium</span>

www#gaodaima.com来源gaodai$ma#com搞$$代**码网搞代码

安装完成 Selenium 还需要下载一个驱动。

  • 谷歌浏览器驱动:驱动版本需要对应浏览器版本,不同的浏览器使用对应不同版本的驱动,点击 下载
  • 如果是使用火狐浏览器,查看火狐浏览器版本,点击 
    GitHub火狐驱动下载地址 
    下载(英文不好的同学右键一键翻译即可,每个版本都有对应浏览器版本的使用说明,看清楚下载即可)

安装了 selenium 后新建一 python 文件名为 selenium_search ,先在代码中引入

<span class="hljs-keyword">from selenium <span class="hljs-keyword">import webdriver</span></span>

可能有些读者没有把驱动配置到环境中,接下来我们可以指定驱动的位置(博主已配置到环境中):

driver = webdriver.Chrome(executable_path=<span class="hljs-string">r"F:pythondrchromedriver_win32chromedriver.exe")</span>

新建一个变量 url 赋值为百度首页链接,使用 get 方法传入 url 地址,尝试打开百度首页,完整代码如下:

from selenium <span class="hljs-keyword">import webdriver

url="https:<span class="hljs-comment">//www.baidu.com"
driver=webdriver.<span class="hljs-type">Chrome()
driver.<span class="hljs-keyword">get(url)</span></span></span></span>

在小黑框中使用命令行运行python文件( windows 下):

运行脚本后将会打开谷歌浏览器并跳转至百度首页:

这样就成功使用 selenium 打开了指定网址,接下来将指定搜索关键词查询得到结果,再从结果中遍历到相似数据。

1.2 selenium百度搜索引擎关键词搜索

在自动操控浏览器进行关键字键入到搜索框前,需要获取搜索框元素对象。使用谷歌浏览器打开百度首页,右键搜索框选择查看,将会弹出网页元素(代码)查看视窗,找到搜索框元素(使用鼠标在元素节点中移动,鼠标当前位置的元素节点将会对应的在网页中标蓝):

在html代码中,id的值大多数情况下唯一(除非是打错了),在此选择id作为获取搜索框元素对象的标记。 selenium 提供了 find_element_by_id 方法,可以通过传入 id 获取到网页元素对象。

<span class="hljs-attr">input=driver.find_element_by_id(<span class="hljs-string">"kw")</span></span>

获取元素对象后,使用send_keys方法可传入需要键入的值:

<span class="hljs-selector-tag">input<span class="hljs-selector-class">.send_keys(<span class="hljs-string">"php基础教程 第十一步 面向对象")</span></span></span>

在此我传入了 “ php基础教程 第十一步 面向对象 ”作为关键字作为搜索。运行脚本查看是否在搜索框中键入了关键字。代码如下:

<span class="hljs-selector-tag">input<span class="hljs-selector-class">.send_keys(<span class="hljs-string">"php基础教程 第十一步 面向对象")</span></span></span>

成功打开浏览器并键入了搜索关键字:

现在还差点击“百度一下”按钮完成最终的搜索。使用与查看搜索框相同的元素查看方法查找“百度一下”按钮的id值:

使用 find_element_by_id 方法获取到该元素对象,随后使用click方法使该按钮完成点击操作:

search_btn=driver.find_element_by_id(<span class="hljs-string">"su")
search_btn.click()</span>

完整代码如下:

from selenium import webdriver

url=<span class="hljs-string">"https://www.baidu.com"
driver=webdriver.Chrome()
driver.<span class="hljs-built_in">get(url)
<span class="hljs-built_in">input=driver.find_element_by_id(<span class="hljs-string">"kw")
<span class="hljs-built_in">input.send_keys(<span class="hljs-string">"php基础教程 第十一步 面向对象")
search_btn=driver.find_element_by_id(<span class="hljs-string">"su")
search_btn.click()</span></span></span></span></span></span></span>

浏览器自动完成了键入搜索关键字及搜索功能:

1.3 搜索结果遍历

当前已在浏览器中得到了搜索结果,接下来需要获取整个 web 页面内容,得到搜索结果。使用selenium并不能很方便的获取到,在这里使用 BeautifulSoup 对整个 web 页面进行解析并获取搜索结果。

BeautifulSoup是一个 HTML/XML 解析器,使用 BeautifulSoup 会极大的方便我们对整个 html的信息获取。

使用 BeautifulSoup 前需确保已安装。安装命令如下:

<span class="hljs-attribute">pip install BeautifulSoup</span>

安装后,在当前 python 文件头部引入:

<span class="hljs-keyword">from bs4 <span class="hljs-keyword">import BeautifulSoup</span></span>

获取 html 文本可以调用page_source即可:

<span class="hljs-attr">html=driver.page_source</span>

得到了 html 代码后,新建 BeautifulSoup 对象,传入 html 内容并且指定解析器,这里指定使用 html.parser 解析器:

<span class="hljs-attr">soup = BeautifulSoup(html, <span class="hljs-string">"html.parser")</span></span>

接下来查看搜索内容,发现所有的结果都由一个 h 标签包含,并且 class 为 t :

BeautifulSoup提供了select方法对标签进行获取,支持通过类名、标签名、id、属性、组合查找等。我们发现百度搜索结果中,结果皆有一个class =”t”,此时可以通过类名进行遍历获取最为简便:

<span class="hljs-attr">search_res_list=soup.select(<span class="hljs-string">".t")</span></span>

在 select 方法中传入类名 t ,在类名前加上一个点( . )表示是通过类名获取元素。

完成这一步后可以添加print尝试打印出结果:

print(<span class="hljs-name">search_res_list)</span>

一般情况下,可能输出search_res_list为空列表,这是因为我们在浏览器解析数据渲染到浏览器前已经获取了浏览器当前页的内容,这时有一个简单的方法可以解决这个问题,但是此方法效率却不高,在此只是暂时使用,之后将会用其它效率高于此方法的代码替换(使用time需要在头部引入):

<span class="hljs-selector-tag">time<span class="hljs-selector-class">.sleep(<span class="hljs-number">2)</span></span></span>

完整代码如下:

<span class="hljs-keyword">from selenium <span class="hljs-keyword">import webdriver
<span class="hljs-keyword">from bs4 <span class="hljs-keyword">import BeautifulSoup
<span class="hljs-keyword">import time

url=<span class="hljs-string">"https://www.baidu.com"
driver=webdriver.Chrome()
driver.get(url)
input=driver.find_element_by_id(<span class="hljs-string">"kw")
input.send_keys(<span class="hljs-string">"php基础教程 第十一步 面向对象")
search_btn=driver.find_element_by_id(<span class="hljs-string">"su")
search_btn.click()

time.sleep(<span class="hljs-number">2)<span class="hljs-comment">#在此等待 使浏览器解析并渲染到浏览器

html=driver.page_source <span class="hljs-comment">#获取网页内容
soup = BeautifulSoup(html, <span class="hljs-string">"html.parser")
search_res_list=soup.select(<span class="hljs-string">".t")
print(search_res_list)</span></span></span></span></span></span></span></span></span></span></span></span></span></span>

运行程序将会输出内容:

获取到的结果为所有class为t的标签,包括该标签的子节点,并且使用点(.)运算发可以获取子节点元素。通过浏览器得到的搜索内容皆为链接,点击可跳转,那么只需要获取每一个元素下的a标签即可:

<span class="hljs-keyword">for <span class="hljs-keyword">el in search_res_lis<span class="hljs-variable">t:
    <span class="hljs-keyword">print(<span class="hljs-keyword">el.<span class="hljs-keyword">a)</span></span></span></span></span></span>

从结果中很明显的看出搜索结果的a标签已经获取,那么接下来我们需要的是提取每个a标签内的href超链接。获取href超链接直接使用列表获取元素的方式获取即可:

<span class="hljs-keyword">for <span class="hljs-keyword">el in search_res_lis<span class="hljs-variable">t:
    <span class="hljs-keyword">print(<span class="hljs-keyword">el.<span class="hljs-keyword">a[<span class="hljs-string">"href"])</span></span></span></span></span></span></span>

运行脚本成功得到结果:

细心的读者可能会发现,这些获取到的结果中,都是baidu的网址。其实这些网址可以说是“索引”,通过这些索引再次跳转到真实网址。由于这些“索引”不一定会变动,并不利于长期存储,在此还是需要获取到真实的链接。

我们调用js脚本对这些网址进行访问,这些网址将会跳转到真实网址,跳转后再获取当前的网址信息即可。调用execute_script方法可执行js代码,代码如下:

<span class="hljs-keyword">for <span class="hljs-keyword">el in search_res_lis<span class="hljs-variable">t:
    js = <span class="hljs-string">"window.open(""+<span class="hljs-keyword">el.<span class="hljs-keyword">a[<span class="hljs-string">"href"]+<span class="hljs-string">"")"
    driver.execute_script(js)</span></span></span></span></span></span></span></span>

打开新的网页后,需要获取新网页的句柄,否则无法操控新网页。获取句柄的方法如下:

<span class="hljs-attr">handle_this=driver.current_window_handle#获取当前句柄
<span class="hljs-attr">handle_all=driver.window_handles#获取所有句柄</span></span>

获取句柄后需要把当前操作的对象切换成新的页面。由于打开一个页面后所有页面只有2个,简单的使用遍历做一个替换:

handle_exchange=<span class="hljs-keyword">None<span class="hljs-comment">#要切换的句柄
<span class="hljs-keyword">for handle <span class="hljs-keyword">in handle_all:<span class="hljs-comment">#不匹配为新句柄
   <span class="hljs-keyword">if handle != handle_this:<span class="hljs-comment">#不等于当前句柄就交换
        handle_exchange = handle
driver.switch_to.window(handle_exchange)<span class="hljs-comment">#切换</span></span></span></span></span></span></span></span>

切换后,操作对象为当前刚打开的页面。通过current_url属性拿到新页面的url:

real_url=driver.current_url
<span class="hljs-built_in">print(real_url)</span>

随后关闭当前页面,把操作对象置为初始页面:

<span class="hljs-selector-tag">driver<span class="hljs-selector-class">.close()
<span class="hljs-selector-tag">driver<span class="hljs-selector-class">.switch_to<span class="hljs-selector-class">.window(<span class="hljs-selector-tag">handle_this)#换回最初始界面</span></span></span></span></span></span>

运行脚本成功获取到真实url:

最后在获取到真实url后使用一个列表将结果存储:

<span class="hljs-selector-tag">real_url_list<span class="hljs-selector-class">.append(real_url)</span></span>

这一部分完整代码如下:

<span class="hljs-keyword">from selenium <span class="hljs-keyword">import webdriver
<span class="hljs-keyword">from bs4 <span class="hljs-keyword">import BeautifulSoup
<span class="hljs-keyword">import time

url=<span class="hljs-string">"https://www.baidu.com"
driver=webdriver.Chrome()
driver.get(url)
input=driver.find_element_by_id(<span class="hljs-string">"kw")
input.send_keys(<span class="hljs-string">"php基础教程 第十一步 面向对象")
search_btn=driver.find_element_by_id(<span class="hljs-string">"su")
search_btn.click()

time.sleep(<span class="hljs-number">2)<span class="hljs-comment">#在此等待 使浏览器解析并渲染到浏览器

html=driver.page_source
soup = BeautifulSoup(html, <span class="hljs-string">"html.parser")
search_res_list=soup.select(<span class="hljs-string">".t")

real_url_list=[]
<span class="hljs-comment"># print(search_res_list)
<span class="hljs-keyword">for el <span class="hljs-keyword">in search_res_list:
    js = <span class="hljs-string">"window.open(""+el.a[<span class="hljs-string">"href"]+<span class="hljs-string">"")"
    driver.execute_script(js)
    handle_this=driver.current_window_handle<span class="hljs-comment">#获取当前句柄
    handle_all=driver.window_handles<span class="hljs-comment">#获取所有句柄
    handle_exchange=None<span class="hljs-comment">#要切换的句柄
    <span class="hljs-keyword">for handle <span class="hljs-keyword">in handle_all:<span class="hljs-comment">#不匹配为新句柄
        <span class="hljs-keyword">if handle != handle_this:<span class="hljs-comment">#不等于当前句柄就交换
            handle_exchange = handle
    driver.switch_to.<span class="hljs-built_in">window(handle_exchange)<span class="hljs-comment">#切换
    real_url=driver.current_url
    <span class="hljs-built_in">print(real_url)
    real_url_list.append(real_url)<span class="hljs-comment">#存储结果
    driver.close()
    driver.switch_to.<span class="hljs-built_in">window(handle_this)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

1.4 获取源文本

在当前文件的目录下新建一个文件夹,命名为textsrc,在该目录下创建一个txt文件,把需要对比的文本存放至该文本中。在此我存放的内容为文章“ php基础教程 第十一步 面向对象 ”的内容。

在代码中编写一个函数为获取文本内容:

<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">read_txt<span class="hljs-params">(path=<span class="hljs-string">""):
    f = open(path,<span class="hljs-string">"r")
    <span class="hljs-keyword">return f.read()
src=read_txt(<span class="hljs-string">r"F:	ool	extsrcsrc.txt")</span></span></span></span></span></span></span></span>

为了方便测试,这里使用是绝对路径。

获取到文本内容后,编写余弦相似度的对比方法。

1.5 余弦相似度

相似度计算参考文章 《python实现余弦相似度文本比较》 ,本人修改一部分从而实现。

本文相似度对比使用余弦相似度算法,一般步骤分为分词->向量计算->计算相似度。

新建一个python文件,名为Analyse。新建一个类名为Analyse,在类中添加分词方法,并在头部引入jieba分词库,以及collections统计次数:

<span class="hljs-title">from jieba <span class="hljs-keyword">import lcut
<span class="hljs-keyword">import jieba.analyse
<span class="hljs-keyword">import collections</span></span></span></span>

Count方法:

<span class="hljs-comment">#分词
<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">Count<span class="hljs-params">(self,text):
    tag = jieba.analyse.textrank(text,topK=<span class="hljs-number">20)
    word_counts = collections.Counter(tag) <span class="hljs-comment">#计数统计
    <span class="hljs-keyword">return word_counts</span></span></span></span></span></span></span></span>

Count方法接收一个text变量,text变量为文本,使用textrank方法分词并且使用Counter计数。

随后添加MergeWord方法,使词合并方便之后的向量计算:

<span class="hljs-comment">#词合并
<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">MergeWord<span class="hljs-params">(self,T1,T2):
    MergeWord = []
    <span class="hljs-keyword">for i <span class="hljs-keyword">in T1:
        MergeWord.append(i)
    <span class="hljs-keyword">for i <span class="hljs-keyword">in T2:
        <span class="hljs-keyword">if i <span class="hljs-keyword">not <span class="hljs-keyword">in MergeWord:
            MergeWord.append(i)
    <span class="hljs-keyword">return MergeWord</span></span></span></span></span></span></span></span></span></span></span></span></span>

合并方法很简单不再做解释。接下来添加向量计算方法:

<span class="hljs-comment"># 得出文档向量
<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">CalVector<span class="hljs-params">(self,T1,MergeWord):
   TF1 = [<span class="hljs-number">0] * len(MergeWord)
   <span class="hljs-keyword">for ch <span class="hljs-keyword">in T1:
       TermFrequence = T1[ch]
       word = ch
       <span class="hljs-keyword">if word <span class="hljs-keyword">in MergeWord:
           TF1[MergeWord.index(word)] = TermFrequence
   <span class="hljs-keyword">return TF1</span></span></span></span></span></span></span></span></span></span></span>

最后添加相似度计算方法:

<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">cosine_similarity<span class="hljs-params">(self,vector1, vector2):
    dot_product = <span class="hljs-number">0.0
    normA = <span class="hljs-number">0.0
    normB = <span class="hljs-number">0.0

    <span class="hljs-keyword">for a, b <span class="hljs-keyword">in zip(vector1, vector2):<span class="hljs-comment">#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现
        dot_product += a * b    
        normA += a ** <span class="hljs-number">2
        normB += b ** <span class="hljs-number">2
    <span class="hljs-keyword">if normA == <span class="hljs-number">0.0 <span class="hljs-keyword">or normB == <span class="hljs-number">0.0:
        <span class="hljs-keyword">return <span class="hljs-number">0
    <span class="hljs-keyword">else:
        <span class="hljs-keyword">return round(dot_product / ((normA**<span class="hljs-number">0.5)*(normB**<span class="hljs-number">0.5))*<span class="hljs-number">100, <span class="hljs-number">2)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

相似度方法接收两个向量,随后计算相似度并返回。为了代码冗余度少,在这里先简单的添加一个方法,完成计算流程:

<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_Tfidf<span class="hljs-params">(self,text1,text2):<span class="hljs-comment">#测试对比本地数据对比搜索引擎方法
        <span class="hljs-comment"># self.correlate.word.set_this_url(url)
        T1 = self.Count(text1)
        T2 = self.Count(text2)
        mergeword = self.MergeWord(T1,T2)
        <span class="hljs-keyword">return self.cosine_similarity(self.CalVector(T1,mergeword),self.CalVector(T2,mergeword))</span></span></span></span></span></span></span>

Analyse类的完整代码如下:

<span class="hljs-keyword">from jieba <span class="hljs-keyword">import lcut
<span class="hljs-keyword">import jieba.analyse
<span class="hljs-keyword">import collections

<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Analyse:
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_Tfidf<span class="hljs-params">(self,text1,text2):<span class="hljs-comment">#测试对比本地数据对比搜索引擎方法
        <span class="hljs-comment"># self.correlate.word.set_this_url(url)
        T1 = self.Count(text1)
        T2 = self.Count(text2)
        mergeword = self.MergeWord(T1,T2)
        <span class="hljs-keyword">return self.cosine_similarity(self.CalVector(T1,mergeword),self.CalVector(T2,mergeword))
        
    <span class="hljs-comment">#分词
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">Count<span class="hljs-params">(self,text):
        tag = jieba.analyse.textrank(text,topK=<span class="hljs-number">20)
        word_counts = collections.Counter(tag) <span class="hljs-comment">#计数统计
        <span class="hljs-keyword">return word_counts
    <span class="hljs-comment">#词合并
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">MergeWord<span class="hljs-params">(self,T1,T2):
        MergeWord = []
        <span class="hljs-keyword">for i <span class="hljs-keyword">in T1:
            MergeWord.append(i)
        <span class="hljs-keyword">for i <span class="hljs-keyword">in T2:
            <span class="hljs-keyword">if i <span class="hljs-keyword">not <span class="hljs-keyword">in MergeWord:
                MergeWord.append(i)
        <span class="hljs-keyword">return MergeWord
    <span class="hljs-comment"># 得出文档向量
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">CalVector<span class="hljs-params">(self,T1,MergeWord):
        TF1 = [<span class="hljs-number">0] * len(MergeWord)
        <span class="hljs-keyword">for ch <span class="hljs-keyword">in T1:
            TermFrequence = T1[ch]
            word = ch
            <span class="hljs-keyword">if word <span class="hljs-keyword">in MergeWord:
                TF1[MergeWord.index(word)] = TermFrequence
        <span class="hljs-keyword">return TF1
    <span class="hljs-comment">#计算 TF-IDF
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">cosine_similarity<span class="hljs-params">(self,vector1, vector2):
        dot_product = <span class="hljs-number">0.0
        normA = <span class="hljs-number">0.0
        normB = <span class="hljs-number">0.0

        <span class="hljs-keyword">for a, b <span class="hljs-keyword">in zip(vector1, vector2):<span class="hljs-comment">#两个向量组合成 [(1, 4), (2, 5), (3, 6)] 最短形式表现
            dot_product += a * b    
            normA += a ** <span class="hljs-number">2
            normB += b ** <span class="hljs-number">2
        <span class="hljs-keyword">if normA == <span class="hljs-number">0.0 <span class="hljs-keyword">or normB == <span class="hljs-number">0.0:
            <span class="hljs-keyword">return <span class="hljs-number">0
        <span class="hljs-keyword">else:
            <span class="hljs-keyword">return round(dot_product / ((normA**<span class="hljs-number">0.5)*(normB**<span class="hljs-number">0.5))*<span class="hljs-number">100, <span class="hljs-number">2)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

1.6 搜索结果内容与文本做相似度对比

在selenium_search文件中引入Analyse,并且新建对象:

<span class="hljs-keyword">from Analyse <span class="hljs-keyword">import Analyse
Analyse=Analyse()</span></span>

在遍历搜索结果中添加获取新打开后的页面的网页内容:

time.sleep(5)
html_2=driver.page_source

使用 time.sleep(5) 是为了等待浏览器能够有时间渲染当前web内容。获取到新打开的页面内容后,进行相似度对比:

<span class="hljs-selector-tag">Analyse<span class="hljs-selector-class">.get_Tfidf(src,html_2)</span></span>

由于返回的是一个值,使用print输出:

print("相似度:",Analyse.get_Tfidf(<span class="hljs-name">src,html_2))</span>

完整代码如下:

<span class="hljs-keyword">from selenium <span class="hljs-keyword">import webdriver
<span class="hljs-keyword">from bs4 <span class="hljs-keyword">import BeautifulSoup
<span class="hljs-keyword">import time
<span class="hljs-keyword">from Analyse <span class="hljs-keyword">import Analyse

<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">read_txt<span class="hljs-params">(path=<span class="hljs-string">""):
    f = open(path,<span class="hljs-string">"r")
    <span class="hljs-keyword">return f.read()

<span class="hljs-comment">#获取对比文件
src=read_txt(<span class="hljs-string">r"F:	ool	extsrcsrc.txt")
Analyse=Analyse()

url=<span class="hljs-string">"https://www.baidu.com"
driver=webdriver.Chrome()
driver.get(url)
input=driver.find_element_by_id(<span class="hljs-string">"kw")
input.send_keys(<span class="hljs-string">"php基础教程 第十一步 面向对象")
search_btn=driver.find_element_by_id(<span class="hljs-string">"su")
search_btn.click()

time.sleep(<span class="hljs-number">2)<span class="hljs-comment">#在此等待 使浏览器解析并渲染到浏览器

html=driver.page_source
soup = BeautifulSoup(html, <span class="hljs-string">"html.parser")
search_res_list=soup.select(<span class="hljs-string">".t")

real_url_list=[]
<span class="hljs-comment"># print(search_res_list)
<span class="hljs-keyword">for el <span class="hljs-keyword">in search_res_list:
    js = <span class="hljs-string">"window.open(""+el.a[<span class="hljs-string">"href"]+<span class="hljs-string">"")"
    driver.execute_script(js)
    handle_this=driver.current_window_handle<span class="hljs-comment">#获取当前句柄
    handle_all=driver.window_handles<span class="hljs-comment">#获取所有句柄
    handle_exchange=<span class="hljs-keyword">None<span class="hljs-comment">#要切换的句柄
    <span class="hljs-keyword">for handle <span class="hljs-keyword">in handle_all:<span class="hljs-comment">#不匹配为新句柄
        <span class="hljs-keyword">if handle != handle_this:<span class="hljs-comment">#不等于当前句柄就交换
            handle_exchange = handle
    driver.switch_to.window(handle_exchange)<span class="hljs-comment">#切换
    real_url=driver.current_url
    
    time.sleep(<span class="hljs-number">5)
    html_2=driver.page_source
    print(<span class="hljs-string">"相似度:",Analyse.get_Tfidf(src,html_2))
    
    print(real_url)
    real_url_list.append(real_url)
    driver.close()
    driver.switch_to.window(handle_this)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

运行脚本:

结果显示有几个高度相似的链接,那么这几个就是疑似抄袭的文章了。

以上是完成基本查重的代码,但是相对于说代码比较冗余、杂乱,接下来我们优化一下代码。

二、代码优化

通过以上的程序编程,简要步骤可以分为:获取搜索内容->获取结果->计算相似度。我们可以新建三个类,分别为:Browser、Analyse(已新建)、SearchEngine。

Browser用于搜索、数据获取等;Analyse用于相似度分析、向量计算等;SearchEngine用于不同搜索引擎的基本配置,因为大部分搜多引擎的搜索方式较为一致。

2.1Browser 类

初始化

新建一个python文件,名为Browser,添加初始化方法:

<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">__init__<span class="hljs-params">(self,conf):
        self.browser=webdriver.Chrome()
        self.conf=conf
        self.engine_conf=EngineConfManage().get_Engine_conf(conf[<span class="hljs-string">"engine"]).get_conf()</span></span></span></span></span>

self.browser=webdriver.Chrome() 为新建一个浏览器对象; conf 为传入的搜索配置,之后进行搜索内容由编写配置字典实现; self.engine_conf=EngineConfManage().get_Engine_conf(conf["engine"]).get_conf() 为获取搜索引擎的配置,不同搜索引擎的输入框、搜索按键不一致,通过不同的配置信息实现多搜索引擎搜索。

添加搜索方法

<span class="hljs-comment">#搜索内容写入到搜素引擎中
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">send_keyword<span class="hljs-params">(self):
        input = self.browser.find_element_by_id(self.engine_conf[<span class="hljs-string">"searchTextID"])
        input.send_keys(self.conf[<span class="hljs-string">"kw"])</span></span></span></span></span></span></span>

以上方法中 self.engine_conf["searchTextID"] 与 self.conf["kw"] 通过初始化方法得到对应的搜索引擎配置信息,直接获取信息得到元素。

点击搜索

<span class="hljs-comment">#搜索框点击
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">click_search_btn<span class="hljs-params">(self):
        search_btn = self.browser.find_element_by_id(self.engine_conf[<span class="hljs-string">"searchBtnID"])
        search_btn.click()</span></span></span></span></span></span>

通过使用 self.engine_conf["searchBtnID"] 获取搜索按钮的id。

获取搜索结果与文本

<span class="hljs-comment">#获取搜索结果与文本
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_search_res_url<span class="hljs-params">(<span class="hljs-keyword">self):
        res_link={}
        WebDriverWait(<span class="hljs-keyword">self.browser,timeout=<span class="hljs-number">30,poll_frequency=<span class="hljs-number">1).<span class="hljs-keyword">until(EC.presence_of_element_located((By.ID, <span class="hljs-string">"page")))
        <span class="hljs-comment">#内容通过 BeautifulSoup 解析
        content=<span class="hljs-keyword">self.browser.page_source
        soup = BeautifulSoup(content, <span class="hljs-string">"html.parser")
        search_res_list=soup.select(<span class="hljs-string">"."+<span class="hljs-keyword">self.engine_conf[<span class="hljs-string">"searchContentHref_class"])
        <span class="hljs-keyword">for el <span class="hljs-keyword">in <span class="hljs-symbol">search_res_list:
            js = <span class="hljs-string">"window.open(""+el.a[<span class="hljs-string">"href"]+<span class="hljs-string">"")"
            <span class="hljs-keyword">self.browser.execute_script(js)
            handle_this=<span class="hljs-keyword">self.browser.current_window_handle  <span class="hljs-comment">#获取当前句柄
            handle_all=<span class="hljs-keyword">self.browser.window_handles          <span class="hljs-comment">#获取所有句柄
            handle_exchange=None                            <span class="hljs-comment">#要切换的句柄
            <span class="hljs-keyword">for handle <span class="hljs-keyword">in <span class="hljs-symbol">handle_all:                       <span class="hljs-comment">#不匹配为新句柄
                <span class="hljs-keyword">if handle != <span class="hljs-symbol">handle_this:                   <span class="hljs-comment">#不等于当前句柄就交换
                    handle_exchange = handle
            <span class="hljs-keyword">self.browser.switch_to.window(handle_exchange)  <span class="hljs-comment">#切换
            real_url=<span class="hljs-keyword">self.browser.current_url
            
            time.sleep(<span class="hljs-number">1)
            res_link[real_url]=<span class="hljs-keyword">self.browser.page_source     <span class="hljs-comment">#结果获取
            
            <span class="hljs-keyword">self.browser.close()
            <span class="hljs-keyword">self.browser.switch_to.window(handle_this)
        <span class="hljs-keyword">return res_link</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

以上方法跟之前编写的遍历搜索结果内容相似,从中添加了 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=30 30秒,如果已过去则跳过等待。

以上代码中并不做相似度对比,而是通过 res_link[real_url]=self.browser.page_source 将内容与 url 存入字典,随后返回,之后再做相似度对比,这样编写利于之后的功能扩展。

打开目标搜索引擎进行搜索

<span class="hljs-comment">#打开目标搜索引擎进行搜索
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">search<span class="hljs-params">(self):
        self.browser.get(self.engine_conf[<span class="hljs-string">"website"])       <span class="hljs-comment">#打开搜索引擎站点
        self.send_keyword()                                 <span class="hljs-comment">#输入搜索kw
        self.click_search_btn()                             <span class="hljs-comment">#点击搜索
        <span class="hljs-keyword">return self.get_search_res_url()                    <span class="hljs-comment">#获取web页搜索数据</span></span></span></span></span></span></span></span></span></span></span>

最后添加一个 search 方法,直接调用 search 方法即可实现之前的所有操作,不用暴露过多简化使用。

完整代码如下:

<span class="hljs-keyword">from selenium <span class="hljs-keyword">import webdriver
<span class="hljs-keyword">from bs4 <span class="hljs-keyword">import BeautifulSoup
<span class="hljs-keyword">from SearchEngine <span class="hljs-keyword">import EngineConfManage
<span class="hljs-keyword">from selenium.webdriver.support.wait <span class="hljs-keyword">import WebDriverWait
<span class="hljs-keyword">from selenium.webdriver.support <span class="hljs-keyword">import expected_conditions <span class="hljs-keyword">as EC
<span class="hljs-keyword">from selenium.webdriver.common.by <span class="hljs-keyword">import By
<span class="hljs-keyword">import time

<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Browser:
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">__init__<span class="hljs-params">(self,conf):
        self.browser=webdriver.Chrome()
        self.conf=conf
        self.engine_conf=EngineConfManage().get_Engine_conf(conf[<span class="hljs-string">"engine"]).get_conf()
    <span class="hljs-comment">#搜索内容写入到搜素引擎中
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">send_keyword<span class="hljs-params">(self):
        input = self.browser.find_element_by_id(self.engine_conf[<span class="hljs-string">"searchTextID"])
        input.send_keys(self.conf[<span class="hljs-string">"kw"])
    <span class="hljs-comment">#搜索框点击
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">click_search_btn<span class="hljs-params">(self):
        search_btn = self.browser.find_element_by_id(self.engine_conf[<span class="hljs-string">"searchBtnID"])
        search_btn.click()
    <span class="hljs-comment">#获取搜索结果与文本
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_search_res_url<span class="hljs-params">(self):
        res_link={}
        WebDriverWait(self.browser,timeout=<span class="hljs-number">30,poll_frequency=<span class="hljs-number">1).until(EC.presence_of_element_located((By.ID, <span class="hljs-string">"page")))
        <span class="hljs-comment">#内容通过 BeautifulSoup 解析
        content=self.browser.page_source
        soup = BeautifulSoup(content, <span class="hljs-string">"html.parser")
        search_res_list=soup.select(<span class="hljs-string">"."+self.engine_conf[<span class="hljs-string">"searchContentHref_class"])
        <span class="hljs-keyword">for el <span class="hljs-keyword">in search_res_list:
            js = <span class="hljs-string">"window.open(""+el.a[<span class="hljs-string">"href"]+<span class="hljs-string">"")"
            self.browser.execute_script(js)
            handle_this=self.browser.current_window_handle  <span class="hljs-comment">#获取当前句柄
            handle_all=self.browser.window_handles          <span class="hljs-comment">#获取所有句柄
            handle_exchange=<span class="hljs-keyword">None                            <span class="hljs-comment">#要切换的句柄
            <span class="hljs-keyword">for handle <span class="hljs-keyword">in handle_all:                       <span class="hljs-comment">#不匹配为新句柄
                <span class="hljs-keyword">if handle != handle_this:                   <span class="hljs-comment">#不等于当前句柄就交换
                    handle_exchange = handle
            self.browser.switch_to.window(handle_exchange)  <span class="hljs-comment">#切换
            real_url=self.browser.current_url
            
            time.sleep(<span class="hljs-number">1)
            res_link[real_url]=self.browser.page_source     <span class="hljs-comment">#结果获取
            
            self.browser.close()
            self.browser.switch_to.window(handle_this)
        <span class="hljs-keyword">return res_link
    
    <span class="hljs-comment">#打开目标搜索引擎进行搜索
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">search<span class="hljs-params">(self):
        self.browser.get(self.engine_conf[<span class="hljs-string">"website"])       <span class="hljs-comment">#打开搜索引擎站点
        self.send_keyword()                                 <span class="hljs-comment">#输入搜索kw
        self.click_search_btn()                             <span class="hljs-comment">#点击搜索
        <span class="hljs-keyword">return self.get_search_res_url()                    <span class="hljs-comment">#获取web页搜索数据</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

2.2SearchEngine 类

SearchEngine类主要用于不同搜索引擎的配置编写。更加简便的实现搜索引擎或相似业务的扩展。

<span class="hljs-comment">#搜索引擎配置
<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">EngineConfManage:
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_Engine_conf<span class="hljs-params">(self,engine_name):
        <span class="hljs-keyword">if engine_name==<span class="hljs-string">"baidu":
            <span class="hljs-keyword">return BaiduEngineConf()
        <span class="hljs-keyword">elif engine_name==<span class="hljs-string">"qihu360":
            <span class="hljs-keyword">return Qihu360EngineConf()
        <span class="hljs-keyword">elif engine_name==<span class="hljs-string">"sougou":
            <span class="hljs-keyword">return SougouEngineConf()

<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">EngineConf:
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">__init__<span class="hljs-params">(self):
        self.engineConf={}
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_conf<span class="hljs-params">(self):
        <span class="hljs-keyword">return self.engineConf

<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">BaiduEngineConf<span class="hljs-params">(EngineConf):
    engineConf={}
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">__init__<span class="hljs-params">(self):
        self.engineConf[<span class="hljs-string">"searchTextID"]=<span class="hljs-string">"kw"
        self.engineConf[<span class="hljs-string">"searchBtnID"]=<span class="hljs-string">"su"
        self.engineConf[<span class="hljs-string">"nextPageBtnID_xpath_f"]=<span class="hljs-string">"//*[@id="page"]/div/a[10]"
        self.engineConf[<span class="hljs-string">"nextPageBtnID_xpath_s"]=<span class="hljs-string">"//*[@id="page"]/div/a[11]"
        self.engineConf[<span class="hljs-string">"searchContentHref_class"]=<span class="hljs-string">"t"
        self.engineConf[<span class="hljs-string">"website"]=<span class="hljs-string">"http://www.baidu.com"


<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Qihu360EngineConf<span class="hljs-params">(EngineConf):
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">__init__<span class="hljs-params">(self):
        <span class="hljs-keyword">pass


<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">SougouEngineConf<span class="hljs-params">(EngineConf):
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">__init__<span class="hljs-params">(self):
        <span class="hljs-keyword">pass</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

在此只实现了百度搜索引擎的配置编写。所有不同种类的搜索引擎继承EngineConf基类,使子类都有了 get_conf 方法。 EngineConfManage 类用于不同搜索引擎的调用,传入引擎名即可。

2.3如何使用

首先引入两个类:

<span class="hljs-keyword">from Browser <span class="hljs-keyword">import Browser
<span class="hljs-keyword">from Analyse <span class="hljs-keyword">import Analyse</span></span></span></span>

新建一个方法读取本地文件:

<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">read_txt<span class="hljs-params">(path=<span class="hljs-string">""):
    f = open(path,<span class="hljs-string">"r")
    <span class="hljs-keyword">return f.read()</span></span></span></span></span></span></span>

获取文件并新建数据分析类:

src=read_txt(<span class="hljs-string">r"F:	ool	extsrcsrc.txt")<span class="hljs-comment">#获取本地文本
Analyse=Analyse()</span></span>

配置信息字典编写:

<span class="hljs-comment">#配置信息
conf={
       <span class="hljs-string">"kw"<span class="hljs-symbol">:<span class="hljs-string">"php基础教程 第十一步 面向对象",
       <span class="hljs-string">"engine"<span class="hljs-symbol">:<span class="hljs-string">"baidu",
    }</span></span></span></span></span></span></span>

新建Browser类,并传入配置信息:

<span class="hljs-attr">drvier=Browser(conf)</span>

获取搜索结果及内容

<span class="hljs-attr">url_content=drvier.search()#获取搜索结果及内容</span>

遍历结果及计算相似度:

<span class="hljs-keyword">for k <span class="hljs-keyword">in url_content:
    <span class="hljs-built_in">print(k,<span class="hljs-string">"相似度:",Analyse.get_Tfidf(src,url_content[k]))</span></span></span></span>

完整代码如下:

<span class="hljs-keyword">from Browser <span class="hljs-keyword">import Browser
<span class="hljs-keyword">from Analyse <span class="hljs-keyword">import Analyse

<span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">read_txt<span class="hljs-params">(path=<span class="hljs-string">""):
    f = open(path,<span class="hljs-string">"r")
    <span class="hljs-keyword">return f.read()

src=read_txt(<span class="hljs-string">r"F:	ool	extsrcsrc.txt")<span class="hljs-comment">#获取本地文本
Analyse=Analyse()

<span class="hljs-comment">#配置信息
conf={
       <span class="hljs-string">"kw":<span class="hljs-string">"php基础教程 第十一步 面向对象",
       <span class="hljs-string">"engine":<span class="hljs-string">"baidu",
    }
    
drvier=Browser(conf)
url_content=drvier.search()<span class="hljs-comment">#获取搜索结果及内容
<span class="hljs-keyword">for k <span class="hljs-keyword">in url_content:
    print(k,<span class="hljs-string">"相似度:",Analyse.get_Tfidf(src,url_content[k]))</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

是不是感觉舒服多了?简直不要太清爽。你以为这就完了吗?还没完,接下来扩展一下功能。

三、功能扩展

暂时这个小工具的功能只有查重这个基础功能,并且这个存在很多问题。如没有白名单过滤、只能查一篇文章的相似度、如果比较懒也没有直接获取文章列表自动查重的功能以及结果导出等。接下来慢慢完善部分功能,由于篇幅关系并不完全把的功能实现在此列出,之后将会持续更新。

3.1自动获取文本

新建一个 python 文件,名为 FileHandle 。该类用于自动获取指定目录下 txt 文件, txt 文件文件名为关键字,内容为该名称的文章内容。类代码如下:

<span class="hljs-keyword">import os

<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">FileHandle:
    <span class="hljs-comment">#获取文件内容
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_content<span class="hljs-params">(self,path):
        f = open(path,<span class="hljs-string">"r")   <span class="hljs-comment">#设置文件对象
        content = f.read()     <span class="hljs-comment">#将txt文件的所有内容读入到字符串str中
        f.close()   <span class="hljs-comment">#将文件关闭
        <span class="hljs-keyword">return content
    <span class="hljs-comment">#获取文件内容
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_text<span class="hljs-params">(self):
        file_path=os.path.dirname(__file__)                                 <span class="hljs-comment">#当前文件所在目录
        txt_path=file_path+<span class="hljs-string">r"	extsrc"                                      <span class="hljs-comment">#txt目录
        rootdir=os.path.join(txt_path)                                      <span class="hljs-comment">#目标目录内容
        local_text={}
        <span class="hljs-comment"># 读txt 文件
        <span class="hljs-keyword">for (dirpath,dirnames,filenames) <span class="hljs-keyword">in os.walk(rootdir):
            <span class="hljs-keyword">for filename <span class="hljs-keyword">in filenames:
                <span class="hljs-keyword">if os.path.splitext(filename)[<span class="hljs-number">1]==<span class="hljs-string">".txt":
                    flag_file_path=dirpath+<span class="hljs-string">""+filename                    <span class="hljs-comment">#文件路径
                    flag_file_content=self.get_content(flag_file_path) <span class="hljs-comment">#读文件路径
                    <span class="hljs-keyword">if flag_file_content!=<span class="hljs-string">"":
                        local_text[filename.replace(<span class="hljs-string">".txt", <span class="hljs-string">"")]=flag_file_content  <span class="hljs-comment">#键值对内容
        <span class="hljs-keyword">return local_text</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

其中有两个方法 get_content 与 get_text 。 get_text 为获取目录下所有txt文件路径,通过 get_content 获取到详细文本内容,返回 local_text ; local_text 键为文件名,值为文本内容。

3.2BrowserManage类

在 Browser 类文件中添加一个 BrowserManage 类继承于 Browser ,添加方法:

<span class="hljs-comment">#打开目标搜索引擎进行搜索
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">search<span class="hljs-params">(self):
        self.browser.get(self.engine_conf[<span class="hljs-string">"website"])       <span class="hljs-comment">#打开搜索引擎站点
        self.send_keyword()                                 <span class="hljs-comment">#输入搜索kw
        self.click_search_btn()                             <span class="hljs-comment">#点击搜索
        <span class="hljs-keyword">return self.get_search_res_url()                    <span class="hljs-comment">#获取web页搜索数据</span></span></span></span></span></span></span></span></span></span></span>

添加该类使 Browser 类的逻辑与其它方法分开,便于扩展。

3.3Browser类的扩展

在 Browser 类中添加下一页方法,使搜索内容时能够获取更多内容,并且可指定获取结果条数:

<span class="hljs-comment">#下一页
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">click_next_page<span class="hljs-params">(self,md5):
        WebDriverWait(self.browser,timeout=<span class="hljs-number">30,poll_frequency=<span class="hljs-number">1).until(EC.presence_of_element_located((By.ID, <span class="hljs-string">"page")))
        <span class="hljs-comment">#百度搜索引擎翻页后下一页按钮 xpath 不一致 默认非第一页xpath
        <span class="hljs-keyword">try:
            next_page_btn = self.browser.find_element_by_xpath(self.engine_conf[<span class="hljs-string">"nextPageBtnID_xpath_s"])
        <span class="hljs-keyword">except:
            next_page_btn = self.browser.find_element_by_xpath(self.engine_conf[<span class="hljs-string">"nextPageBtnID_xpath_f"])
        next_page_btn.click()
        <span class="hljs-comment">#md5 进行 webpag text 对比,判断是否已翻页 (暂时使用,存在bug)
        i=<span class="hljs-number">0
        <span class="hljs-keyword">while md5==hashlib.md5(self.browser.page_source.encode(encoding=<span class="hljs-string">"UTF-8")).hexdigest():<span class="hljs-comment">#md5 对比
            time.sleep(<span class="hljs-number">0.3)<span class="hljs-comment">#防止一些错误,暂时使用强制停止保持一些稳定
            i+=<span class="hljs-number">1
            <span class="hljs-keyword">if i><span class="hljs-number">100:
                <span class="hljs-keyword">return <span class="hljs-keyword">False
        <span class="hljs-keyword">return <span class="hljs-keyword">True</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

百度搜索引擎翻页后下一页按钮 xpath 不一致 默认非第一页 xpath ,出现异常使用另外一个 xpath 。随后对页面进行 md5 ,对比md5值,如果当前页面没有刷新, md5 值将不会改变,等待小短时间之后点击下一页。

3.4get_search_res_url方法的修改

get_search_res_url方法的修改了部分内容,添加了增加结果条数指定、下一页内容获取以及白名单设置更改过后的代码如下:

<span class="hljs-comment">#获取搜索结果与文本
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_search_res_url<span class="hljs-params">(<span class="hljs-keyword">self):
        res_link={}
        WebDriverWait(<span class="hljs-keyword">self.browser,timeout=<span class="hljs-number">30,poll_frequency=<span class="hljs-number">1).<span class="hljs-keyword">until(EC.presence_of_element_located((By.ID, <span class="hljs-string">"page")))
        <span class="hljs-comment">#内容通过 BeautifulSoup 解析
        content=<span class="hljs-keyword">self.browser.page_source
        soup = BeautifulSoup(content, <span class="hljs-string">"html.parser")
        search_res_list=soup.select(<span class="hljs-string">"."+<span class="hljs-keyword">self.engine_conf[<span class="hljs-string">"searchContentHref_class"])
        <span class="hljs-keyword">while len(res_link)<<span class="hljs-keyword">self.conf[<span class="hljs-string">"target_page"]:
            <span class="hljs-keyword">for el <span class="hljs-keyword">in <span class="hljs-symbol">search_res_list:
                js = <span class="hljs-string">"window.open(""+el.a[<span class="hljs-string">"href"]+<span class="hljs-string">"")"
                <span class="hljs-keyword">self.browser.execute_script(js)
                handle_this=<span class="hljs-keyword">self.browser.current_window_handle  <span class="hljs-comment">#获取当前句柄
                handle_all=<span class="hljs-keyword">self.browser.window_handles          <span class="hljs-comment">#获取所有句柄
                handle_exchange=None                            <span class="hljs-comment">#要切换的句柄
                <span class="hljs-keyword">for handle <span class="hljs-keyword">in <span class="hljs-symbol">handle_all:                       <span class="hljs-comment">#不匹配为新句柄
                    <span class="hljs-keyword">if handle != <span class="hljs-symbol">handle_this:                   <span class="hljs-comment">#不等于当前句柄就交换
                        handle_exchange = handle
                <span class="hljs-keyword">self.browser.switch_to.window(handle_exchange)  <span class="hljs-comment">#切换
                real_url=<span class="hljs-keyword">self.browser.current_url
                <span class="hljs-keyword">if real_url <span class="hljs-keyword">in <span class="hljs-keyword">self.conf[<span class="hljs-string">"white_list"]:         <span class="hljs-comment">#白名单
                    continue
                time.sleep(<span class="hljs-number">1)
                res_link[real_url]=<span class="hljs-keyword">self.browser.page_source     <span class="hljs-comment">#结果获取
                
                <span class="hljs-keyword">self.browser.close()
                <span class="hljs-keyword">self.browser.switch_to.window(handle_this)
            content_md5=hashlib.md5(<span class="hljs-keyword">self.browser.page_source.encode(encoding=<span class="hljs-string">"UTF-8")).hexdigest() <span class="hljs-comment">#md5对比
            <span class="hljs-keyword">self.click_next_page(content_md5)
        <span class="hljs-keyword">return res_link</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

while len(res_link)<self.conf["target_page"]: 为增加了对结果条数的判断。

content_md5=hashlib.md5(<span class="hljs-keyword">self.browser.page_source.encode(encoding=<span class="hljs-string">"UTF-8")).hexdigest() <span class="hljs-comment">#md5对比
<span class="hljs-keyword">self.click_next_page(content_md5)</span></span></span></span>

以上代码增加了当前页面刷新后的md5值判断,不一致则进行跳转。

<span class="hljs-keyword">if real_url <span class="hljs-keyword">in <span class="hljs-keyword">self.conf[<span class="hljs-string">"white_list"]:         <span class="hljs-comment">#白名单
    continue</span></span></span></span></span>

以上代码对白名单进行了判断,自己设置的白名单不加入到条数。

3.5新建Manage类

新建一python文件名为Manage,再次封装。代码如下:

<span class="hljs-keyword">from Browser <span class="hljs-keyword">import BrowserManage
<span class="hljs-keyword">from Analyse <span class="hljs-keyword">import Analyse
<span class="hljs-keyword">from FileHandle <span class="hljs-keyword">import FileHandle

<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Manage:
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">__init__<span class="hljs-params">(self,conf):
        self.drvier=BrowserManage(conf)
        self.textdic=FileHandle().get_text()
        self.analyse=Analyse()
    <span class="hljs-function"><span class="hljs-keyword">def <span class="hljs-title">get_local_analyse<span class="hljs-params">(self):    
        resdic={}
        
        <span class="hljs-keyword">for k <span class="hljs-keyword">in self.textdic:
            res
                                                                                                        
                                                </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:利用Python制作文章查重系统

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址