我想从http://www.youtube-mp3.org/上下载几首歌。我使用的是urllib2和BeautifulSoup。
问题是,当我用我的视频ID http://www.youtube-mp3.org/?c#v=lV7r8PiuecQ打开网站时,我会看到网站,但他们对此很棘手,并在初始页面加载后加载一些js ajax内容的信息。因此,当我尝试抓取下载链接的url时,它实际上不在页面上,因为它还没有加载。
有人知道如何在我的python脚本中触发这个js加载器吗?
下面是我想要的内容加载到其中之前的相关空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>发布于 2011-08-30 19:14:31
API是基于JSON的,所以html文件的内容不会给您任何关于在哪里找到文件的线索。在探索像这样的web服务时,一个好主意是在Chrome的开发人员工具中打开Network选项卡,看看它在与页面交互时加载了哪些页面。该练习向我展示了两个特别有趣的urls:
第一个url似乎正在排队等待处理的文件,第二个url则用于获取正在处理的作业的状态。
第二个url接受youtube GET参数,该参数是youtube (http://www.youtube.com/watch?v=KMU0tzLwhbE)上视频的id,并返回解码作业的状态。第二个和第三个似乎与此无关,您可以通过测试加载带有和不带有额外参数的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,引用它并使用以下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
使用在info url中找到的散列来构造下载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发布于 2011-08-30 16:43:37
您可以使用selenium与js进行交互,然后将其与BeautifulSoup结合使用,或者使用selenium执行所有操作,就像您喜欢的那样。
http://seleniumhq.org/
Selenium是一种浏览器自动化工具,它绑定了几种语言,包括Python。它需要一个正在运行的Firefox/IE/Chrome实例,让我们编写脚本(对于这个简单的问题,我建议使用selenium webdriver,而不是整个selenium服务器)。
发布于 2011-08-30 16:37:38
你将不得不通过http://www.youtube-mp3.org/client.js找出正在传递的确切信息,这个可以允许你发布请求,解析响应,并从正确的抓取url下载。
https://stackoverflow.com/questions/7240382
复制相似问题