2011-08-30 137 views
8

我想從http://www.youtube-mp3.org/下載幾首歌。我使用的是urllib2和BeautifulSoupPython數據抓取

問題是,當我urllib2打開與我的視頻ID插入的網站,http://www.youtube-mp3.org/?c#v=lV7r8PiuecQ,我得到的網站,但他們很棘手,並加載後的初始頁面加載一些js ajax東西的信息。所以當我試圖抓取下載鏈接的URL時,從字面上看不在頁面上,因爲它沒有被加載。

任何人都知道我可能會觸發這個js加載器在我的Python腳本,或者什麼?

以下是我想要加載的內容之前的相關空html。

<div id="link_box" style="display:none"> 
    <div id="link_box_title" style="font-weight:bold; text-decoration:underline"> 
    </div> 
    <div class="row"> 
    <div id="link_box_bb_code_title" style="font-weight:bold"> 
    </div> 
    <input type="text" id="BBCodeLink" onclick="sAll(this)" /> 
    </div> 
    <div class="row"> 
    <div id="link_box_html_code_title" style="font-weight:bold"> 
    </div> 
    <input type="text" id="HTMLLink" onclick="sAll(this)" /> 
    </div> 
    <div class="row"> 
    <div id="link_box_direct_code_title" style="font-weight:bold"> 
    </div> 
    <input type="text" id="DirectLink" onclick="sAll(this)" /> 
    </div> 
    </div> 
    <div id="v-ads"> 
    </div> 
    <div id="dl_link"> 
    </div> 
    <div id="progress"> 
    </div> 
    <div id="loader"> 
    <img src="ajax-loader-b.gif" alt="loading.." width="16" height="11" /> 
    </div> 
</div> 
<div class="clear"> 
</div> 
</div> 
+6

看起來我們需要http://youtube-mp3-scraper.org/:一個頁面,YouTube的擦傷,MP3,這反過來又刮的YouTube;) – phihag

+0

嗯,因爲我在Mac上,也許我可以使用Automator來瀏覽youtube-mp3上的URL列表,並讓它們逐一下載到實際的瀏覽器中。我寧願留在Python中。 – Oliver

+2

美麗的肥皂是處理鍵盤細菌的最佳蟒蛇庫。 – Profane

回答

10

API是基於JSON的,所以html文件的內容不會給你任何線索在哪裏找到文件。在探索像這樣的網絡服務時,一個好主意是在Chrome的開發者工具中打開網絡標籤,並查看它在與網頁進行交互時加載的網頁。這項工作給我看,尤其是兩個網址似乎有趣:

  1. http://www.youtube-mp3.org/api/pushItem/?item=http%3A//www.youtube.com/watch%3Fv%3DKMU0tzLwhbE&xy=trve&r=1314700829128
  2. http://www.youtube-mp3.org/api/itemInfo/?video_id=KMU0tzLwhbE&adloc=&r=1314700829314

第一url似乎排隊處理的文件,第二個得到處理的狀態工作。

第二個網址需要一個video_id GET參數,它是youtube上視頻的ID(http://www.youtube.com/watch?v=KMU0tzLwhbE)並返回解碼作業的狀態。第二個和第三個似乎與此無關,您可以通過測試來驗證是否加載帶有和不帶額外參數的url。

頁的內容是:

info = { "title" : "Developers", 
     "image" : "http://i4.ytimg.com/vi/KMU0tzLwhbE/default.jpg", 
     "length" : "3", "status" : "serving", "progress_speed" : "", 
     "progress" : "", "ads" : "", 
     "h" : "a0aa17294103c638fa7f5e0606f839d3" }; 

這恰好是JSON數據。這裏有趣的是「a0aa17294103c638fa7f5e0606f839d3」,它看起來像是Web服務用來引用解碼的mp3文件的散列。還檢查了頭版上的下載鏈接的外觀:

http://www.youtube-mp3.org/get?video_id=KMU0tzLwhbE&h=a0aa17294103c638fa7f5e0606f839d3

現在我們有所有謎題的缺失拼在一起。首先,我們將youtube視頻的網址(http://www.youtube.com/watch?V = iKP7DZmqdbU)URL引用它,並使用這個網址飼料它的API:

http://www.youtube-mp3.org/api/pushItem/?item=http%3A//www.youtube.com/watch%3Fv%3DiKP7DZmqdbU&xy=trve

然後,等待片刻直到解碼工作已經完成:

http://www.youtube-mp3.org/api/itemInfo/?video_id=iKP7DZmqdbU

拿在信息URL哈希發現構建下載網址:

http://www.youtube-mp3.org/get?video_id=iKP7DZmqdbU&h=2e4b61b6ddc8bf83f5a0e4e4ee0635bb

請注意,如果人們開始(在網站管理員的眼中)濫用網站,網站的網站管理員可能不想被刮掉,並採取反措施。例如,它似乎使用了引用者保護,因此單擊本文中的鏈接將不起作用,您必須複製它們並將它們加載到新的瀏覽器窗口中。

測試代碼:

from re import findall 
from time import sleep 
from urllib import urlopen, quote 

yt_code = 'gijypDkEqUA' 

yt_url = 'http://www.youtube.com/watch?v=%s' % yt_code 
push_url_fmt = 'http://www.youtube-mp3.org/api/pushItem/?item=%s&xy=trve' 
info_url_fmt = 'http://www.youtube-mp3.org/api/itemInfo/?video_id=%s' 
download_url_fmt = 'http://www.youtube-mp3.org/get?video_id=%s&h=%s' 
push_url = push_url_fmt % quote(yt_url) 
data = urlopen(push_url).read() 
sleep(10) 
info_url = info_url_fmt % yt_code 
data = urlopen(info_url).read() 
res = findall('"h" : "([^"]*)"', data) 
download_url = download_url_fmt % (yt_code, res[0]) 
print 'Download here:', download_url 
+0

+1爲dilligence – mjhm

+0

嘿,這不工作了。似乎需要r值才能開始轉換。有關如何獲得r值的任何想法? – JonasG

4

您可以使用硒與js的東西進行交互,然後將它與BeautifulSoup結合起來,或者與硒一起做任何事情,就像你喜歡的一樣。

http://seleniumhq.org/

硒是瀏覽器的自動化的工具,有一些語言,包括Python綁定。它需要一個運行的Firefox/IE/Chrome實例,讓我們編寫腳本(我建議使用selenium webdriver來解決這個簡單的問題,而不是整個硒服務器)。