引言
度過了短暫的春節假期,又要開始繼續搬磚了,因為還處於節後 綜合徵,各種散漫,不想看任何程式碼相關的東西,根本擠不出學習熱情... 恰逢前幾天,公司的UI妹子安利了一個賣萌的新番:小木乃伊到我家
就是圖中的這四隻小東西,敲可愛的說,分別叫:
小伊(木乃伊),可尼(小鬼,牛),啊勇(龍),胖嘟嘟
UI妹子尤其喜歡可尼,是挺萌的,突然想找些相關的手機或者電腦桌布,
桌布沒找到,卻在 小木乃伊到我家吧
裡找到了一些自制的表情包:
tieba.baidu.com/p/552209106…
表情都很有趣嘛,寫個指令碼把圖片都爬下來?走一波流程:
Step 1:Network抓包看下返回的資料是否和Element一致, 或者說有我們想要的資料,而不是通過JS黑魔法進行載入的;
複製下第一個圖的圖片連結,到Network選項卡里的Response 裡查詢以下,嗯,找得到,可以:
Step 2:滾動到底,抓包沒有發現Ajax動態載入資料的蹤跡
Step 3:點選第二頁,抓包發現了Ajax載入的痕跡!!!
同樣拿第一個圖的url搜下,同樣可以找到
三個引數猜測pn為page_number,即頁數,PostMan或者自己 寫程式碼模擬請求,記得塞入Host和X-Requested-With,驗證pn=1 是否為第一頁資料,驗證通過,即所有頁面資料都可以通過這個 介面拿到;
Step 4:先載入拿到末頁是第幾頁,然後走一波迴圈遍歷即可 解析資料獲得圖片url,寫入檔案,使用多個執行緒進行下載 比較簡單,就不詳解了,直接給出程式碼,看不懂的自己複習去:
# 抓取百度貼吧某個帖子裡的所有圖片
import coderpig_n as cpn
import requests
import time
import threading
import queue
tiezi_url = "https://tieba.baidu.com/p/5522091060"
headers = {
'Host': 'tieba.baidu.com',
'User-Agent': cpn.user_agent_dict['chrome'],
}
pic_save_dir = 'output/Picture/BaiduTieBa/'
pic_urls_file = 'tiezi_pic_urls.txt'
download_q = queue.Queue() # 下載佇列
# 獲得頁數
def get_page_count():
try:
resp = requests.get(tiezi_url, headers=headers, timeout=5)
if resp is not None:
soup = cpn.get_bs(resp.text)
a_s = soup.find("ul", attrs={'class': 'l_posts_num'}).findAll("a")
for a in a_s:
if a.get_text() == '尾頁':
return a['href'].split('=')[1]
except Exception as e:
print(str(e))
# 下載執行緒
class PicSpider(threading.Thread):
def __init__(self, t_name, func):
self.func = func
threading.Thread.__init__(self, name=t_name)
def run(self):
self.func()
# 獲得每頁裡的所有圖片
def get_pics(count):
while True:
params = {
'pn': count,
'ajax': '1',
't': int(time.time())
}
try:
resp = requests.get(tiezi_url, headers=headers, timeout=5, params=params)
if resp is not None:
soup = cpn.get_bs(resp.text)
imgs = soup.findAll('img', attrs={'class': 'BDE_Image'})
for img in imgs:
cpn.write_str_data(img['src'], pic_urls_file)
return None
except Exception as e:
pass
pass
# 下載執行緒呼叫的方法
def down_pics():
global download_q
while not download_q.empty():
data = download_q.get()
download_pic(data)
download_q.task_done()
# 下載呼叫的方法
def download_pic(img_url):
while True:
proxy_ip = {
'http': 'http://' + cpn.get_dx_proxy_ip(),
'https': 'https://' + cpn.get_dx_proxy_ip()
}
try:
resp = requests.get(img_url, headers=headers, proxies=proxy_ip, timeout=5)
if resp is not None:
print("下載圖片:" + resp.request.url)
pic_name = img_url.split("/")[-1]
with open(pic_save_dir + pic_name, "wb+") as f:
f.write(resp.content)
return None
except Exception as e:
pass
if __name__ == '__main__':
cpn.is_dir_existed(pic_save_dir)
print("檢索判斷連結檔案是否存在:")
if not cpn.is_dir_existed(pic_urls_file, mkdir=False):
print("不存在,開始解析帖子...")
page_count = get_page_count()
if page_count is not None:
headers['X-Requested-With'] = 'XMLHttpRequest'
for page in range(1, int(page_count) + 1):
get_pics(page)
print("連結已解析完畢!")
headers.pop('X-Requested-With')
else:
print("存在")
print("開始下載圖片~~~~")
headers['Host'] = 'imgsa.baidu.com'
pic_list = cpn.load_list_from_file(pic_urls_file)
threads = []
for pic in pic_list:
download_q.put(pic)
for i in range(0, len(pic_list)):
t = PicSpider(t_name='執行緒' + str(i), func=down_pics)
t.daemon = True
t.start()
threads.append(t)
download_q.join()
for t in threads:
t.join()
print("圖片下載完畢")
複製程式碼
執行結果:
接著在和UI妹子聊天的時候就可以拿這些表情來鬥圖了,但是問題來了, 總共有165個圖,我每次想說什麼都要開啟圖片一個個看文字是否 符合場景,然後才發,有點呆,而且浪費時間,有沒有什麼快點 找到表情的方法呢?
答:直接把表情裡的文字作為圖片名不就好了,直接檔案搜尋搜關鍵字;
但是問題又來了,一張張去改檔名?多呆哦!
突然想起之前看過一篇**頭腦王者
**答題輔助指令碼的文章,就是
利用OCR文字識別,把識別出來的文字丟百度上搜尋,選項頻度最高
的一般就是正確答案,可以試一波這個套路,谷歌為我們提供了一個
免費的ORC文字識別引擎:Tesseract
倉庫地址:github.com/tesseract-o…
1.裝一波環境
穩定版本是3.0,4.0版本還處於研發,一開始以為新版的肯定牛逼 一些,裝了4.0的發現對於中文的識別效率超低,差太遠了,後來 又換回了3.0版本,情況稍微好一些,當然可以通過其他方法提高 中文識別率,圖片裁剪,調節對比度,黃底黑字,自己訓練語言庫等, 不是本節的學習範疇,本節寫個簡單的例子瞭解下怎麼用而已~
更多可移步到:ubuntu下使用Tesseract-ocr(編譯、安裝、使用、訓練新的語言庫) 各個版本介紹:github.com/tesseract-o…
Ubuntu 14.04 環境安裝(其他系統環境後續用到再補充...)
1.安裝tesseract-ocr
sudo apt-get install tesseract-ocr
tesseract --version
複製程式碼
2.安裝pytesseract與Image
sudo pip install pytesseract
sudo pip install Image
複製程式碼
3.下載tesseract中文簡體字型檔
預設安裝後是不帶中文簡體庫的,官方倉庫走一波: github.com/tesseract-o… 記得選擇版本Tag,3.0的tesseract-ocr是用不了4.0的字型檔的!!! 如果你下錯了,呼叫的時候會報3.0用不了4.0的字型檔的錯誤!!!
這兩個就是對應中文簡體與繁體:
字型檔下載後需要放到下面的目錄下:/usr/share/tesseract-ocr/tessdata
然後你發現字型檔檔案無法拷貝到該目錄下,因為需要許可權,這裡可以通過
命令列拷貝一波:
sudo cp '/home/jay/下載/chi_sim.traineddata' /usr/share/tesseract-ocr/tessdata
複製程式碼
前面是原始檔,後面是拷貝到哪個目錄下。
好了,到此就準備完成了,接著寫個簡單的程式來識別一波!
2.識別一波圖片
程式碼忒簡單,建立一個Image物件,呼叫下**pytesseract.image_to_string()**方法 就能識別文字了,引數依次是Image物件,識別語言型別,chi_sim中文簡體
import pytesseract
from PIL import Image
image = Image.open('1.png')
text = pytesseract.image_to_string(image, lang='chi_sim')
print(text.replace(" ", ""))
複製程式碼
隨手截一波掘金首頁的分類欄:
執行一波:
識別結果有點感人,調一張表情圖試試:
識別結果:
???都識別出來什麼東西,後面試了幾張圖片我還發現不止識別 錯誤,有時連字都識別不出來...在不自己去訓練字型庫的情況下, 中文識別率真心感人,不過最大的有點優點還是:Tesseract免費。 識別數字或者英語的時候,還湊合,隨手複製一段英文:
設定下lang='eng',輸出結果:
免費的識別率低,試試收費的怎樣,百度雲OCR
3.試試百度雲OCR
收費,每天免費500次,拿來完成我們這個圖片命名的小指令碼足矣! 官方文件:文字識別 - Python SDK文件
配置流程:
1.開通文字識別服務:cloud.baidu.com/product/ocr…
2.建立一個應用,然後記下API Key 和 Secret Key 程式裡要用
3.點右上角->使用者中心,抄下自己的使用者ID
4.pip命令安裝一波
sudo pip install baidu-aip
複製程式碼
編寫簡單程式碼:
from aip import AipOcr
# 新建一個AipOcr物件
config = {
'appId': 'XXX',
'apiKey': 'YYY',
'secretKey': 'ZZZ'
}
client = AipOcr(**config)
# 讀取圖片
def get_file_content(file_path):
with open(file_path, 'rb') as fp:
return fp.read()
# 識別圖片裡的文字
def img_to_str(image_path):
image = get_file_content(image_path)
# 呼叫通用文字識別, 圖片引數為本地圖片
result = client.basicGeneral(image)
# 結果拼接返回
if 'words_result' in result:
return '\n'.join([w['words'] for w in result['words_result']])
if __name__ == '__main__':
print(img_to_str('1.png'))
複製程式碼
試試上面掘金的那個,輸出結果:
嘖嘖,可以的,試試搞基那個表情?
嗯,還是有點小錯誤,在文件裡找到:
把**basicGeneral
** 改為 basicAccurate
,結果:
嘖嘖,完美識別,稍微慢了一點點,接下來把程式碼完善下, 把所有的圖片重新命名一波咯!
4.實戰:利用百度OCR識別自動修改檔名
遍歷資料夾,獲得所有的圖片路徑,然後文字識別一波,獲得結果集 里長度最長的字串作為檔名,能識別的就修改下檔名,完整程式碼 如下:
import os
from aip import AipOcr
# 新建一個AipOcr物件
config = {
'appId': 'XXX',
'apiKey': 'YYY',
'secretKey': 'ZZZ'
}
client = AipOcr(**config)
pic_dir = r"/home/jay/圖片/BaiduTieBa/"
# 讀取圖片
def get_file_content(file_path):
with open(file_path, 'rb') as fp:
return fp.read()
# 識別圖片裡的文字
def img_to_str(image_path):
image = get_file_content(image_path)
# 呼叫通用文字識別, 圖片引數為本地圖片
result = client.basicGeneral(image)
# 結果拼接返回
words_list = []
if 'words_result' in result:
if len(result['words_result']) > 0:
for w in result['words_result']:
words_list.append(w['words'])
file_name = get_longest_str(words_list)
print(file_name)
os.rename(image_path, pic_dir + str(file_name).replace("/", "") + '.jpg')
# 獲取字串列表中最長的字串
def get_longest_str(str_list):
return max(str_list, key=len)
# 遍歷某個資料夾下所有圖片
def query_picture(dir_path):
pic_path_list = []
for filename in os.listdir(dir_path):
pic_path_list.append(dir_path + filename)
return pic_path_list
if __name__ == '__main__':
pic_list = query_picture(pic_dir)
if len(pic_list) > 0:
for i in pic_list:
img_to_str(i)
複製程式碼
執行結果:
要注意一點,高精度版免費只有50次,我一開始不知道,後面跑程式 突然卡住一直不動,這點要注意,後面還是用回了普通模式,所以有 些檔名並不完全是對的,就調調API的事,非常簡單,專案有極大 剛需要用到文字識別的自行去官網瞭解吧~
5.小結
本節簡單的瞭解了一下pytesseract這個免費的OCR識別庫, 對於中文的識別率不高,後面試了下百度雲OCR,順道寫了 一個簡單的實戰專案,都比較簡單,那麼本節就到這裡啦~
來啊,Py交易啊
想加群一起學習Py的可以加下,智障機器人小Pig,驗證資訊裡包含: Python,python,py,Py,加群,交易,屁眼 中的一個關鍵詞即可通過;
驗證通過後回覆 加群 即可獲得加群連結(不要把機器人玩壞了!!!)~~~ 歡迎各種像我一樣的Py初學者,Py大神加入,一起愉快地交流學♂習,van♂轉py。