python爬取20000個單詞音訊
阿新 • • 發佈:2019-01-13
雖然單詞現在隨處可見,但是對於鍛鍊技術來說是一個好方法,這篇部落格將從找目標到程式碼完整的記錄此過程。
真實需求:
下載了20000個單詞,結果只有單詞沒有音訊,這怎麼行呢?
作為一名喜歡自動化的童鞋來說,才不會再去網上找音訊,所以乾脆寫個程式吧。
步驟
1、找一個查單詞的網站,找到單詞發音的地址
2、使用python下載儲存
接下來就一步步來
1、網站與地址
經過多次查詢,發現以前有前輩寫過的,但是那是個外國網站,而且實在難得操作,所以乾脆找個國內的,然後發現幾乎都不能直接找到地址,是通過js觸發的,於是在js程式碼裡找到地址:
1、此網站
http://www.chadanci.com/
2、找到頁面發音的a標籤:
<a onmouseover="asplay('and', 0)" onclick="asplay('and', 0)" class="play_word" href="javascript:;" title="真人發音"></a>
3、找到對應此函式的js程式碼:
在source裡找到:http://www.chadanci.com/images/js/_xml_content.js
裡面的方法:
function play_sentence(liju){
$.ajax({
type: "GET",
url: "/e/extend/s/file.php?type=sentence" ,
data: "q="+encodeURIComponent(liju),
success: function(url){
var asound = getFlashObject("asound");
if(asound){
asound.SetVariable("f",url);
asound.GotoFrame(1);
}
}
});
}
4、構造查詢地址:
http://www.chadanci .com/e/extend/s/file.php?type=0&world=and
很清楚就出來了:0是英式發音,1是美式,word是單詞
5、但是查詢這個頁面返回的是音訊mp3的地址,可以直接進行下載。
2、使用python下載儲存
因為是GET連結,可能伺服器沒有過多在意爬蟲,所以也不搞代理和分散式了。
最開始想法非常簡單:
1、讀取單詞文字
2、構造連結進行下載
3、寫入文字
def download(word):
url = "http://www.chadanci.com//e/extend/s/file.php?type=0&world="+word
req = urllib2.Request(url)
req.add_header("User-Agent",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36")
res_data = urllib2.urlopen(req)
mp3_url = res_data.read()
#print mp3_url
if mp3_url is None:
return
try:
f = urllib2.urlopen(mp3_url)
with open("mp3/"+word+".mp3", "wb") as fword:
fword.write(f.read())
except:
print "error1"
def process(file_name):
done = [] #儲存已下載單詞
#進度處理
with open(file_name) as f:
words = f.readlines()
num = len(words)
i = 0
width = num/100 #用來控制進度
p = '#'
while i<num:
word = words[i].strip('\n')
# print word
try:
if word not in done:
download(word)
#加入已下載列表
done.append(word)
except:
print "error2"
i+=1
if i%width==0:
p+='#'
#原地重新整理進度
sys.stdout.write(str((i*1.0/num)*100)+"% :"+p+"->"+"\r")
sys.stdout.flush()
if __name__=='__main__':
process('word.txt')
結果:
發現到某個單詞會卡住,然後整個就卡了,後來發現作出如下改正:
1、設定延時:
res_data = urllib2.urlopen(req,timeout=3)
2、採用多執行緒處理
3、改進程式碼
也許一次沒有下載完,所以考慮將已下載的單詞寫入檔案。
#!/usr/bin/env python
# coding=utf-8
import urllib2
import threading
import sys
#執行緒類
class MyThread(threading.Thread):
def __init__(self,target,args):
super(MyThread,self).__init__()
self.target = target
self.args = args
def run(self):
self.target(self.args)
def download(word):
url = "http://www.chadanci.com//e/extend/s/file.php?type=0&world="+word
req = urllib2.Request(url)
req.add_header("User-Agent",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36")
#延時
res_data = urllib2.urlopen(req,timeout=3)
mp3_url = res_data.read()
#print mp3_url
if mp3_url is None:
return
try:
f = urllib2.urlopen(mp3_url)
with open("mp3/"+word+".mp3", "wb") as fword:
fword.write(f.read())
with open("done_word.txt","ab") as done:
done.write(word+"\n")
except:
print "error1"
def process(file_name):
#從檔案把已下載單詞加入列表裡
done = []
#繼續下載
with open(file_name) as f:
words = f.readlines()
num = len(words)
i = 0
width = num/100
p = '#'
while i<num:
word = words[i].strip('\n')
# print word
try:
if word not in done:
download(word)
#加入已下載列表
done.append(word)
except:
print "error2"
i+=1
if i%width==0:
p+='#'
sys.stdout.write(str((i*1.0/num)*100)+"% :"+p+"->"+"\r")
sys.stdout.flush()
def main():
t1 = MyThread(process,'word.txt')
t1.start()
t1.join()
if __name__=='__main__':
main()
結果,雖然沒有卡頓,但這速度不敢恭維,半個小時才下了6000多個單詞。
4、總結
使用到的技術:
1、urllib2爬取網頁
2、檔案處理
3、系統輸出,進度重新整理
4、多執行緒