2011-08-30 140 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来解决这个简单的问题,而不是整个硒服务器)。