0

我正在尝试通过点击 URL 来下载 PDF。假设我的 URL 如下所示:http: //foo.bar/this/downloads/pdf

如果我直接点击 URL,浏览器会下载 PDF,没有问题。但是,如果我尝试使用urllib2.urlopen我获取 PDF,我会得到一个不完整的文件。

url = "http://foo.bar/this/downloads/pdf"
sock = urllib2.urlopen(url)
content = sock.read()
with open('/tmp/test.pdf', 'w') as f:
    f.write(content)

/tmp/test.pdf 的最后 3 行看起来像这样(在变量中看起来像这样content):

0000778731 00000 n 
0000778751 00000 n 
000

但我从浏览器下载的实际文件如下所示:

0000778731 00000 n 
0000778751 00000 n 
0000778772 00000 n 
...
%%EOF

每一个 PDF,无论大小,似乎都在这个最终的数字组合中的某个地方被切断了。

我尝试了以下解决方案,但都不起作用。urllib2我认为原因与读取数据的方式无关,而是根本没有得到完整的响应这一事实。

python,没有得到完整的响应

urllib2 未检索整个 HTTP 响应

可能是一个因素的另一件事(尽管我不确定)是 PDF 发送到浏览器的方式。据我所知,PDF 是使用 PHP x-sendfile 发送的。我只是对为什么部分下载 PDF 感到困惑。

4

1 回答 1

2

您必须打开文件以二进制模式写入(注意wb):

with open('/tmp/test.pdf', 'wb') as f:
    f.write(content)

编辑:哦,您还必须继续阅读,直到.read()什么也没返回:

url = "http://foo.bar/this/downloads/pdf"
sock = urllib2.urlopen(url)
with open('/tmp/test.pdf', 'wb') as f:
    while True:
        content = sock.read()
        if not content: break
        f.write(content)

urllib文档中:

一个警告:read() 方法,如果 size 参数被省略或为负,可能直到数据流结束才读取;在一般情况下,没有很好的方法来确定来自套接字的整个流是否已被读取。

这个警告没有出现在 的文档中urllib2,但同样的概念也适用。

于 2012-09-24T20:32:59.917 回答