模拟浏览器下载文件?

16 投票
11 回答
12580 浏览
提问于 2025-04-17 15:42

在网上有一个FLV格式的视频文件,可以直接在Chrome浏览器中下载。这个文件是中央电视台(CCTV)的一档电视节目。CCTV是一个非营利的国有广播机构,由中国的纳税人资助,所以我们下载他们的内容是合法的,不会侵犯版权。

我可以使用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的代码正常工作呢?

11 个回答

5
  1. 你可以使用 seleniumwatir 来完成你在浏览器中需要做的所有事情。
  2. 因为你不想看到浏览器界面,你可以让 selenium 在无头模式下运行

另外,看看 这个回答

6

看起来,mechanize可以进行有状态的浏览,也就是说它能在浏览器请求之间保持上下文和 cookies。我的建议是,先加载包含视频的完整页面,然后再尝试明确地下载视频。这样,网站服务器会认为你正在进行一个完整的(合法的)浏览会话。

26

首先,如果你想进行抓取(即使你不是在解析HTML,这也算抓取),你需要先做一些准备工作。

如果你还没有FirefoxFirebug,赶紧去下载。然后如果你还没有Chrome,也去下载一个。

启动Firefox/Firebug和Chrome,清除所有的cookies等数据。然后打开Firebug,在Chrome中选择查看->开发者->开发者工具。

接下来,打开你想下载视频的主页面。注意页面加载时设置的任何cookies、头信息、POST变量和查询字符串变量。你可能想把这些信息保存下来。

然后尝试下载视频,再次注意视频加载时设置的任何cookies、头信息、POST变量和查询字符串变量。很可能在你最初加载页面时,有一个cookie或POST变量是必须的,才能真正获取到视频文件。

当你写Python代码时,需要尽量模拟这个交互过程。使用python-requests库。这是最简单的URL库,除非你遇到什么问题,否则我建议你一直使用它。我一开始用python-requests后,我的URL获取代码减少了五倍。

现在,第一次尝试可能不会成功。所以,你需要用Python加载主页面。打印出所有的cookies、头信息、POST变量和查询字符串变量,并和Chrome/Firebug中的进行比较。然后再尝试加载视频,再次比较这些值(也就是你发送给服务器的和服务器返回给你的)。你需要找出它们之间的不同之处(别担心,这个我们在幼儿园就学过……“这些东西中有一个不一样”),并分析这个不同是如何导致问题的。

如果经过这些步骤后你还是搞不定,可能需要查看包含视频链接的页面的HTML。查找页面中的任何JavaScript。然后使用Firebug/Chrome开发者工具检查JavaScript,看看它是否在管理你的用户会话。如果它生成了与视频访问相关的令牌(cookies或POST/GET变量),你需要在Python中模拟它的令牌生成方法。

希望这些信息能帮到你,不会让你觉得太复杂。关键是你需要像个科学家一样。弄清楚你知道什么、不知道什么、想要什么,然后开始实验并记录你的结果。最终会出现一个模式。

编辑:明确步骤

  1. 调查状态是如何保持的
  2. 用Python拉取初始页面,获取所需的状态信息
  3. 根据状态信息进行任何必要的令牌生成
  4. 使用步骤2和3中的令牌拉取视频
  5. 如果出现问题,输出你的请求/响应头、cookies、查询变量、POST变量,并与Chrome/Firebug进行比较
  6. 返回第一步,直到找到解决方案

编辑: 你可能在这些请求中(HTML页面或文件下载)被重定向了。如果发生这种情况,你很可能会在Firebug/Chrome中错过请求/响应。解决方案是使用像LiveHTTPHeaders这样的嗅探工具,或者像其他回答者建议的,使用WireSharkFiddler。请注意,如果你在Linux或OSX上,Fiddler对你没有帮助。它只支持Windows,并且主要针对.NET开发……(唉)。Wireshark非常有用,但对于大多数问题来说可能有点过于复杂,具体取决于你使用的机器,可能会遇到一些问题。所以我建议你先试试LiveHTTPHeaders。

我喜欢这种问题

撰写回答