2013-02-13 239 views
15

网络上有一个FLV文件,可以直接在Chrome中下载。该档案是由中央电视台(中央电视台)出版的电视节目。中央电视台是一家非营利性国有广播电台,由中国纳税人出资,允许我们在不侵犯版权的情况下下载他们的内容。模拟浏览器下载文件?

使用wget,我可以从其他地址下载文件,但不能从Chrome中的地址下载文件。

这是我一直试图做的事:

url='http://114.80.235.200/f4v/94/163005294.h264_1.f4v?10000&key=7b9b1155dc632cbab92027511adcb300401443020d&playtype=1&tk=163659644989925531390490125&brt=2&bc=0&nt=0&du=1496650&ispid=23&rc=200&inf=1&si=11000&npc=1606&pp=0&ul=2&mt=-1&sid=10000&au=0&pc=0&cip=222.73.44.31&hf=0&id=tudou&itemid=135558267&fi=163005294&sz=59138302' 

wget -c $url --user-agent="" -O xfgs.f4v 

这不起作用或者:

wget -c $url -O xfgs.f4v 

输出是:

Connecting to 118.26.57.12:80... connected. 
HTTP request sent, awaiting response... 403 Forbidden 
2013-02-13 09:50:42 ERROR 403: Forbidden. 

我在做什么错误?

我最终想用Python库mechanize下载它。这里是代码我使用的为:

import mechanize 
br = mechanize.Browser() 
br = mechanize.Browser() 
br.set_handle_robots(False) 
br.set_handle_equiv(False) 
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] 
url='http://114.80.235.200/f4v/94/163005294.h264_1.f4v?10000&key=7b9b1155dc632cbab92027511adcb300401443020d&playtype=1&tk=163659644989925531390490125&brt=2&bc=0&nt=0&du=1496650&ispid=23&rc=200&inf=1&si=11000&npc=1606&pp=0&ul=2&mt=-1&sid=10000&au=0&pc=0&cip=222.73.44.31&hf=0&id=tudou&itemid=135558267&fi=163005294&sz=59138302' 
r = br.open(url).read() 
tofile=open("/tmp/xfgs.f4v","w") 
tofile.write(r) 
tofile.close() 

这是结果:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.7/dist-packages/mechanize/_mechanize.py", line 203, in open 
    return self._mech_open(url, data, timeout=timeout) 
    File "/usr/lib/python2.7/dist-packages/mechanize/_mechanize.py", line 255, in _mech_open 
raise response 
mechanize._response.httperror_seek_wrapper: HTTP Error 403: Forbidden 

谁能解释如何获得mechanize代码工作吗?

+1

如果您使用:'user_agent ='Mozilla/5.0(X11; U; Linux i686; en-US; rv:1.9.0.1)Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1)''然后' wget -c“$ {url}”--user-agent =“$ {user_agent}”-O x fgs.f4v'?如果这不起作用,那么Python可能无法帮助你! – Johnsyweb 2013-02-13 02:45:14

+7

您得到403响应的原因很可能是因为当您在浏览器中访问网站时,网站会保持状态,最有可能是cookie。这就是YouTube所做的。从浏览器中导出您的cookie并将其设置在wget中(您可以简单地使用“Cookie:”标题),它应该可以工作。 – 2013-02-13 02:47:17

+0

@Johnsyweb在大多数情况下,Python可以完美地模拟浏览器(当然,除了通过JavaScript等设置cookie的奇怪网站之外)。 – 2013-02-13 02:49:13

回答

20

首先,如果您试图进行任何形式的抓取(即使您不一定解析HTML,这也算是刮蹭),但您还是需要进行一定程度的初步调查。

如果您还没有FirefoxFirebug,请获取它们。那么如果你还没有Chrome,那就去吧。

启动Firefox/Firebug和Chrome,清除所有的cookies/etc。然后打开Firebug,在Chrome中打开View-> Developer-> Developer Tools。

然后加载您试图抓取的视频的主页面。注意当页面加载时正在设置的cookies/header/POST变量/查询字符串变量。您可能希望将此信息保存在某处。

然后尝试下载视频,再次注意视频加载时正在设置的所有cookie/headers/post变量/查询字符串变量。当您最初加载页面时,很可能会设置cookie或POST变量,这是实际提取视频文件所必需的。

当你编写你的python时,你将需要尽可能地模拟这种交互。使用python-requests。这可能是最简单的URL库,除非你以某种方式遇到了墙(不能做),否则我绝不会使用其他任何东西。第二个我开始使用python-requests,我所有的URL获取代码都缩小了5倍。

现在,事情可能不会在你第一次尝试它们时起作用。 Soooo,你将需要使用python加载主页面。打印出所有的cookies/headers/POST变量/查询字符串变量,并将它们与Chrome/Firebug的内容进行比较。然后尝试加载视频,再次比较所有这些值(这意味着您发送服务器的内容以及服务器向您发送的内容)。你需要弄清楚他们之间有什么不同(不要担心,我们都在幼儿园学到了这个东西......“这些东西中的一个与其他东西不一样)”,并分析这种差异如何打破东西。

如果在所有这一切的结尾,仍然无法弄清楚,那么您可能需要查看包含电影链接的页面的HTML。在页面中查找任何javascript。然后使用Firebug/Chrome开发人员工具来检查JavaScript并查看它是否正在对用户会话进行某种管理。如果它以某种方式生成与视频访问相关的令牌(cookie或POST/GET变量),则需要在python中模拟其标记化方法。

希望这一切都有所帮助,而且看起来不太可怕。关键是你需要成为一名科学家。找出你知道的,你不知道的,你想要的,并开始试验和记录你的结果。最终会出现一种模式。

编辑:澄清步骤

  1. 研究如何状态维持
  2. 与蟒蛇拉初始页面,抢你需要从它
  3. 执行可能与需要的任何符号化的任何状态信息该状态信息
  4. 使用来自步骤2的令牌和3
  5. 拉出视频如果东西吹起来,输出您的请求/响应HEA分布式能源,饼干,查询乏,POST变量,并将它们
  6. 返回比较Chrome浏览器/ Firebug的步骤1,直到你找到一个解决方案

编辑: 你也可以得到在任何一个重定向这些请求(html页面或文件下载)。如果发生这种情况,您很可能会错过Firebug/Chrome中的请求/响应。解决方法是使用嗅探器,如LiveHTTPHeaders,或者其他响应者已建议的,WireSharkFiddler。请注意,如果您在Linux或OSX机器上,Fiddler将无能为力。它只是Windows,并且绝对专注于.NET开发......(呃)。 Wireshark对于大多数问题是非常有用的,但是过分的,并且根据你运行的是什么机器,你可能会遇到问题。所以我会先建议LiveHTTPHeaders。

我喜欢这样的问题

+5

老实说,我喜欢这样的答案,听起来像'不给我鱼,但学会我去钓鱼'的隐喻。这些都是很好的提示。 – 2013-02-22 20:55:04

+0

这是编程吧? :)谢谢,最好的学习方式是通过做(调试)。打破事情,并找出他们为什么打破。然后,您更好地了解整个系统,而不是仅仅解决一个问题域特定的解决方案 – 2013-02-24 18:51:12

+0

要自动化网络资料,我经常使用以下三个工具: - Chrome的开发人员工具,启用网络选项“保留日志”和控制台 - 当发现POST/GET请求时(您需要一些技巧),我使用'Copy as curl' - 然后编写自己的python来自动化案例,我还发现了这个工具:http:// curl .trillworks.com /#python为我生成代码。 您可能还需要使用python/urllib2的cookiejar来保存cookie 您还可以使用nodejs或phantomjs轻松地在代码中执行/ eval Javascript代码 – hzrari 2015-04-16 21:58:52

5

似乎机械化可以进行有状态浏览,这意味着它将保持浏览器请求之间的上下文和cookie。我建议首先加载视频所在的完整页面,然后再尝试明确下载视频。这样,Web服务器将认为这是一个完整的(合法的)浏览会话正在进行

0
from urllib import urlopen 
print urlopen(url) #python built-in high level interface to get ANY online resources, auto responds to HTTP error codes. 
+0

没有家伙这不是一个真正的解决方案恕我直言 – 0x90 2014-07-04 09:48:01

4

为了澄清你的问题,你可以路由你的浏览器,并通过调试代理代码的请求的“为什么”的一部分。如果你使用Windows,我建议fiddler2。其他平台还有其他调试代理。但小提琴手2绝对是我的最爱。

http://www.fiddler2.com/fiddler2/

https://www.owasp.org/index.php/Category:OWASP_WebScarab_Project

http://www.charlesproxy.com/

或者更低水平 http://netcat.sourceforge.net/

http://www.wireshark.org/

一旦你知道它通常是简单得多的分歧拿出一个解决方案。我怀疑关于有状态浏览/ cookie的其他答案是正确的。通过上述工具,您可以分析这些Cookie并推出合适的解决方案,而无需进行浏览器自动化。

+0

+1简单 – flup 2013-02-20 15:26:06

2

有一个开源的,Python库,命名为ghost,它包装无头,WebKit的浏览器,这样你就可以通过简单的API控制一切:

from ghost import Ghost 
ghost = Ghost() 

page, resources = ghost.open('http://my.web.page') 

它支持的cookies,JavaScript和一切。您可以将JavaScript注入到页面中,并且它是无头的,因此它不会以图形方式呈现任何内容,但您仍然拥有DOM。这是一个完整的浏览器。

它不能很好地扩展,但它很有趣,并且当你需要接近完整的浏览器时可能会有用。

+1

这可能是矫枉过正他的问题,因为它加载了一个完整的WebKit/JavascriptCore或V8实例。这使得它非纯Python和依赖可能成为一个问题,取决于他的代码运行的地方。但不管真棒建议!我从来没有见过这个。 – 2013-02-22 17:09:41

3

我认为很多网站使用只存在于您的会话中的临时链接。网址中的代码可能与您的会话ID类似。这意味着特定的链接将永远不会再工作。

你将不得不重新使用一些库,可容纳该会话(如在其他的答案中提到)包含链接的页面。然后尝试找到链接并仅在此会话中使用它。

5

假设您没有手动输入URL,请使用机械化首先进入您从中获取该页面的页面。然后模拟您下载实际文件的操作(可能点击链接或按钮)。

这可能不是工作,虽然是机械化保持饼干和重定向的状态,但不处理任何JavaScript实时更改HTML页面。要检查JavaScript是否对操作至关重要,请在Chrome(或任何其他浏览器)中切换JavaScript,并确保可以下载该文件。如果JavaScript是必要的,我会尝试以编程方式驱动浏览器来获取文件。

我通常的方法来尝试这种拼抢的是

  1. 尝试了wget或蟒蛇的urllib2
  2. 尝试机械化
  3. 驱动器中的浏览器

除非有一些验证码,最后一个通常工作,但其他人更容易(和更快)。

0

您是否尝试过请求模块?它比urllib2和pycurl等使用起来要简单得多。 但它功能强大。它具有以下特点:该链接是here

  • 国际域名和网址
  • 保持活动&连接池
  • 会话与Cookie持久
  • 浏览器风格的SSL验证
  • 基本/摘要式身份验证
  • 优雅的键/值饼干
  • 自动减压
  • Unicode的响应主体
  • 分段文件上传
  • 连接超时
  • 的.netrc支持
  • 的Python 2.6-3.3
  • 线程安全的。
  • 2

    下载任何流媒体虽然目前接受的答案(由G.希勒)可能是最好的一般来说,我发现了一种跳过几个步骤的方法 - 用a firefox extension called cliget将请求上下文与所有http头和cookie一起,并生成复制到剪贴板的curl(或wget)命令。

    编辑:这个功能也是萤火和Chrome调试器的网络面板可用 - 右键点击请求,“副本作为卷曲”

    大多数时候,你会得到一个非常详细的命令一些显然不需要的标题,但是你可以一个接一个地删除这些请求,直到服务器拒绝请求,而不是相反(老实说,我觉得很沮丧 - 我经常陷入思考请求中缺少什么标题)。

    (此外,您可能想要删除从curl命令行的-O选项来查看,而不是将其下载到文件的结果在标准输出,并添加-v看到完整的标题列表)

    即使你不想使用curl/wget,将一个curl/wget命令行转换为python代码只是知道如何向urllib请求(或任何http请求库)添加标头的问题