wget
我尝试使用和下载文件,curl
但它被拒绝并出现 403 错误(禁止)。
我可以使用同一台计算机上的网络浏览器查看该文件。
我再次尝试使用浏览器的用户代理,通过以下方式获得http://www.whatsmyuseragent.com。我这样做:
wget -U 'Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' http://...
和
curl -A 'Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' http://...
但它仍然是被禁止的。 403 可能还有哪些其他原因,我可以通过哪些方式更改wget
和curl
命令来克服这些原因?
(这与能否获取文件无关 - 我知道我可以从浏览器中保存它;这是关于理解为什么命令行工具的工作方式不同)
更新
感谢对这个问题的所有精彩回答。我遇到的具体问题是服务器正在检查引荐来源网址。通过将其添加到命令行,我可以使用curl
和获取文件wget
。
检查引荐来源网址的服务器通过 302 跳转到另一个根本不执行任何检查的位置,因此该站点的某个curl
或部分wget
工作正常。
如果有人感兴趣,这是因为我正在阅读这页面来了解嵌入式 CSS,并尝试查看该网站的 css 示例。我遇到问题的实际 URL 是这我curl
最终得到的是
curl -L -H 'Referer: http://css-tricks.com/forums/topic/font-face-in-base64-is-cross-browser-compatible/' http://cloud.typography.com/610186/691184/css/fonts.css
wget 是
wget --referer='http://css-tricks.com/forums/topic/font-face-in-base64-is-cross-browser-compatible/' http://cloud.typography.com/610186/691184/css/fonts.css
很有意思。
答案1
HTTP 请求可能包含更多未由curl 或wget 设置的标头。例如:
- Cookie:这是请求被拒绝的最有可能的原因,我在下载网站上看到过这种情况发生。给定一个 cookie
key=val
,您可以使用-b key=val
(或--cookie key=val
) 选项来设置它curl
。 - 引用者(原文如此):当单击网页上的链接时,大多数浏览器倾向于将当前页面作为引用者发送。不应依赖它,但当此标头不存在时,即使 eBay 也无法重置密码。所以是的,这可能会发生。
curl
对此的选项是-e URL
和--referer URL
。 - 授权:由于用户名/密码对话框的用户界面不可控,现在这种方式已经不太流行了,但它仍然是可能的。可以
curl
使用-u user:password
( 或--user user:password
) 选项进行设置。 - 用户代理:某些请求将根据用户代理产生不同的响应。这可以以好的方式使用(提供真正的下载而不是镜像列表),也可以以坏的方式使用(拒绝不以
Mozilla
, 或包含Wget
或开头的用户代理curl
)。
您通常可以使用浏览器的开发者工具(Firefox 和 Chrome 支持)来读取浏览器发送的标头。如果连接未加密(即不使用 HTTPS),那么您还可以使用数据包嗅探器(例如 Wireshark)来实现此目的。
除了这些标头之外,网站还可能触发一些改变状态的幕后操作。例如,打开页面时,有可能在后台发出请求准备下载链接。或者页面上发生重定向。这些操作通常使用 Javascript,但也可能有一个隐藏框架来促进这些操作。
如果您正在寻找一种轻松地从下载站点获取文件的方法,请查看 plowdown,其中包含耜。
答案2
尝试了以上所有方法,但没有运气;使用开发浏览器工具获取用户代理字符串,一旦我添加以下内容,成功:
--user-agent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
答案3
只是想在上述答案中添加一点,您可以使用 Chrome 开发人员工具(自 v26.0 起)和 Firebug(自 v26.0 起)中提供的“复制为 cURL”功能v1.12)。您可以通过右键单击“网络”选项卡中的请求行来访问此功能。
答案4
发生这种情况的另一个原因是该站点是否需要 SSL。您的浏览器会自动从 HTTP 转发到 HTTPS,但curl 和 wget 不会。因此尝试使用 HTTPS 而不是 HTTP 进行请求。