
CDA數(shù)據(jù)分析師
出品作者:CDALevel Ⅰ
持證人崗位:數(shù)據(jù)分析師
行業(yè):大數(shù)據(jù)
眾所周知,規(guī)范性的網(wǎng)絡(luò)爬蟲可以幫助Decision-maker在低成本下獲得想要的信息,不僅如此,做科研、寫論文、包括現(xiàn)在的大學(xué)生都可以利用該技術(shù)獲得相應(yīng)的數(shù)據(jù)。在數(shù)據(jù)為王的時(shí)代,網(wǎng)絡(luò)爬蟲是每個(gè)coder都需要必備的技能。然而,隨著爬蟲事業(yè)的發(fā)展,網(wǎng)站也開始部署了一些反爬蟲措施,最典型的莫過于12306等網(wǎng)站。其中,驗(yàn)證碼是常用的表單登錄反爬蟲措施。coder在編寫程序爬蟲的時(shí)候或多或少都會(huì)遇到驗(yàn)證碼的人機(jī)判別。當(dāng)然,驗(yàn)證碼不是一成不變的,隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,驗(yàn)證碼的樣式也變得越來越多。比如包括中文漢字、中文符號(hào)、英文字符的圖形驗(yàn)證碼、移動(dòng)滑塊驗(yàn)證碼、滑動(dòng)宮格驗(yàn)證碼、計(jì)算題驗(yàn)證碼、點(diǎn)觸驗(yàn)證碼等等。
本文選擇目前市場上較為流行且難度較大的移動(dòng)滑塊驗(yàn)證碼,并在介紹其樣式的基礎(chǔ)上進(jìn)一步選擇更為高級(jí)的無原圖有空隙的移動(dòng)滑塊驗(yàn)證碼,利用Python語言結(jié)合超級(jí)鷹平臺(tái)高效實(shí)現(xiàn)滑塊路徑長度的計(jì)算,并以小不點(diǎn)搜索網(wǎng)址(https://www.xiaoso.net/)作為案例作為代碼實(shí)現(xiàn),使讀者更為直觀的體驗(yàn)。
本文采用Anaconda進(jìn)行Python編譯,主要涉及的Python模塊:
本章分為三部分講解:
移動(dòng)滑塊驗(yàn)證碼目的是讓使用者將指定的部分拖動(dòng)到缺口部分,完成圖形的拼合。目前市場上主要有兩種樣式,一種是無空隙的,換句話說就是拖動(dòng)的滑塊一開始是處于左側(cè)邊緣的,如下圖所示,此類我稱之為無空隙移動(dòng)滑塊。
另一種則是有空隙的,也即拖動(dòng)的滑塊一開始不在左側(cè)邊緣,而是與左側(cè)邊緣存在一定距離的,最常見的就是如下圖所示的企鵝拼圖。
除此樣式的不同之外,更深層次的區(qū)別有無原圖與有原圖。熟悉網(wǎng)絡(luò)爬蟲技術(shù)的coder都知道,在網(wǎng)頁源代碼中是存在一個(gè)frame框架來裝驗(yàn)證碼整個(gè)驗(yàn)證程序,而在解決怎么自動(dòng)破解這個(gè)移動(dòng)滑塊驗(yàn)證碼的時(shí)候,我們需要下載驗(yàn)證碼原圖,通過一系列技術(shù)發(fā)現(xiàn)拖動(dòng)滑塊與缺口的距離(第二部分會(huì)詳解)。而這張?jiān)瓐D就是區(qū)別所在,下面為兩個(gè)定義的解釋:
無原圖驗(yàn)證碼:只有帶滑塊的圖,沒有不帶滑塊的原圖
有原圖驗(yàn)證碼:有不帶滑塊的圖
上面的注釋可能有些云里霧里,那么以無空隙移動(dòng)滑塊驗(yàn)證碼舉例,無原圖驗(yàn)證碼和有原圖驗(yàn)證碼的圖片如下:
在每個(gè)網(wǎng)站進(jìn)行表單登錄,如間隔較長時(shí)間進(jìn)行微信登錄就有移動(dòng)滑塊驗(yàn)證碼的出現(xiàn),也有在對(duì)多頁進(jìn)行信息爬取的時(shí)為防止是機(jī)器操縱而彈出的移動(dòng)滑塊驗(yàn)證碼。而這些都需要我們?cè)诖a中判別是否需要進(jìn)行驗(yàn)證碼拖動(dòng)。以微信登錄為例子,由于驗(yàn)證碼在第一次登錄肯定是會(huì)彈出來的,因此,我們只需在代碼中一步一步來即可,不用加判斷條件。
而后便是移動(dòng)滑塊驗(yàn)證碼自身的解決問題。換位思考一下,如果不用機(jī)器用的是人工,那么我們會(huì)根據(jù)肉眼的信息自然而然的判斷將滑塊拖動(dòng)到缺口位置,但是機(jī)器是沒有肉眼和判斷力。因此,作為coder,應(yīng)該給予機(jī)器判別能力,能做的即是告訴機(jī)器滑塊的位置以及滑塊移動(dòng)的距離。
在第一部分講解了移動(dòng)滑塊驗(yàn)證碼有兩種類別,有空隙和無空隙的。先介紹無空隙情況下如何實(shí)現(xiàn)滑塊移動(dòng)距離的計(jì)算。
市面上常用的方式是有邊緣檢測(cè)算法,該算法是基于在移動(dòng)滑塊驗(yàn)證碼中,缺口的位置四周邊緣有明顯的斷裂痕跡。邊緣檢測(cè)算法有Canny算子、Sobel算子等進(jìn)行計(jì)算,大致過程就是將原始的移動(dòng)滑塊驗(yàn)證碼圖片進(jìn)行圖像灰度化、高斯平滑繼而識(shí)別到邊緣,整個(gè)過程可以借助Python中的opencv庫進(jìn)行。識(shí)別到邊緣后,對(duì)缺口和滑塊的輪廓面積做一個(gè)限定條件,接著計(jì)算滑塊和缺口的質(zhì)心,進(jìn)而計(jì)算所需位移。不同算子的邊緣檢測(cè)算法準(zhǔn)確度是不一樣的,普遍都較低且位移誤差大。耗時(shí)方面,由于是對(duì)圖像進(jìn)行識(shí)別,可想而知其速度是不盡人意的。對(duì)于無空隙的移動(dòng)滑塊驗(yàn)證碼的情況下,coder僅僅把缺口的質(zhì)心位置識(shí)別出來即可。而對(duì)于有空隙的情況下,就需要計(jì)算滑塊和缺口的質(zhì)心,即設(shè)定滑塊和缺口的輪廓條件,繼而計(jì)算滑塊的移動(dòng)距離。
市面上除了邊緣檢測(cè)算法外,還有一種準(zhǔn)確度較高的,也是普遍再用的方法。這種方法是將帶缺口的移動(dòng)滑塊驗(yàn)證碼和不到缺口的移動(dòng)滑塊驗(yàn)證碼進(jìn)行RGB像素做差。設(shè)定一個(gè)閾值并遍歷兩張圖片中的RGB像素,如果相同地方上的差值小于這個(gè)閾值那么認(rèn)為圖像基本是 一致的,反之則是不一致,可以認(rèn)為是缺口。找到這個(gè)缺口后,對(duì)于無空隙的驗(yàn)證碼圖片來說將缺口的質(zhì)心橫坐標(biāo)計(jì)算出來即是滑動(dòng)的距離。而對(duì)于有空隙的驗(yàn)證碼圖片來說,就需要有原圖移動(dòng)滑塊驗(yàn)證碼圖片和不帶缺口的移動(dòng)滑塊驗(yàn)證碼圖片,這樣滑塊和缺口的位置才能通過RGB像素對(duì)比得到出來。然而,在大多網(wǎng)頁上是不存在有原圖移動(dòng)滑塊驗(yàn)證碼圖片的,需要通過一系列設(shè)置才能夠得到,這將在第三部分案例中詳細(xì)講到。這個(gè)方法可以明顯感覺到準(zhǔn)確度是比較大的,但是要求也是比較苛刻,需要有原圖移動(dòng)滑塊驗(yàn)證碼圖片。
下面從公式角度理解滑塊移動(dòng)距離的計(jì)算,首先是無空隙的移動(dòng)滑塊驗(yàn)證碼,如下圖
可以看到,當(dāng)coder求出滑塊的質(zhì)心坐標(biāo)$C{s}$和缺口的質(zhì)心坐標(biāo)$C{g}$后,直接用橫坐標(biāo)$C{g1}-C{s1}$相減即可。要計(jì)算的滑塊移動(dòng)距離$d$即為$d=C{g1}-C{s1}$,上面講解過其實(shí)無空隙的移動(dòng)滑塊驗(yàn)證碼在編程中可以偷懶,因?yàn)榘雮€(gè)滑塊的長度有時(shí)在某些網(wǎng)頁中是被允許接受的,也即直接計(jì)算缺口的質(zhì)心$C_{s}$作為移動(dòng)距離$d$也是可以的。
接著講解有空隙的移動(dòng)滑塊驗(yàn)證碼的情況,如下圖:
有空隙的情況就可能復(fù)雜點(diǎn),coder直接利用$d=C{g1}-C{s1}$公式得到滑塊的計(jì)算距離是最快的。而如果想要像無空隙移動(dòng)滑塊驗(yàn)證碼一樣偷懶的話是不行的,如上圖直接計(jì)算質(zhì)心$C{g}$的橫坐標(biāo)外,還需要減上空隙的距離、滑塊的一半長度,即$d = C{g1}-d{g}-d{m}$。
在了解了無原圖、有原圖、無空隙、有空隙相關(guān)特征的滑塊驗(yàn)證碼后,本文選擇無原圖有空隙的滑塊驗(yàn)證碼作為案例,選擇小不點(diǎn)搜索網(wǎng)站(https://www.xiaoso.net/)為案例網(wǎng)站,進(jìn)去以后如下圖所示:
該網(wǎng)站是一個(gè)類似于百度、搜狗的這種搜索引擎。它的特點(diǎn)在于,他主要是視頻結(jié)果呈現(xiàn),給出一句關(guān)鍵詞后,會(huì)給出在知名視頻平臺(tái)(B站、youku、qq等)上有關(guān)該關(guān)鍵詞的視頻。因此,小不點(diǎn)對(duì)于經(jīng)常找相關(guān)視頻材料的小伙伴們也是一個(gè)大的福利,可以節(jié)省下不少的時(shí)間。
進(jìn)去以后,可以看到右上角有個(gè)登錄頁面,點(diǎn)進(jìn)去后呈現(xiàn)如下頁面
由于我們是第一次進(jìn)入,也即是新用戶,因此,直接進(jìn)行新用戶注冊(cè)即可,無需掃碼,填寫手機(jī)號(hào)等信息。注冊(cè)之后,讀者們可以嘗試登錄,在輸入完用戶名和密碼后會(huì)彈出一個(gè)驗(yàn)證碼,該驗(yàn)證碼就是本文重點(diǎn)講的無原圖有空隙移動(dòng)滑塊驗(yàn)證碼。我們需要用Python編程實(shí)現(xiàn)自動(dòng)登錄(自動(dòng)表單登錄)
Tips:有讀者會(huì)問實(shí)現(xiàn)這個(gè)小不點(diǎn)自動(dòng)登錄有什么用呢?本文可以給出答案:這個(gè)小不點(diǎn)網(wǎng)站僅在本文做一個(gè)例子體現(xiàn),讓讀者可以清洗明了如何使用Python實(shí)現(xiàn)自動(dòng)登錄。在往后實(shí)現(xiàn)QQ郵箱自動(dòng)登錄、爬蟲時(shí)遇到反爬蟲就可以舉一反三。
接下來將講解如何在Python中實(shí)現(xiàn)小不點(diǎn)網(wǎng)站的自動(dòng)登錄。
首先,我們需要明確下思路,我們做這個(gè)的自動(dòng)登錄的流程圖應(yīng)如下所示:
其實(shí)整個(gè)登錄頁面是很比較簡潔的,我們讓機(jī)器實(shí)現(xiàn)自動(dòng)輸入英文用戶名、密碼、點(diǎn)擊提交即可。整個(gè)過程只有三步,那如何讓機(jī)器找到填寫與點(diǎn)擊的位置呢,我們就需要找到網(wǎng)頁的源代碼,在源代碼中找到三個(gè)元素對(duì)應(yīng)的相關(guān)代碼即可。
如何打開網(wǎng)頁源代碼?在所在頁面按F12即可,然后同時(shí)按住ctrl+shift+C即可快捷的進(jìn)入到鼠標(biāo)拖動(dòng)模式,該模式下利用鼠標(biāo)點(diǎn)擊即可到達(dá)相應(yīng)位置的源代碼,比如點(diǎn)擊"英文用戶名",效果如圖下所示
可以看到"英文用戶名"元素的類名為input,是一個(gè)輸入文本類型,那么如何取出其代碼呢?其實(shí)這里所說的代碼只是籠統(tǒng)的概念,本質(zhì)上是讓機(jī)器識(shí)別出元素的位置。那么識(shí)別元素的位置在網(wǎng)頁中有許多方式,例如利用id去導(dǎo)航,class類去導(dǎo)航、css等。本文則主要選擇xpath去導(dǎo)航,xpath可以理解為機(jī)器(Python中的selenium工具)使用路徑表達(dá)式在 XML 文檔中進(jìn)行導(dǎo)航。除此之外,本文還少量用到name屬性,如上面那張圖,name=“username”在該網(wǎng)頁中是有且只有一個(gè)的,那么就可以直接同name進(jìn)行導(dǎo)航。
具體怎么得到這些元素的相關(guān)屬性實(shí)現(xiàn)導(dǎo)航呢,很簡單,在右側(cè)對(duì)應(yīng)代碼中鼠標(biāo)右鍵點(diǎn)擊,找到copy,選擇"copy xpath"即可。
同理,英文用戶名、密碼、提交均可以使用上述方法。此外,點(diǎn)擊提交后會(huì)彈出移動(dòng)滑塊驗(yàn)證碼。這個(gè)驗(yàn)證碼在實(shí)現(xiàn)滑塊的拖動(dòng)與點(diǎn)擊依舊是上述的xpath元素定位方法。但稍有不同的是,需要先切換到驗(yàn)證碼所在frame中。frame為框,可以理解為在一個(gè)網(wǎng)頁中嵌套的頁面,frame不是獨(dú)立的頁面而是原本網(wǎng)頁中一個(gè)產(chǎn)物。因此,在編程的時(shí)候需要注意,要從原本的frame中切換到驗(yàn)證碼所在的frame,不然會(huì)報(bào)錯(cuò)。
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains import time
from selenium.webdriver.support.ui import WebDriverWait
from chaojiying import Chaojiying_Client
# 啟動(dòng)瀏覽器
def Launch_browser(self): self.driver = webdriver.Chrome() self.wait = WebDriverWait(self.driver, 10, 0.5) self.driver.get(self.url)
account = self.account
pwd = self.pwd self.driver.find_element_by_name('username').send_keys(account) self.driver.find_element_by_name('password').send_keys(pwd) self.driver.find_element_by_xpath(self.enter).click()
# 等待className為geetest_slider_button的元素在元素表中出現(xiàn)
time.sleep(2)
這段代碼是使用類定義編寫的,首先引入相關(guān)庫。
webdriver.Chrome()這句函數(shù)是調(diào)出Google瀏覽器,比如在anaconda中的spyder編譯器,會(huì)彈出一個(gè)Google瀏覽器頁面。這相當(dāng)于完成機(jī)器自動(dòng)打開瀏覽器這一操作。接下來就是讓機(jī)器跳轉(zhuǎn)到小不點(diǎn)搜索網(wǎng)站,用的是self.driver.get(self.url)這一函數(shù)。self.url這里指的是小不點(diǎn)搜索網(wǎng)站的網(wǎng)址。
跳轉(zhuǎn)后就會(huì)到熟悉的登錄界面,在界面中如何導(dǎo)航到英文用戶名和密碼對(duì)應(yīng)的位置并輸入進(jìn)去呢?代碼中
account = self.account ##輸入小不點(diǎn)注冊(cè)的賬號(hào) pwd = self.pwd #輸入小不點(diǎn)注冊(cè)的密碼 self.driver.find_element_by_name('username').send_keys(account) # 找到賬號(hào)位置并給予信息 self.driver.find_element_by_name('password').send_keys(pwd) #找到密碼位置并給予信息 self.driver.find_element_by_xpath(self.enter).click() #模擬點(diǎn)擊提交按鈕
便是導(dǎo)航到元素對(duì)應(yīng)位置與點(diǎn)擊提交的操縱,可以看到本文使用name元素定位的,這也應(yīng)征了上一部分所說,'username'和'password'在該頁面是獨(dú)立存在。最后的代碼time.sleep(2)是防止網(wǎng)速過慢導(dǎo)致滑塊驗(yàn)證碼出現(xiàn)延遲而跟不上機(jī)器識(shí)別的節(jié)奏導(dǎo)致的問題出現(xiàn)。
接下來就是移動(dòng)滑塊驗(yàn)證碼的破解,破解當(dāng)然需要超級(jí)鷹,但是超級(jí)鷹服務(wù)的引入下一部分在說明。而破解的前提是要獲取移動(dòng)滑塊驗(yàn)證碼的圖片,這里本文將利用selenium庫中的截屏功能,將移動(dòng)滑塊驗(yàn)證碼的圖片整一張保存至本地中。代碼如下
# 移動(dòng)滑塊驗(yàn)證碼截圖 def get_picture(self): self.driver.switch_to_frame(self.frame) #一定要轉(zhuǎn)到驗(yàn)證碼的框,才能定位?。?! self.slider = self.driver.find_element_by_xpath(self.slider_xpath) ## 先將滑塊隱藏,獲取原圖,在截圖,在復(fù)原 self.driver.execute_script("document.getElementsByClassName('{}')[0].style['display'] = 'none'".format(self.gap_xpath)) self.driver.find_element_by_xpath('//*[@id="slideBgWrap"]').screenshot(self.file_path) self.driver.find_element_by_xpath(self.img_xpath).screenshot(self.file_path2) self.driver.execute_script("document.getElementsByClassName('{}')[0].style['display'] = 'block'".format(self.gap_xpath))
首先依舊采用類與對(duì)象的寫法,第一行代碼是將frame轉(zhuǎn)到移動(dòng)滑塊驗(yàn)證碼所在的框中,第二行則是通過xpath路徑導(dǎo)航到滑塊的地方。接著則是驗(yàn)證碼截圖部分重要的地方,前面講了該案例是解決無原圖有空隙的移動(dòng)滑塊驗(yàn)證碼。如果整個(gè)過程交給了超級(jí)鷹那么無原圖有空隙這兩個(gè)問題變迎刃而解。但是,如果采用市面上常用的方法呢,那么無原圖怎么解決呢?第3行到最后一行代碼就是答案。同樣是利用selenium庫的功能,首先通過多次試驗(yàn),作者發(fā)現(xiàn)在網(wǎng)頁源代碼上做特定的修改就會(huì)使驗(yàn)證碼圖像變回原來的圖像,不會(huì)帶缺口的。修改方式就是在
document.getElementsByClassName('{}')[0]處賦予沒有缺口屬性.style['display'] = 'none'。賦予之后就會(huì)呈現(xiàn)原圖,接著利用xpath導(dǎo)航至驗(yàn)證碼原圖的位置并screenshot截圖一下即可完成移動(dòng)滑塊驗(yàn)證碼圖片的本地保存。最后復(fù)原驗(yàn)證碼圖片,在修改處改為.style['display'] = 'block',即可重新出現(xiàn)缺口。下載下來的圖片如下圖所示(tips:由于每一次登錄的驗(yàn)證碼圖片都不一致,這里展現(xiàn)實(shí)驗(yàn)時(shí)的一次。)
得到了驗(yàn)移動(dòng)滑塊驗(yàn)證碼圖片之后,我們需要計(jì)算滑塊到缺口的距離,這時(shí)候使用Chaojiying無疑是高效實(shí)現(xiàn)。
在超級(jí)鷹平臺(tái)上有一個(gè)名為"Chaojiying"的Python API接口,是平臺(tái)寫好并讓Python user來直接調(diào)用的,下載地址為:
https://www.chaojiying.com/download/Chaojiying_Python.rar。而在main主程序上我們只需要在同一路徑下實(shí)現(xiàn)該代碼即可
from chaojiying import Chaojiying_Client
引入該服務(wù)后,需要上傳在超級(jí)鷹平臺(tái)注冊(cè)的賬號(hào)密碼,還有需要識(shí)別的驗(yàn)證碼圖片。具體代碼如下:
# 超級(jí)鷹 def cjy(self): # 用戶中心>>軟件ID 生成一個(gè)替換 910001 self.chaojiying = Chaojiying_Client('', '', '') # chaojiying = Chaojiying_Client('超級(jí)鷹用戶名', '超級(jí)鷹密碼', '910001') # 本地圖片文件路徑 來替換 a.jpg 有時(shí)WIN系統(tǒng)須要// im = open('./img/code_picture2.png', 'rb').read() #驗(yàn)證碼圖片存放位置 # 9101 驗(yàn)證碼類型 官方網(wǎng)站>>價(jià)格體系 3.4+版 print 后要加() # 咨詢了一下滑動(dòng)驗(yàn)證碼是選擇9101 re = self.chaojiying.PostPic(im, 9101) print('兩個(gè)坐標(biāo)') print(re) # 減去一半滑塊長度 self.diff = int(re['pic_str'].split(',')[0]) self.distance = int(re['pic_str'].split('|')[1].split(',')[0]) - self.diff print(self.distance) self.im_id = re['pic_id'] print(self.im_id)
解析:首先讀者需要在Chaojiying_client這句函數(shù)里面寫上相關(guān)的用戶名、密碼和軟件ID。其次以二進(jìn)制格式讀取移動(dòng)滑塊驗(yàn)證碼圖片并使用Chaojiying內(nèi)置函數(shù)Postpic上傳至平臺(tái)。這樣平臺(tái)就會(huì)返回我們滑塊到缺口gap的坐標(biāo),我們利用兩坐標(biāo)相減即可得到路徑。注意:在得到路徑上應(yīng)該減去一半滑塊長度,在第二部分已經(jīng)講解為何減去一半滑塊長度。
在得到滑塊移動(dòng)的路徑后,更謹(jǐn)慎的我們還需要賦予滑塊一個(gè)速度,以防止網(wǎng)站發(fā)現(xiàn)是機(jī)器人操縱。具體代碼如下:
# 獲取移動(dòng)軌跡 def get_track(self): self.track = []
mid = self.distance * 3 / 5 current = 0 t = 0.2 v = 0 while current < self.distance: if current < mid: a = 8 else: a = -12 v0 = v
v = v0 + a * t
move = v * t + 1 / 2 * a * t * t
current += move self.track.append(round(move))
print(self.track) # 模擬移動(dòng) def move(self): self.track = self.track
ActionChains(self.driver).click_and_hold(self.slider).perform() for x in self.track: ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(2)
ActionChains(self.driver).release().perform() self.slider.click()
第一個(gè)def類---get_track就是定義滑塊的移動(dòng)每0.2秒的移動(dòng)距離。本文定義為在移動(dòng)路徑的$frac{2}{5}$路徑之前加速度為8,即做加速直線運(yùn)動(dòng)。后半程的加速度為-12即做減速直線運(yùn)動(dòng)。結(jié)合速度公式和位移公式即可得到每一步滑塊需要走多遠(yuǎn)。
最后使用selenium庫中的懸停鼠標(biāo)工具ActionChains拖拽住滑塊,遍歷每一步的步長,講滑塊移動(dòng)到缺口位置。
可以看到上述的代碼時(shí)以類方式封裝的,因此介紹上使用者如何運(yùn)行代碼,首先是主程序main
from no_img import scratch_main
url = 'https://www.xiaoso.net/m/member/action/login'
username = '' #輸入小不點(diǎn)賬號(hào) password = '' #輸入小不點(diǎn)密碼 enter_xpath = '//*[@id="TencentCaptcha"]'
frame = 'tcaptcha_iframe'
slider_xpath = '//*[@id="tcaptcha_drag_thumb"]'
gap_xpath = 'tc-jpp-img unselectable'
img_xpath = '//*[@id="slideBgWrap"]'
process = scratch_main(url,username,password,enter_xpath,frame,slider_xpath,gap_xpath,img_xpath)
process.main()
這個(gè)需要使用者在username和password上輸入自己在小不點(diǎn)上注冊(cè)的賬號(hào)密碼,接著是no_img程序,
'''
無原圖滑塊驗(yàn)證碼案例
author:henry
''' from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from PIL import Image
from chaojiying import Chaojiying_Client class scratch_main(): def __init__(self,url,username,password,enter_xpath,frame,slider_xpath,gap_xpath,img_xpath): self.url = url self.file_path = './img/code_picture.png' self.file_path2 = './img/code_picture2.png' self.distance = 0 self.key = 0 self.account = username self.pwd = password self.enter = enter_xpath self.frame = frame self.slider_xpath = slider_xpath self.gap_xpath = gap_xpath self.img_xpath = img_xpath # 啟動(dòng)瀏覽器 def Launch_browser(self): self.driver = webdriver.Chrome() self.wait = WebDriverWait(self.driver, 10, 0.5) self.driver.get(self.url)
account = self.account
pwd = self.pwd
time.sleep(2) self.driver.find_element_by_name('username').send_keys(account) self.driver.find_element_by_name('password').send_keys(pwd) self.driver.find_element_by_xpath(self.enter).click()
time.sleep(2) self.driver.switch_to_frame(self.frame) #一定要轉(zhuǎn)到驗(yàn)證碼的框,才能定位?。。?/span> self.slider = self.driver.find_element_by_xpath(self.slider_xpath) # 截圖 def get_picture(self): ## 先將滑塊隱藏,獲取原圖,在截圖,在復(fù)原 self.driver.find_element_by_xpath(self.img_xpath).screenshot(self.file_path2) self.driver.execute_script("document.getElementsByClassName('{}')[0].style['display'] = 'block'".format(self.gap_xpath)) # 分割截圖獲取驗(yàn)證碼圖片,由于使用超級(jí)鷹,所以直接用上面截圖驗(yàn)證碼部分即可,不用截圖缺口 def crop_picture(self):
pass # 超級(jí)鷹 def cjy(self): # 用戶中心>>軟件ID 生成一個(gè)替換 910001 self.chaojiying = Chaojiying_Client('', '', '') # chaojiying = Chaojiying_Client('超級(jí)鷹用戶名', '超級(jí)鷹密碼', '910001') # 本地圖片文件路徑 來替換 a.jpg 有時(shí)WIN系統(tǒng)須要// im = open('./img/code_picture2.png', 'rb').read()
re = self.chaojiying.PostPic(im, 9202)
print('兩個(gè)坐標(biāo)')
print(re) # print(re['pic_str']) # 減去一半滑塊長度 self.diff = int(re['pic_str'].split(',')[0]) self.distance = int(re['pic_str'].split('|')[1].split(',')[0]) - self.diff
print(self.distance) self.im_id = re['pic_id']
print(self.im_id) # 獲取軌跡 def get_track(self): self.track = []
mid = self.distance * 2 / 5 current = 0 t = 0.2 v = 0 while current < self.distance: if current < mid: a = 8 else: a = -12 v0 = v
v = v0 + a * t
move = v * t + 1 / 2 * a * t * t
current += move self.track.append(round(move))
print(self.track) # 模擬移動(dòng) def move(self): self.track = self.track
ActionChains(self.driver).click_and_hold(self.slider).perform() for x in self.track: ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(2)
ActionChains(self.driver).release().perform() self.slider.click() def check(self):
pass # 關(guān)閉瀏覽器 def quit(self):
time.sleep(5) self.driver.quit() # main方法 def main(self): self.Launch_browser() self.get_picture() self.crop_picture() self.cjy() self.get_track() self.move() self.check() if __name__ == '__main__':
ma = scratch_main()
ma.main()
這里需要使用者在cjy類中輸入自己在超級(jí)鷹上注冊(cè)的賬號(hào)密碼和軟件ID。此外,使用者需要把main、Chaojiying、no_img三個(gè)程序放到一個(gè)相同路徑下。
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
LSTM 模型輸入長度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報(bào)考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計(jì)的實(shí)用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實(shí)施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價(jià)值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時(shí)代,BI ...
2025-07-10SQL 在預(yù)測(cè)分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢(shì)預(yù)判? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代,預(yù)測(cè)分析作為挖掘數(shù)據(jù)潛在價(jià)值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價(jià)值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點(diǎn),而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報(bào)考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢(shì)性檢驗(yàn):捕捉數(shù)據(jù)背后的時(shí)間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢(shì)性檢驗(yàn)如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時(shí)間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時(shí)間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實(shí)戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗(yàn):數(shù)據(jù)趨勢(shì)與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢(shì)變化以及識(shí)別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對(duì)策略? 長短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨(dú)特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計(jì)學(xué)方法在市場調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場調(diào)研是企業(yè)洞察市場動(dòng)態(tài)、了解消費(fèi)者需求的重要途徑,而統(tǒng)計(jì)學(xué)方法則是市場調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動(dòng)力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動(dòng)力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價(jià)值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03