最近中文字幕2019高清,亚洲人成高清在线播放,男生淦哭男生图片动漫有字,国产亚洲精品九九久在线观看,无码av专区丝袜专区

解決方案:python *敏*感*詞*教你基于搜索引擎實(shí)現文章查重

優(yōu)采云 發(fā)布時(shí)間: 2022-11-29 17:30

  解決方案:python *敏*感*詞*教你基于搜索引擎實(shí)現文章查重

  前言

  文章抄襲在網(wǎng)絡(luò )上很普遍,很多博主都為之煩惱。近年來(lái),隨著(zhù)互聯(lián)網(wǎng)的發(fā)展,網(wǎng)絡(luò )上抄襲等*敏*感*詞*行為愈演愈烈。甚至復制粘貼貼出原文的情況并不少見(jiàn),有的抄襲文章甚至標注了一些*敏*感*詞*,以便讀者獲取源代碼等信息。這種不良行為讓人憤慨。

  本文利用搜索引擎結果作為文章數據庫,然后與本地或互聯(lián)網(wǎng)上的數據進(jìn)行相似度比對,實(shí)現文章的抄襲檢查;由于抄襲檢查的實(shí)現過(guò)程與正常情況下微博情感分析的實(shí)現過(guò)程類(lèi)似,因此很容易擴展情感分析功能(下一篇文章將根據數據完成從數據采集、清洗到情感分析的全過(guò)程本文中的代碼)。

  由于近期時(shí)間不夠,暫時(shí)實(shí)現了主要功能,細節方面沒(méi)有做優(yōu)化。但是在代碼結構上做了一些簡(jiǎn)單的設計,方便以后的功能擴展和升級。我本人會(huì )不斷更新這個(gè)工具的功能,力爭讓這個(gè)工具在技術(shù)上更加成熟和實(shí)用。

  技術(shù)

  考慮到適應大多數站點(diǎn),本文實(shí)現的查重功能使用selenium進(jìn)行數據獲取,配置不同搜索引擎的信息,實(shí)現更通用的搜索引擎查詢(xún),不需要考慮過(guò)多的動(dòng)態(tài)數據抓??;分詞主要是利用jieba庫完成中文句子的分詞;利用余弦相似度完成文本相似度的比較,并將比較數據導出到Excel文章中,作為報表信息。

  微博情感分析基于sklearn,使用樸素貝葉斯完成數據的情感分析;在數據抓取方面,實(shí)現過(guò)程類(lèi)似于文本抄襲檢查功能。

  測試代碼獲取

  codechina代碼庫:

  環(huán)境

  筆者的環(huán)境描述如下:

  如有錯誤請指出并留言交流。

  1.文本校驗的實(shí)現 1.1 selenium安裝配置

  由于selenium的使用,需要確保讀者在使用前已經(jīng)安裝了selenium。使用pip命令安裝如下:

  pip install selenium

  安裝 Selenium 后,您需要下載驅動(dòng)程序。

  安裝好selenium后,新建一個(gè)python文件,命名為selenium_search,先在代碼中引入

  from selenium import webdriver

  有的讀者可能沒(méi)有把驅動(dòng)配置進(jìn)環(huán)境,那么我們可以指定驅動(dòng)的位置(博主已經(jīng)配置進(jìn)環(huán)境):

  driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')

  新建一個(gè)變量url賦給百度首頁(yè)鏈接,使用get方法傳入url地址,嘗試打開(kāi)百度首頁(yè),完整代碼如下:

  from selenium import webdriver

url='https://www.baidu.com'

driver=webdriver.Chrome()

driver.get(url)

  使用命令行運行小黑框里的python文件(windows下):

  運行腳本后,谷歌瀏覽器將被打開(kāi)并重定向到百度首頁(yè):

  這樣就成功使用selenium打開(kāi)了指定的url,然后會(huì )查詢(xún)指定的搜索關(guān)鍵詞得到結果,然后從結果中遍歷出類(lèi)似的數據。

  1.2 selenium百度搜索引擎關(guān)鍵詞搜索

  在自動(dòng)操縱瀏覽器向搜索框輸入關(guān)鍵詞之前,需要獲取搜索框元素對象。使用谷歌瀏覽器打開(kāi)百度首頁(yè),右擊搜索框選擇查看,會(huì )彈出網(wǎng)頁(yè)元素(代碼)查看窗口,找到搜索框元素(用鼠標在元素節點(diǎn)中移動(dòng),元素鼠標當前位置的節點(diǎn)將對應網(wǎng)頁(yè)中藍色的索引):

  在html代碼中,id的值在大多數情況下是唯一的(除非是錯別字),這里選擇id作為獲取搜索框元素對象的標簽。Selenium提供了find_element_by_id方法,可以通過(guò)傳入id獲取網(wǎng)頁(yè)元素對象。

  input=driver.find_element_by_id('kw')

  獲取元素對象后,使用send_keys方法傳入需要鍵入的值:

  input.send_keys('php基礎教程 第十一步 面向對象')

  這里我傳入“php基礎教程step 11 面向對象”作為關(guān)鍵字作為搜索。運行腳本以查看是否在搜索框中鍵入了關(guān)鍵字。代碼如下:

  input.send_keys('php基礎教程 第十一步 面向對象')

  成功打開(kāi)瀏覽器并輸入搜索關(guān)鍵字:

  現在只需點(diǎn)擊“百度點(diǎn)擊”按鈕即可完成最終搜索。使用與查看搜索框相同的元素查看方法找到“百度”按鈕的id值:

  使用find_element_by_id方法獲取元素對象,然后使用click方法讓按鈕完成點(diǎn)擊操作:

  search_btn=driver.find_element_by_id('su')

search_btn.click()

  完整代碼如下:

  from selenium import webdriver

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()

  瀏覽器自動(dòng)完成搜索關(guān)鍵字的輸入和搜索功能:

  1.3 搜索結果遍歷

  目前已經(jīng)在瀏覽器中獲取到搜索結果,下一步就是獲取整個(gè)網(wǎng)頁(yè)內容獲取搜索結果。用selenium獲取不是很方便。這里使用BeautifulSoup來(lái)解析整個(gè)網(wǎng)頁(yè)并獲取搜索結果。

  BeautifulSoup是一個(gè)HTML/XML解析器,使用BeautifulSoup將極大方便我們獲取整個(gè)html信息。

  在使用 BeautifulSoup 之前確保已安裝它。安裝命令如下:

  pip install BeautifulSoup

  安裝完成后,在當前python文件的頭部引入:

  from bs4 import BeautifulSoup

  要獲取 html 文本,您可以調用 page_source:

  html=driver.page_source

  得到html代碼后,創(chuàng )建一個(gè)BeautifulSoup對象,傳入html內容并指定解析器,這里指定html.parser解析器:

  soup = BeautifulSoup(html, "html.parser")

  接下來(lái)查看搜索內容,發(fā)現所有結果都收錄

在一個(gè)h標簽中,類(lèi)別為t:

  BeautifulSoup提供了select方法獲取標簽,支持通過(guò)類(lèi)名、標簽名、id、屬性、組合進(jìn)行搜索。我們發(fā)現在百度搜索結果中,所有的結果都有一個(gè)class="t",這時(shí)候遍歷類(lèi)名是最方便的:

  search_res_list=soup.select('.t')

  在select方法中,傳入類(lèi)名t,在類(lèi)名前加一個(gè)點(diǎn)(.),表示通過(guò)類(lèi)名獲取元素。

  完成這一步后,可以添加print來(lái)嘗試打印出結果:

  print(search_res_list)

  一般情況下,輸出的search_res_list可能是一個(gè)空列表。這是因為在瀏覽器解析數據并呈現給瀏覽器之前,我們已經(jīng)獲取了瀏覽器當前頁(yè)面的內容。有一個(gè)簡(jiǎn)單的方法可以解決這個(gè)問(wèn)題,但是這個(gè)方法效率不高,暫時(shí)只用到這里,以后會(huì )換成其他比這個(gè)方法效率更高的代碼(使用時(shí)間需要介紹在標題中):

  time.sleep(2)

  完整代碼如下:

  from selenium import webdriver

from bs4 import BeautifulSoup

import time

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 #獲取網(wǎng)頁(yè)內容

soup = BeautifulSoup(html, "html.parser")

search_res_list=soup.select('.t')

print(search_res_list)

  運行程序會(huì )輸出:

  得到的結果都是類(lèi)t的標簽,包括標簽的子節點(diǎn),子節點(diǎn)元素可以通過(guò)點(diǎn)(.)操作得到。通過(guò)瀏覽器獲取的搜索內容都是鏈接,點(diǎn)擊跳轉,那么只需要獲取每個(gè)元素下的a標簽即可:

  for el in search_res_list:

print(el.a)

  從結果中可以看出,已經(jīng)得到了搜索結果的a標簽,那么接下來(lái)我們要做的就是提取每個(gè)a標簽中的href超鏈接。使用list獲取元素直接獲取href超鏈接:

  for el in search_res_list:

print(el.a['href'])

  成功運行腳本會(huì )導致:

  細心的讀者可能會(huì )發(fā)現,得到的結果都是百度網(wǎng)址。其實(shí)這些URL可以說(shuō)是“索引”,通過(guò)這些索引再次跳轉到真正的URL。由于這些“索引”不一定會(huì )變,也不利于長(cháng)期保存,所以這里還是需要獲取真實(shí)的鏈接。

  我們調用js腳本來(lái)訪(fǎng)問(wèn)這些url,這些url會(huì )跳轉到真實(shí)的url,跳轉后獲取當前的url信息。調用execute_script方法執行js代碼,代碼如下:

  for el in search_res_list:

js = 'window.open("'+el.a['href']+'")'

driver.execute_script(js)

  打開(kāi)新網(wǎng)頁(yè)后,需要獲取新網(wǎng)頁(yè)的句柄,否則無(wú)法操作新網(wǎng)頁(yè)。獲取句柄的方法如下:

  handle_this=driver.current_window_handle#獲取當前句柄

handle_all=driver.window_handles#獲取所有句柄

  獲取句柄后,需要將當前操作的對象切換到新的頁(yè)面。由于打開(kāi)一個(gè)頁(yè)面后只有2個(gè)頁(yè)面,所以干脆使用遍歷進(jìn)行替換:

  handle_exchange=None#要切換的句柄

for handle in handle_all:#不匹配為新句柄

if handle != handle_this:#不等于當前句柄就交換

handle_exchange = handle

driver.switch_to.window(handle_exchange)#切換

  切換后,操作對象為當前剛打開(kāi)的頁(yè)面。通過(guò)current_url屬性獲取新頁(yè)面的url:

  real_url=driver.current_url

print(real_url)

  然后關(guān)閉當前頁(yè)面,將操作對象設置為初始頁(yè)面:

  driver.close()

driver.switch_to.window(handle_this)#換回最初始界面

  運行腳本成功獲取真實(shí)url:

  最后用一個(gè)list來(lái)存儲得到真實(shí)url后的結果:

  real_url_list.append(real_url)

  該部分完整代碼如下:

  from selenium import webdriver

from bs4 import BeautifulSoup

import time

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 = 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 獲取源文本

  在當前文件所在目錄下新建一個(gè)文件夾,命名為textsrc,在該目錄下新建一個(gè)txt文件,在text中存放要比較的文本。我這里存放的內容是《PHP基礎教程面向對象第十一步》一文的內容。

  在代碼中寫(xiě)一個(gè)函數獲取文本內容:

  def read_txt(path=''):

f = open(path,'r')

return f.read()

src=read_txt(r'F:\tool\textsrc\src.txt')

  為了測試方便,這里使用絕對路徑。

  得到文本內容后,寫(xiě)一個(gè)余弦相似度的比較方法。

  1.5 余弦相似度

  相似度計算參考《Python實(shí)現余弦相似度文本比較》一文,我修改了一部分實(shí)現。

  本文相似度比較采用余弦相似度算法,大致步驟分為分詞->向量計算->計算相似度。

  創(chuàng )建一個(gè)名為 Analyze 的新 Python 文件。新建一個(gè)類(lèi)叫Analyze,在類(lèi)中添加一個(gè)分詞方法,在head中引入jieba分詞庫,采集

數統計:

  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方法接收一個(gè)文本變量,為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

  合并的方法很簡(jiǎn)單,就不解釋了。接下來(lái)添加向量計算方法:

  # 得出文檔向量

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):#兩個(gè)向量組合成 [(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)

  相似度方法采用兩個(gè)向量,計算相似度并將其返回。為了減少代碼冗余,這里簡(jiǎn)單的增加一個(gè)方法來(lái)完成計算過(guò)程:

  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))

  Analyze類(lèi)的完整代碼如下:

  from jieba import lcut

import jieba.analyse

import collections

class 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):#兩個(gè)向量組合成 [(1, 4), (2, 5), (3, 6)] 最短形式表現

dot_product += a * b

<p>

" />

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)

</p>

  1.6 比較搜索結果內容與文本的相似度

  在selenium_search文件中引入Analyze,新建一個(gè)對象:

  from Analyse import Analyse

Analyse=Analyse()

  將新打開(kāi)頁(yè)面的網(wǎng)頁(yè)內容添加到遍歷的搜索結果中:

  time.sleep(5)

html_2=driver.page_source

  使用 time.sleep(5) 等待瀏覽器有時(shí)間渲染當前網(wǎng)頁(yè)內容。獲取新打開(kāi)頁(yè)面的內容后,比較相似度:

  Analyse.get_Tfidf(src,html_2)

  既然返回了一個(gè)值,那么用print輸出:

  print(&#39;相似度:&#39;,Analyse.get_Tfidf(src,html_2))

  完整代碼如下:

  from selenium import webdriver

from bs4 import BeautifulSoup

import time

from Analyse import Analyse

def read_txt(path=&#39;&#39;):

f = open(path,&#39;r&#39;)

return f.read()

#獲取對比文件

src=read_txt(r&#39;F:\tool\textsrc\src.txt&#39;)

Analyse=Analyse()

url=&#39;https://www.baidu.com&#39;

driver=webdriver.Chrome()

driver.get(url)

input=driver.find_element_by_id(&#39;kw&#39;)

input.send_keys(&#39;php基礎教程 第十一步 面向對象&#39;)

search_btn=driver.find_element_by_id(&#39;su&#39;)

search_btn.click()

time.sleep(2)#在此等待 使瀏覽器解析并渲染到瀏覽器

html=driver.page_source

soup = BeautifulSoup(html, "html.parser")

search_res_list=soup.select(&#39;.t&#39;)

real_url_list=[]

# print(search_res_list)

for el in search_res_list:

js = &#39;window.open("&#39;+el.a[&#39;href&#39;]+&#39;")&#39;

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(&#39;相似度:&#39;,Analyse.get_Tfidf(src,html_2))

print(real_url)

real_url_list.append(real_url)

driver.close()

driver.switch_to.window(handle_this)

  運行腳本:

  結果顯示有幾個(gè)高度相似的鏈接,因此這些是涉嫌抄襲的文章。

  上面是完成基本查重的代碼,但是和代碼相比,顯得冗余和凌亂。接下來(lái),讓我們優(yōu)化代碼。

  2.代碼優(yōu)化

  通過(guò)上面的程序編程,大致可以分為:獲取搜索內容-&gt;獲取結果-&gt;計算相似度。我們可以新建三個(gè)類(lèi),分別是:Browser、Analyze(新創(chuàng )建的)、SearchEngine。

  瀏覽器用于搜索、數據獲取等;Analyze用于相似度分析、向量計算等;SearchEngine用于不同搜索引擎的基礎配置,因為大部分搜索引擎的搜索方式都比較一致。

  2.1瀏覽器類(lèi)

  初始化

  新建一個(gè)名為 Browser 的 python 文件,并添加一個(gè)初始化方法:

  def __init__(self,conf):

self.browser=webdriver.Chrome()

self.conf=conf

self.engine_conf=EngineConfManage().get_Engine_conf(conf[&#39;engine&#39;]).get_conf()

  self.browser=webdriver.Chrome() 是創(chuàng )建一個(gè)新的瀏覽器對象;conf是傳入的搜索配置,然后通過(guò)編寫(xiě)配置字典來(lái)實(shí)現搜索內容;self.engine_conf=EngineConfManage().get_Engine_conf(conf['engine'] ).get_conf()是獲取搜索引擎的配置。不同搜索引擎的輸入框和搜索按鈕不一致,通過(guò)不同的配置信息實(shí)現多搜索引擎搜索。

  添加搜索方法

   #搜索內容寫(xiě)入到搜素引擎中

def send_keyword(self):

input = self.browser.find_element_by_id(self.engine_conf[&#39;searchTextID&#39;])

input.send_keys(self.conf[&#39;kw&#39;])

  上述方法中self.engine_conf['searchTextID']和self.conf['kw']通過(guò)初始化方法獲取對應的搜索引擎配置信息,直接獲取信息獲取元素。

  點(diǎn)擊搜索

   #搜索框點(diǎn)擊

def click_search_btn(self):

search_btn = self.browser.find_element_by_id(self.engine_conf[&#39;searchBtnID&#39;])

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")))

#內容通過(guò) BeautifulSoup 解析

content=self.browser.page_source

soup = BeautifulSoup(content, "html.parser")

search_res_list=soup.select(&#39;.&#39;+self.engine_conf[&#39;searchContentHref_class&#39;])

for el in search_res_list:

js = &#39;window.open("&#39;+el.a[&#39;href&#39;]+&#39;")&#39;

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

  上面的方法和之前寫(xiě)的遍歷搜索結果類(lèi)似,添加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")) 是否找到一個(gè)id為page的網(wǎng)頁(yè)元素,id為page的網(wǎng)頁(yè)元素為分頁(yè)按鈕的標簽id。如果沒(méi)有獲取到,說(shuō)明當前網(wǎng)頁(yè)沒(méi)有加載完成,等待時(shí)間timeout=3030秒,如果已經(jīng)過(guò)去,則跳過(guò)等待。

  上面的代碼并沒(méi)有比較相似度,而是通過(guò)res_link[real_url]=self.browser.page_source將內容和url存入字典,然后返回,再進(jìn)行相似度比較,有利于以后的功能擴展。

  打開(kāi)目標搜索引擎進(jìn)行搜索

   #打開(kāi)目標搜索引擎進(jìn)行搜索

def search(self):

self.browser.get(self.engine_conf[&#39;website&#39;]) #打開(kāi)搜索引擎站點(diǎn)

self.send_keyword() #輸入搜索kw

self.click_search_btn() #點(diǎn)擊搜索

return self.get_search_res_url() #獲取web頁(yè)搜索數據

  最后添加一個(gè)search方法,直接調用search方法即可實(shí)現前面的所有操作,無(wú)需過(guò)多暴露,簡(jiǎn)化使用。

  完整代碼如下:

  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 time

class Browser:

def __init__(self,conf):

self.browser=webdriver.Chrome()

self.conf=conf

self.engine_conf=EngineConfManage().get_Engine_conf(conf[&#39;engine&#39;]).get_conf()

#搜索內容寫(xiě)入到搜素引擎中

def send_keyword(self):

input = self.browser.find_element_by_id(self.engine_conf[&#39;searchTextID&#39;])

input.send_keys(self.conf[&#39;kw&#39;])

#搜索框點(diǎn)擊

def click_search_btn(self):

search_btn = self.browser.find_element_by_id(self.engine_conf[&#39;searchBtnID&#39;])

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")))

#內容通過(guò) BeautifulSoup 解析

content=self.browser.page_source

soup = BeautifulSoup(content, "html.parser")

search_res_list=soup.select(&#39;.&#39;+self.engine_conf[&#39;searchContentHref_class&#39;])

for el in search_res_list:

js = &#39;window.open("&#39;+el.a[&#39;href&#39;]+&#39;")&#39;

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

#打開(kāi)目標搜索引擎進(jìn)行搜索

def search(self):

self.browser.get(self.engine_conf[&#39;website&#39;]) #打開(kāi)搜索引擎站點(diǎn)

self.send_keyword() #輸入搜索kw

self.click_search_btn() #點(diǎn)擊搜索

return self.get_search_res_url() #獲取web頁(yè)搜索數據

  2.2SearchEngine類(lèi)

  SearchEngine類(lèi)主要用于不同搜索引擎的配置編寫(xiě)。更容易實(shí)現搜索引擎或類(lèi)似業(yè)務(wù)的擴展。

  #搜索引擎配置

class EngineConfManage:

def get_Engine_conf(self,engine_name):

if engine_name==&#39;baidu&#39;:

return BaiduEngineConf()

elif engine_name==&#39;qihu360&#39;:

return Qihu360EngineConf()

elif engine_name==&#39;sougou&#39;:

return SougouEngineConf()

class EngineConf:

def __init__(self):

self.engineConf={}

def get_conf(self):

return self.engineConf

class BaiduEngineConf(EngineConf):

engineConf={}

def __init__(self):

self.engineConf[&#39;searchTextID&#39;]=&#39;kw&#39;

self.engineConf[&#39;searchBtnID&#39;]=&#39;su&#39;

self.engineConf[&#39;nextPageBtnID_xpath_f&#39;]=&#39;//*[@id="page"]/div/a[10]&#39;

self.engineConf[&#39;nextPageBtnID_xpath_s&#39;]=&#39;//*[@id="page"]/div/a[11]&#39;

self.engineConf[&#39;searchContentHref_class&#39;]=&#39;t&#39;

self.engineConf[&#39;website&#39;]=&#39;http://www.baidu.com&#39;

class Qihu360EngineConf(EngineConf):

def __init__(self):

pass

class SougouEngineConf(EngineConf):

def __init__(self):

pass

  這里只實(shí)現了百度搜索引擎的配置。各種搜索引擎都繼承了EngineConf基類(lèi),所以子類(lèi)都有g(shù)et_conf方法。EngineConfManage類(lèi)用于調用不同的搜索引擎,傳入引擎名稱(chēng)即可。

  2.3 如何使用

  先介紹兩個(gè)類(lèi):

  from Browser import Browser

from Analyse import Analyse

  創(chuàng )建一個(gè)讀取本地文件的新方法:

  def read_txt(path=&#39;&#39;):

f = open(path,&#39;r&#39;)

return f.read()

  獲取文件并新建一個(gè)數據分析類(lèi):

  src=read_txt(r&#39;F:\tool\textsrc\src.txt&#39;)#獲取本地文本

Analyse=Analyse()

  配置信息字典寫(xiě)法:

  #配置信息

conf={

&#39;kw&#39;:&#39;php基礎教程 第十一步 面向對象&#39;,

&#39;engine&#39;:&#39;baidu&#39;,

}

  新建一個(gè)Browser類(lèi),傳入配置信息:

  drvier=Browser(conf)

  獲取搜索結果和內容

  url_content=drvier.search()#獲取搜索結果及內容

  遍歷結果,計算相似度:

  for k in url_content:

print(k,&#39;相似度:&#39;,Analyse.get_Tfidf(src,url_content[k]))

  完整代碼如下:

  from Browser import Browser

from Analyse import Analyse

def read_txt(path=&#39;&#39;):

f = open(path,&#39;r&#39;)

return f.read()

src=read_txt(r&#39;F:\tool\textsrc\src.txt&#39;)#獲取本地文本

Analyse=Analyse()

#配置信息

conf={

&#39;kw&#39;:&#39;php基礎教程 第十一步 面向對象&#39;,

&#39;engine&#39;:&#39;baidu&#39;,

}

drvier=Browser(conf)

url_content=drvier.search()#獲取搜索結果及內容

for k in url_content:

print(k,&#39;相似度:&#39;,Analyse.get_Tfidf(src,url_content[k]))

  你覺(jué)得更舒服嗎?簡(jiǎn)直不要太清爽。你認為這是結束了嗎?還沒(méi)完,接下來(lái)我們來(lái)擴展一下功能。

  3、功能擴展

  暫時(shí)這個(gè)小工具的功能只是檢查重量的基本功能,這里面還有很多問(wèn)題。如果沒(méi)有白名單過(guò)濾,只能查一篇文章的相似度,偷懶的話(huà),沒(méi)有直接獲取文章列表自動(dòng)查重并導出結果的功能。接下來(lái)會(huì )逐步完善一些功能。限于篇幅,實(shí)現的功能這里就不一一列舉了,以后會(huì )不斷更新。

  3.1 自動(dòng)獲取文本

  創(chuàng )建一個(gè)名為 FileHandle 的新 Python 文件。該類(lèi)用于自動(dòng)獲取指定目錄下的txt文件,txt文件的名稱(chēng)為關(guān)鍵字,內容為該名稱(chēng)的文章內容。類(lèi)代碼如下:

  import os

class FileHandle:

#獲取文件內容

def get_content(self,path):

f = open(path,"r") #設置文件對象

content = f.read() #將txt文件的所有內容讀入到字符串str中

f.close() #將文件關(guān)閉

return content

#獲取文件內容

def get_text(self):

file_path=os.path.dirname(__file__) #當前文件所在目錄

txt_path=file_path+r&#39;\textsrc&#39; #txt目錄

rootdir=os.path.join(txt_path) #目標目錄內容

local_text={}

# 讀txt 文件

<p>

" />

for (dirpath,dirnames,filenames) in os.walk(rootdir):

for filename in filenames:

if os.path.splitext(filename)[1]==&#39;.txt&#39;:

flag_file_path=dirpath+&#39;\\&#39;+filename #文件路徑

flag_file_content=self.get_content(flag_file_path) #讀文件路徑

if flag_file_content!=&#39;&#39;:

local_text[filename.replace(&#39;.txt&#39;, &#39;&#39;)]=flag_file_content #鍵值對內容

return local_text

</p>

  有兩個(gè)方法get_content 和get_text。get_text是獲取目錄下所有的txt文件路徑,通過(guò)get_content獲取詳細的文本內容,返回local_text;local_text key是文件名,value是文本內容。

  3.2BrowserManage類(lèi)

  在Browser類(lèi)文件中添加一個(gè)繼承自Browser的BrowserManage類(lèi),并添加方法:

  #打開(kāi)目標搜索引擎進(jìn)行搜索

def search(self):

self.browser.get(self.engine_conf[&#39;website&#39;]) #打開(kāi)搜索引擎站點(diǎn)

self.send_keyword() #輸入搜索kw

self.click_search_btn() #點(diǎn)擊搜索

return self.get_search_res_url() #獲取web頁(yè)搜索數據

  添加這個(gè)類(lèi)將 Browser 類(lèi)的邏輯與其他方法分開(kāi),以便于擴展。

  3.3 Browser類(lèi)的擴展

  在Browser類(lèi)中添加next page方法,這樣在搜索內容的時(shí)候可以獲取更多的內容,可以指定獲取結果的個(gè)數:

  #下一頁(yè)

def click_next_page(self,md5):

WebDriverWait(self.browser,timeout=30,poll_frequency=1).until(EC.presence_of_element_located((By.ID, "page")))

#百度搜索引擎翻頁(yè)后下一頁(yè)按鈕 xpath 不一致 默認非第一頁(yè)xpath

try:

next_page_btn = self.browser.find_element_by_xpath(self.engine_conf[&#39;nextPageBtnID_xpath_s&#39;])

except:

next_page_btn = self.browser.find_element_by_xpath(self.engine_conf[&#39;nextPageBtnID_xpath_f&#39;])

next_page_btn.click()

#md5 進(jìn)行 webpag text 對比,判斷是否已翻頁(yè) (暫時(shí)使用,存在bug)

i=0

while md5==hashlib.md5(self.browser.page_source.encode(encoding=&#39;UTF-8&#39;)).hexdigest():#md5 對比

time.sleep(0.3)#防止一些錯誤,暫時(shí)使用強制停止保持一些穩定

i+=1

if i>100:

return False

return True

  百度搜索引擎翻頁(yè)后,下一頁(yè)按鈕的xpath不一致。默認不是第一頁(yè)的xpath。如果出現異常,則使用另一個(gè) xpath。然后在頁(yè)面上進(jìn)行md5,比較md5值。如果當前頁(yè)面沒(méi)有刷新,md5值不會(huì )改變。稍等片刻,然后單擊下一頁(yè)。

  3.4 修改get_search_res_url方法

  修改了get_search_res_url方法的部分內容,添加指定數量的結果,獲取下一頁(yè)內容,更改白名單設置后的代碼如下:

<p>#獲取搜索結果與文本

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")))

#內容通過(guò) BeautifulSoup 解析

content=self.browser.page_source

soup = BeautifulSoup(content, "html.parser")

search_res_list=soup.select(&#39;.&#39;+self.engine_conf[&#39;searchContentHref_class&#39;])

while len(res_link)

0 個(gè)評論

要回復文章請先登錄注冊


官方客服QQ群

微信人工客服

QQ人工客服


線(xiàn)

最近中文字幕2019高清,亚洲人成高清在线播放,男生淦哭男生图片动漫有字,国产亚洲精品九九久在线观看,无码av专区丝袜专区