我在Python 2.6中使用Bing API编写了一个Web爬虫,它搜索某些文档,然后下载它们以便稍后进行分类。我一直在使用字符串方法和urllib.urlretrieve()
来下载其URL以.pdf,.ps等结尾的结果,但是当文档“隐藏”在以下URL之后我遇到了麻烦:
http://www.oecd.org/officialdocuments/displaydocument/?cote=STD/CSTAT/WPNA(2008)25&docLanguage=En
所以,两个问题。有没有一种方法可以判断一个URL是否有一个pdf / doc等文件,如果它没有这么明确地链接到它(例如www.domain.com/file.pdf)?有没有办法让Python抓住那个文件?
编辑:
感谢您的回复,其中一些建议下载文件,看看它是否是正确的类型。唯一的问题是......我不知道该怎么做(见上面的问题#2)。 urlretrieve(<above url>)
仅提供包含相同网址的href的html文件。
答案 0 :(得分:8)
没有办法从网址上告诉你它会给你什么。即使它以.pdf
结尾,它仍然可以为您提供HTML或任何它喜欢的内容。
您可以执行HEAD请求并查看内容类型,如果服务器没有对您说谎,则会告诉您它是否为PDF。
或者,您可以下载它,然后确定您获得的是PDF格式。
答案 1 :(得分:3)
在这种情况下,您所谓的“未在URL中明确引用的文档”似乎就是所谓的“重定向”。基本上,服务器会告诉您必须在另一个URL上获取文档。通常,python的urllib会自动遵循这些重定向,因此您最终会得到正确的文件。 (和 - 正如其他人已经提到的那样 - 你可以查看响应的mime-type标题,看它是不是pdf)。
但是,有问题的服务器在这里做了一些奇怪的事情。您请求该网址,并将其重定向到另一个网址。你请求另一个网址,它会再次重定向你...到同一个网址!再次......再次......在某些时候,urllib已经确定这已经足够了,并且会停止重定向,以避免陷入无限循环。
那你怎么能在使用浏览器时获得pdf?因为很明显,如果你启用了cookie,服务器将只提供pdf服务。 (为什么?你必须要求负责服务器的人......)如果你没有cookie,它会永远重定向你。
(查看urllib2和cookielib模块以获取对Cookie的支持,this tutorial可能有所帮助)
至少,这是我认为导致问题的原因。我还没有尝试过使用cookies。它也可能是服务器“不想”提供pdf,因为它检测到你没有使用“普通”浏览器(在这种情况下你可能需要摆弄User-Agent标头),但它这样做会很奇怪。所以我的猜测是它在某个地方使用“会话cookie”,如果你还没有,那就继续尝试重定向。
答案 2 :(得分:2)
如前所述,无法从URL中分辨内容类型。但是如果你不介意为每个URL获取标题,你可以这样做:
obj = urllib.urlopen(URL)
headers = obj.info()
if headers['Content-Type'].find('pdf') != -1:
# we have pdf file, download whole
...
这样您就不必下载每个URL的标题了。它仍然没有完全保存网络流量,但你不会比这更好。
此外,您应该使用mime-types而不是我的粗略查找('pdf')。
答案 3 :(得分:0)
没有。仅仅通过查看它就无法确定URL引用了哪种资源。当您请求某个URL时,完全取决于服务器决定他给您的内容。
答案 4 :(得分:0)
使用urllib.info()
功能检查mimetype。这可能不是100%准确,它实际上取决于站点作为Content-Type标头返回的内容。如果表现良好,它将返回正确的mime类型。
PDF应该返回application / pdf,但情况可能并非如此。
否则你可能只需要下载并尝试一下。
答案 5 :(得分:0)
您无法直接从网址中看到它。您可以尝试仅下载HTTP响应的标头并查找Content-Type标头。但是,您必须信任服务器 - 它可以使用与正文中提供的数据不匹配的错误Content-Type标头进行响应。
答案 6 :(得分:0)
使用url检测Python 3.x和webapp中的文件类型,该文件没有扩展名或伪扩展名。你应该使用
安装python-magicpip3 install python-magic
对于Mac OS X,您还应该使用
安装libmagicbrew install libmagic
代码段
import urllib
import magic
from urllib.request import urlopen
url = "http://...url to the file ..."
request = urllib.request.Request(url)
response = urlopen(request)
mime_type = magic.from_buffer(response.read())
print(mime_type)