使用Python下载未在URL中明确引用的文档

1 投票
7 回答
2131 浏览
提问于 2025-04-16 05:52

我用Python 2.6写了一个网络爬虫,利用Bing的API来搜索特定的文档,然后下载这些文档以便后续分类。我一直在用字符串处理方法和urllib.urlretrieve()来下载那些以.pdf、.ps等结尾的链接,但当文档被隐藏在像这样的链接后面时,我就遇到麻烦了:

http://www.oecd.org/officialdocuments/displaydocument/?cote=STD/CSTAT/WPNA(2008)25&docLanguage=En

所以,我有两个问题。一般来说,有没有办法判断一个链接是否指向一个pdf/doc等文件,如果它没有明确说明(比如:www.domain.com/file.pdf)?有没有办法让Python抓取到那个文件?

编辑:感谢大家的回复,其中有几条建议下载文件看看它是否是正确的类型。唯一的问题是……我不知道怎么做(见上面的问题#2)。urlretrieve(<上面的链接>)只返回一个包含那个链接的html文件。

7 个回答

2

正如之前所说,从网址是无法判断内容类型的。不过,如果你不介意为每个网址获取一下头信息,可以这样做:

obj = urllib.urlopen(URL)

headers = obj.info()
if headers['Content-Type'].find('pdf') != -1:
   # we have pdf file, download whole
...

这样你就不需要下载每个网址的内容,只需获取它的头信息。虽然这并不能完全节省网络流量,但也算是个不错的办法。

另外,你应该使用 MIME 类型,而不是我那种简单的查找方式(比如找 'pdf')。

8

从网址上根本无法判断它会给你什么内容。即使网址最后是.pdf,它也可能给你返回HTML页面或者其他任何东西。

你可以发送一个HEAD请求,查看内容类型。如果服务器没有欺骗你,这个内容类型会告诉你它是不是PDF文件。

另外,你也可以直接下载这个文件,然后再判断一下你得到的东西是不是PDF。

5

在这种情况下,你提到的“一个没有在网址中明确引用的文档”,其实就是我们所说的“重定向”。简单来说,服务器告诉你要去另一个网址获取这个文档。通常情况下,Python的urllib会自动跟随这些重定向,这样你就能拿到正确的文件。(而且,正如其他人提到的,你可以查看响应的mime-type头,看看它是不是pdf格式。)

不过,这里提到的服务器有点奇怪。你请求一个网址,它把你重定向到另一个网址。你再请求那个网址,它又把你重定向回去……又是同一个网址!而且这样一直循环下去……最终,urllib会觉得这样不行,停止跟随重定向,以免陷入无尽的循环。

那么,为什么你在浏览器中能拿到pdf呢?因为显然,服务器只有在你启用cookies的情况下才会提供pdf。(为什么会这样?你得问问负责这个服务器的人……)如果你没有cookie,它就会一直把你重定向下去,永远拿不到文件。

(可以查看urllib2cookielib模块来获取cookie的支持,这个教程可能会对你有帮助)

至少,我认为这就是问题的原因。我还没尝试过带着cookie去做。也有可能是服务器不“想”提供pdf,因为它检测到你不是在使用“正常”的浏览器(在这种情况下,你可能需要调整User-Agent头),但这样做也太奇怪了。所以我猜它可能在某个地方使用了“会话cookie”,如果你还没有这个cookie,就一直在尝试重定向。

撰写回答