Python:将大型网页保存到文件
让我首先说,我对编程并不陌生,但对python非常陌生 我已经使用urllib2编写了一个程序,它请求一个我希望保存到文件中的网页。这个网页大约有300KB,我并不觉得它特别大,但似乎足以给我带来麻烦,所以我称之为“大”。 我使用一个简单的调用直接从Python:将大型网页保存到文件,python,file,urllib2,Python,File,Urllib2,让我首先说,我对编程并不陌生,但对python非常陌生 我已经使用urllib2编写了一个程序,它请求一个我希望保存到文件中的网页。这个网页大约有300KB,我并不觉得它特别大,但似乎足以给我带来麻烦,所以我称之为“大”。 我使用一个简单的调用直接从urlopen返回的对象复制到文件中: file.write(webpage.read()) 但它只会停留几分钟,试图写入文件,我最终收到以下信息: Traceback (most recent call last): File "program
urlopen
返回的对象复制到文件中:
file.write(webpage.read())
但它只会停留几分钟,试图写入文件,我最终收到以下信息:
Traceback (most recent call last):
File "program.py", line 51, in <module>
main()
File "program.py", line 43, in main
f.write(webpage.read())
File "/usr/lib/python2.7/socket.py", line 351, in read
data = self._sock.recv(rbufsize)
File "/usr/lib/python2.7/httplib.py", line 541, in read
return self._read_chunked(amt)
File "/usr/lib/python2.7/httplib.py", line 592, in _read_chunked
value.append(self._safe_read(amt))
File "/usr/lib/python2.7/httplib.py", line 649, in _safe_read
raise IncompleteRead(''.join(s), amt)
httplib.IncompleteRead: IncompleteRead(6384 bytes read, 1808 more expected)
我会使用由shutil
模块提供的一个方便工具。它在我的机器上工作:)
更新:您可能希望将第三个参数传递给控制用于传输字节的内部缓冲区大小的copyfileobj
UPDATE2:shutil.copyfileobj没有什么特别之处。它只是从源文件对象读取一块字节,然后将其反复写入目标文件对象,直到没有更多的内容可读取为止。以下是我从Python标准库中获取的实际源代码:
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)
你能展示一下你是如何打开这一页的吗?可能是相关的。有几件事需要隔离……如果你只是读入一个数组,我想你在没有写任何文件的情况下也会遇到同样的问题。另外,如果您为read调用指定一个最大大小,比如read(500000),会怎么样?也许这会对您有所帮助:我使用了下面建议的shutil.copyfileobj,它现在似乎可以工作了。你知道为什么会这样吗?谢谢你,我曾经这样做过,现在看起来很有效。你知道copyfileobj的不同之处是什么吗?嗨@JustinSmith,再次看到我的答案,我已经更新了更多信息
copyfileobj
没有做任何特别深刻的事情。一次只将一个字节复制到目标文件中。这仍然不能解释原始代码的错误。实际问题是,由于文件太大,请求超时。我增加了超时时间,之后一切都正常了,我使用了这种方法。(例如,图像文件。)
>>> import urllib2
>>> import shutil
>>> remote_fo = urllib2.urlopen('http://docs.python.org/library/shutil.html')
>>> with open('bigfile', 'wb') as local_fo:
... shutil.copyfileobj(remote_fo, local_fo)
...
>>>
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)