16

网络上有一个 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代码工作?

4

11 回答 11

25

首先,如果您尝试进行任何类型的抓取(是的,即使您不一定解析 HTML,这也算作抓取),您需要执行一定数量的初步调查。

如果您还没有FirefoxFirebug,请获取它们。然后,如果您还没有Chrome,请获取它。

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

然后加载您要抓取的视频的主页。注意页面加载时设置的任何 cookie/headers/POST 变量/查询字符串变量。您可能希望将此信息保存在某处。

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

当您编写 Python 时,您将需要尽可能地模拟这种交互。使用python-requests。这可能是可用的最简单的 URL 库,除非你以某种方式碰壁(这是它做不到的),否则我永远不会使用其他任何东西。在我开始使用python-requests的那一刻,我所有的 URL 获取代码都缩小了 5 倍。

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

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

希望所有这些都会有所帮助,并且看起来不会太吓人。关键是你需要成为一名科学家。弄清楚你知道什么,你不知道什么,你想要什么,然后开始试验和记录你的结果。最终会出现一个模式。

编辑:澄清步骤

  1. 调查如何维护状态
  2. 使用 python 拉初始页面,从中获取您需要的任何状态信息
  3. 执行该状态信息可能需要的任何标记化
  4. 使用步骤 2 和 3 中的令牌拉取视频
  5. 如果出现问题,输出您的请求/响应标头、cookie、查询变量、发布变量,并将它们与 Chrome/Firebug 进行比较
  6. 返回步骤 1。直到找到解决方案

编辑: 您也可能会在这些请求之一(html页面或文件下载)处获得重定向。如果发生这种情况,您很可能会错过 Firebug/Chrome 中的请求/响应。解决方案是使用像LiveHTTPHeaders这样的嗅探器,或者像其他响应者WireSharkFiddler所建议的那样。请注意,如果您使用的是 Linux 或 OSX 机器,Fiddler 对您没有好处。它仅适用于 Windows,并且绝对专注于 .NET 开发......(呃)。Wireshark 非常有用,但对于大多数问题来说都是多余的,并且根据您运行的机器,您可能无法使其正常工作。所以我会首先建议 LiveHTTPHeaders。

我喜欢这种问题

于 2013-02-22T15:25:22.950 回答
6

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

于 2013-02-13T03:02:11.847 回答
5

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

这可能不起作用,因为 Mechanize 保持 cookie 和重定向的状态,但不处理对 html 页面的任何 JavaScript 实时更改。要检查 JavaScript 是否对操作至关重要,请在 Chrome(或任何其他浏览器)中切换 JavaScript,并确保您可以下载文件。如果需要 JavaScript,我会尝试以编程方式驱动浏览器来获取文件。

我通常尝试这种刮擦的方法是

  1. 尝试 wget 或 pythons urllib2
  2. 尝试机械化
  3. 驱动浏览器

除非有一些验证码,否则最后一个通常有效,但其他验证码更容易(更快)。

于 2013-02-22T07:05:25.443 回答
5
  1. 您可以在浏览器中使用seleniumwatir执行您需要的所有操作。
  2. 由于您不想看到浏览器,因此可以运行 selenium headless

另请参阅此答案

于 2013-02-16T04:19:25.130 回答
4

为了澄清问题的“为什么”部分,您可以通过调试代理路由浏览器和代码请求。如果您使用的是 Windows,我建议您使用 fiddler2。其他平台也存在其他调试代理。但 fiddler2 绝对是我的最爱。

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 并推出合适的解决方案,而无需浏览器自动化。

于 2013-02-19T06:29:35.017 回答
3

我认为许多站点使用仅存在于您的会话中的临时链接。url 中的代码可能类似于您的会话 ID。这意味着特定链接将永远无法再次工作。

您必须使用一些容纳此会话的库(如其他答案中提到的)重新打开包含链接的页面。然后尝试找到该链接并仅在此会话中使用它。

于 2013-02-21T11:38:55.307 回答
2

有一个名为ghost的开源 Python 库,它封装了一个无头 WebKit 浏览器,因此您可以通过一个简单的 API 控制一切:

from ghost import Ghost
ghost = Ghost()

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

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

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

于 2013-02-20T10:39:21.810 回答
2

虽然当前接受的答案(由 G. Shearer 提供)是一般抓取的最佳建议,但我找到了一种跳过几个步骤的方法 - 使用名为 cliget 的 firefox 扩展,它将请求上下文与所有 http 标头和cookie 并生成复制到剪贴板的curl(或)命令。wget

编辑:firebug 的网络面板和 chrome 调试器也提供此功能 - 右键单击​​请求,“复制为 curl”

大多数情况下,您会收到一个非常冗长的命令,其中包含一些显然不需要的标头,但是您可以一个一个地删除这些命令,直到服务器拒绝请求,而不是相反(老实说,我觉得令人沮丧 - 我经常得到一直在思考请求中缺少什么标头)。

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

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

于 2013-06-30T12:03:07.423 回答
0

您是否尝试过请求模块?它比 urllib2 和 pycurl 等使用起来简单得多,但它很强大。它具有以下特点:链接在这里

  • 国际域名和 URL
  • 保持活动和连接池
  • 具有 Cookie 持久性的会话
  • 浏览器式 SSL 验证
  • 基本/摘要认证
  • 优雅的键/值 Cookie
  • 自动减压
  • Unicode 响应体
  • 多部分文件上传
  • 连接超时
  • .netrc 支持
  • Python 2.6—3.3
  • 线程安全。
  • 于 2013-02-22T10:34:53.917 回答
    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.
    
    于 2013-02-17T18:23:03.490 回答
    0

    您可以使用Internet 下载管理器 ,它能够从任何网站捕获和下载任何流媒体

    于 2013-02-22T20:54:31.523 回答