2011-08-30 14 views
8

Voglio scaricare un paio di brani su http://www.youtube-mp3.org/. Sto usando urllib2 e BeautifulSoup.Scrittura dati in Python

Il problema è che quando urllib2 apro il sito con il mio ID video collegato, http://www.youtube-mp3.org/?c#v=lV7r8PiuecQ, ottengo il sito ma sono complicati e caricano le informazioni dopo il caricamento iniziale con alcune cose js ajax. Quindi quando provo a raschiare l'url del link per il download, letteralmente non è nella pagina perché non è stato caricato.

Qualcuno sa come posso attivare questo caricatore js nel mio script Python, o qualcosa del genere?

Ecco l'html vuoto pertinente PRIMA che il contenuto che desidero venga caricato in esso.

<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

Sembra che abbiamo bisogno http://youtube-mp3-scraper.org/: una pagina che raschia youtube-mp3, che a sua volta raschia youtube;) – phihag

+0

Hmm, dal momento che Posso usare Automator semplicemente per scorrere l'elenco degli URL su youtube-mp3 e scaricarli con il browser uno per uno? Preferisco di gran lunga rimanere in Python. – Oliver

+2

Beautiful Soap è la migliore libreria Python per la gestione dei batteri della tastiera. – Profane

risposta

10

L'API è basata su JSON, quindi il contenuto dei file html non ti darà alcun indizio su dove trovare i file. Una buona idea quando esplori servizi web come questo, è aprire la scheda Rete negli strumenti di sviluppo di Chrome e vedere quali pagine carica quando interagiscono con la pagina. Questo esercizio mi ha mostrato che due URL, in particolare, sembrano interessanti:

  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

il primo URL sembra essere in coda un file per l'elaborazione, la seconda per ottenere lo stato del trattamento lavoro.

Il secondo url prende un parametro video_id GET che è l'id per il video su youtube (http://www.youtube.com/watch?v=KMU0tzLwhbE) e restituisce lo stato del processo di decodifica. Il secondo e il terzo sembrano irrilevanti per questo scopo che puoi verificare testando il caricamento dell'URL con e senza i parametri aggiuntivi.

Il contenuto della pagina è:

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

che risulta essere dati JSON. Il bit interessante in questo è "a0aa17294103c638fa7f5e0606f839d3" che sembra un hash che il servizio Web usa per riferirsi al file mp3 decodificato. Verificate anche come il link per il download in prima pagina appare:

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

Ora abbiamo tutti i pezzi mancanti del puzzle. Per prima cosa prendiamo l'url di un video di youtube (http://www.youtube.com/watch?v = iKP7DZmqdbU) URL citazione e mangimi per l'API utilizzando questo URL:

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

Poi, attendere qualche istante fino a quando il lavoro è fatto di decodifica:

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

Prendere la hASH trovato nella informazioni URL per costruire l'URL per il download:

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

Nota che è possibile che il web master del sito non voglia essere raschiato e prenderà contromisure se la gente inizia a (negli occhi dei webmaster) abusare del sito. Ad esempio, sembra che utilizzi la protezione dei referer, quindi fare clic sui collegamenti in questo post non funzionerà, devi copiarli e caricarli in una nuova finestra del browser.

Codice di prova:

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 per dilligence – mjhm

+0

Ehi, questo non funziona più. Sembra che il valore r sia necessario per avviare una conversione. Qualche idea su come ottenere il valore r? – JonasG

2

Stai andando ad avere per lavorare attraverso http://www.youtube-mp3.org/client.js e capire le informazioni esatte che viene passato in giro, questo potrebbe permetterà di inviare una richiesta, di analizzare la risposta e scaricare dal URL corretto raschiato .

4

È possibile utilizzare il selenio per interagire con la roba di js e quindi combinarlo con BeautifulSoup o fare tutto con il selenio, proprio come preferisci.

http://seleniumhq.org/

Il selenio è uno strumento per il browser automatizzazione e ha binding per un paio di lingue, tra cui Python. Ci vuole un'istanza in esecuzione di Firefox/IE/Chrome e lascia che tu lo script (ti suggerisco di usare il selenio web per questo semplice problema, non l'intero server di selenio).