【问题标题】:Python data scrapingPython数据抓取
【发布时间】:2011-11-06 14:39:16
【问题描述】:

我想从http://www.youtube-mp3.org/ 下载几首歌曲。我正在使用 urllib2 和 BeautifulSoup

问题是,当我 urllib2 打开插入了我的视频 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>

【问题讨论】:

  • 看起来我们需要 youtube-mp3-scraper.org :一个抓取 youtube-mp3 的页面,然后再抓取 youtube ;)
  • 嗯,因为我在 Mac 上,也许我可以使用 Automator 来浏览 youtube-mp3 上的 URL 列表,然后用实际的浏览器一一下载......?不过,我更愿意留在 Python 中。
  • Beautiful Soap 是处理键盘细菌最好的python库。

标签: python youtube urllib2 scrape


【解决方案1】:

API 是基于 JSON 的,因此 html 文件的内容不会为您提供有关在何处找到文件的任何线索。探索类似这样的网络服务时,一个好主意是在 Chrome 的开发人员工具中打开网络选项卡,查看与页面交互时它加载的页面。该练习向我展示了两个 url 看起来特别有趣:

  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 似乎在排队等待处理文件,第二个获取处理作业的状态。

第二个 url 采用 video_id 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 视频的 url (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 中的 hash 来构造下载 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

【讨论】:

  • 嘿,这不再起作用了。似乎需要 r 值才能开始转换。关于如何获得 r 值的任何想法?
【解决方案2】:

您可以使用 selenium 与 js 内容进行交互,然后将其与 BeautifulSoup 结合使用,或者使用 selenium 做任何事情,就像您喜欢的那样。

http://seleniumhq.org/

Selenium 是一种用于浏览器自动化的工具,并且绑定了包括 Python 在内的几种语言。它需要一个正在运行的 Firefox/IE/Chrome 实例,让我们编写脚本(我建议使用 selenium webdriver 来解决这个简单的问题,而不是整个 selenium 服务器)。

【讨论】:

    【解决方案3】:

    您将不得不通过http://www.youtube-mp3.org/client.js 并找出正在传递的确切信息,这可以允许您发布请求、解析响应并从正确的抓取网址。

    【讨论】:

      猜你喜欢
      • 2017-09-04
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-23
      • 2022-01-24
      相关资源
      最近更新 更多