主要實現功能:
- 登陸網頁
- 動態等待網頁加載
- 驗證碼下載
很早就有一個想法,就是自動按照腳本執行一個功能,節省大量的人力——個人比較懶?;藥滋鞂懥藢?,本著想完成驗證碼的識別,從根本上解決問題,只是難度太高,識別的準確率又太低,計劃再次告一段落。
希望這次經歷可以與大家進行分享和交流。
Python打開瀏覽器
相比與自帶的urllib2模塊,操作比較麻煩,針對于一部分網頁還需要對cookie進行保存,很不方便。于是,我這里使用的是Python2.7下的selenium模塊進行網頁上的操作。
測試網頁:http://graduate.buct.edu.cn
打開網頁:(需下載chromedriver)
為了支持中文字符輸出,我們需要調用sys模塊,把默認編碼改為 UTF-8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<code class = "hljs python" > from selenium.webdriver.support.ui import Select, WebDriverWait from selenium import webdriver from selenium import common from PIL import Image import pytesser import sys reload (sys) sys.setdefaultencoding( 'utf8' ) broswer = webdriver.Chrome() broswer.maximize_window() username = 'test' password = 'test' url = 'http://graduate.buct.edu.cn' broswer.get(url)< / code> |
等待網頁加載完畢
使用的是selenium中的WebDriverWait,上面的代碼中已經加載
1
2
3
4
5
|
<code class = "hljs livecodeserver" >url = 'http://graduate.buct.edu.cn' broswer.get(url) wait = WebDriverWait(webdriver, 5 ) #設置超時時間5s # 在這里輸入表單填寫并加載的代碼 elm = wait.until( lambda webdriver: broswer.find_element_by_xpath(xpathMenuCheck))< / code> |
元素定位、字符輸入
接下來我們需要進行登錄操作:這里我使用的是Chrome,右鍵選擇需要進行填寫內容的部分,選擇檢查,會自動轉跳到 F12下的開發者模式(全程需要這個功能來找到相關的資源)。
vczKprbLJnJkcXVvO9Gh1PHT0LnYtcSyv7fWPGJyIC8+DQo8aW1nIGFsdD0="這里寫圖片描述" sr c="uploadfile/Collfiles/20160414/20160414092144893.png" src="/uploads/allimg/200819/101P05S0-1.png" />
這里,我需要的是功能是自動對學術報告進行報名
對需要已有的報告右鍵即可發現和這個活動有關的消息,因現在沒有報告,所以只顯示了標題,但對于后面的有效報告識別有相似的地方。
對于元素的定位,我優先選擇了 xpath,根據測試,可以唯一定位一個元素的位置,很好用。
1
|
<code class = "hljs perl" > / / * [@ id = "dgData00" ] / tbody / tr / td[ 2 ] (前面是xpath)< / code> |
爬取信息
接下來我們要進行的步驟是爬取現有的有效報告:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<code class = "hljs axapta" > # 尋找有效報告 flag = 1 count = 2 count_valid = 0 while flag: try : category = broswer.find_element_by_xpath( '//*[@id="dgData00"]/tbody/tr[' + str (count) + ']/td[1]' ).text count + = 1 except common.exceptions.NoSuchElementException: break # 獲取報告信息 flag = 1 for currentLecture in range ( 2 , count): # 類別 category = broswer.find_element_by_xpath( '//*[@id="dgData00"]/tbody/tr[' + str (currentLecture) + ']/td[1]' ).text # 名稱 name = broswer.find_element_by_xpath( '//*[@id="dgData00"]/tbody/tr[' + str (currentLecture) + ']/td[2]' ).text # 單位 unitsPublish = broswer.find_element_by_xpath( '//*[@id="dgData00"]/tbody/tr[' + str (currentLecture) + ']/td[3]' ).text # 開始時間 startTime = broswer.find_element_by_xpath( '//*[@id="dgData00"]/tbody/tr[' + str (currentLecture) + ']/td[4]' ).text # 截止時間 endTime = broswer.find_element_by_xpath( '//*[@id="dgData00"]/tbody/tr[' + str (currentLecture) + ']/td[5]' ).text< / code> |
爬取驗證碼
對網頁中的驗證碼進行元素審查后,我們發現了其中的一個一個鏈接,是 IdentifyingCode.apsx,后面我們就對這個頁面進行加載,并批量獲取驗證碼。
爬取的思路是用selenium截取當前頁面(僅顯示部分),并保存到本地——需要翻頁并截取特定位置的請研究:
broswer.set_window_position(**)相關函數;然后人工進行驗證碼的定位,通過PIL模塊進行截取并保存。
最后調用谷歌在Python下的pytesser進行字符識別,但這個網站的驗證碼有很多的干擾,外加字符旋轉,僅僅能識別其中的一部分字符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<code class = "hljs livecodeserver" > # 獲取驗證碼并驗證(僅僅一幅) authCodeURL = broswer.find_element_by_xpath( '//*[@id="Table2"]/tbody/tr[2]/td/p/img' ).get_attribute( 'src' ) # 獲取驗證碼地址 broswer.get(authCodeURL) broswer.save_screenshot( 'text.png' ) rangle = ( 0 , 0 , 64 , 28 ) i = Image. open ( 'text.png' ) frame4 = i.crop(rangle) frame4.save( 'authcode.png' ) qq = Image. open ( 'authcode.png' ) text = pytesser.image_to_string(qq).strip()< / code> <code class = "hljs axapta" > # 批量獲取驗證碼 authCodeURL = broswer.find_element_by_xpath( '//*[@id="Table2"]/tbody/tr[2]/td/p/img' ).get_attribute( 'src' ) # 獲取驗證碼地址 # 獲取學習樣本 for count in range ( 10 ): broswer.get(authCodeURL) broswer.save_screenshot( 'text.png' ) rangle = ( 1 , 1 , 62 , 27 ) i = Image. open ( 'text.png' ) frame4 = i.crop(rangle) frame4.save( 'authcode' + str (count) + '.png' ) print 'count:' + str (count) broswer.refresh() broswer.quit()< / code> |
爬取下來的驗證碼
一部分驗證碼原圖:
從上面的驗證碼看出,字符是帶旋轉的,而且因為旋轉造成的重疊對于后續的識別也有很大的影響。我曾嘗試過使用神經網絡進行訓練,但因沒有進行特征向量的提取,準確率低得離譜。
關于Python爬蟲爬驗證碼實現功能詳解就給大家介紹到這里,希望對大家有所幫助!