python 通过post 上传文件

nicozhang 发布于 2012/11/29 11:21
阅读 17K+
收藏 4

小弟刚接触python ,感觉这门语言是如此的神奇。最近,想帮同事写一个能通过post 上传文件的脚本。到网上一搜,有几个模块可以用,用的最多的是MultipartPostHandler和poster。网上的资料也有例子,不过很坑爹啊,都是把官方的例子给复制出来到处粘贴,有木有啊。按照例子实验,怎么都不能成功,不知道为何。下面,我贴出代码,希望高手们能帮忙。代码是临时写的测试用的:

index.php

<html>
<body>

<form name="file" action="upload.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" /> 
<br />
<input type="submit" name="submit" value="Submit" />
</form>

</body>
</html>


upload.php:
<?php
if(isset($_POST["submit"])){
	if ($_FILES["file"]["error"] > 0)
	  {
	  echo "Error: " . $_FILES["file"]["error"] . "<br />";
	  }
	else
	  {
	  echo "Upload: " . $_FILES["file"]["name"] . "<br />";
	  echo "Type: " . $_FILES["file"]["type"] . "<br />";
	  echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
	  echo "Stored in: " . $_FILES["file"]["tmp_name"]."<br/>";
	  move_uploaded_file($_FILES["file"]["tmp_name"],$_FILES["file"]["name"]);
	  echo "Stored in: ".$_FILES["file"]["name"];
	  }
	 }
?>
下面分别是两种方法实现的上传文件:
#filename:uploadFile3.py
#module:MultipartPostHandler

import MultipartPostHandler, urllib2, cookielib,time
cookies = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                              MultipartPostHandler.MultipartPostHandler)
params = {"filename":open("E:\\py\\uploadFile\\1.xls","rb")}

opener.open("http://localhost/upload/",params)

time.sleep(10)

print "handle the request"


# -*- coding: gbk -*-
#module of poster
#filename:uploadFile2.py
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
import urllib2,sys

register_openers()

datagen,headers = multipart_encode({'file':open("E:\\py\\uploadFile\\1.xls","rb")})
request = urllib2.Request("http://localhost/upload/",datagen,headers)

#print urllib2.urlopen(request).read()

悲剧的是,这两种方法都没能实现上传哦。请各位大神给予指点。非常感谢。

以下是问题补充:

@nicozhang:平台是 wamp 目前还不清楚,这两个模块是通过什么机制实现上传的。 (2012/11/29 12:18)
加载中
0
nicozhang
nicozhang
没人给指点一下么
0
nicozhang
nicozhang
神奇般的搞定了,看了一个ChinaUnix 的例子,虽然和我用的平台不一样,但是我终于顿悟问题出在什么地方了…………终于成功了。
0
nicozhang
nicozhang
下面写出问题的解决思路:

起初,我一直以为是客户端的代码问题造成的,所以目标一直都放在客户端代码上。但是我错了。从网上找的两个模块,按照他们的例子,修改了上传路径(本机测试)和文件名。但是一直都没能成功。我一开始的想法是:模块打开远程的网页文件,根据name标签找到上传文件的地方,然后填写地址,最后自动点击提交。现在看看这个思路是错的。而且研究了两天没什么进展。

就刚才,在ChinaUnix 上看到一个例子,它是用Django 作为服务端。服务器端的代码是直接处理上传文件的,并没有对post做任何的响应。这就是问题的根源。结论:(poster 模块实验成功了)

1,poster 会构造一个完整post请求,multipart_encode(),就相当于加密表单数据。html中的post传参 是name:value的方式,multipart_encode()也是按照这个格式进行加密的。所以,根本不需要提交到index.php,而是直接提交到表单处理的upload.php就可以了。因为multipart_encode()已经构建了一个完整的post请求。

2,post提交部分没问题了,看upload.php。有一句验证的代码 if(isset($_POST["submit"])) 验证我的post是否提交。其实,就是这句代码,害死我了。在用multipart_encode()构造的post 的请求中,并没有submit 这个标签,所以,无论如何upload.php都无法处理提交的文件。去掉这个标签,一切都ok了。

现在总算明白是怎么回事了。

0
Scholer
Scholer
看到没分号就恐惧
menglinxi_a
menglinxi_a
回复 @nicozhang : 楼主,你的客户端提交是用 python的第二种方式提交的么?
nicozhang
nicozhang
回复 @Scholer : python 看的不是分号,是缩进。这种编程风格挺好的,让人养成一种善于缩进的编程习惯,读代码的时候也比较容易。最新Golang 也是采用的这种编码风格。
Scholer
Scholer
回复 @nicozhang : 不是不是 我是说python~~ 我不懂 哈哈
nicozhang
nicozhang
编辑窗口小了点……没注意
0
-亮子-
-亮子-
试的第二种方法,能成功
0
MacOS
MacOS
有时间试试
0
fromdtor
fromdtor
https://my.oschina.net/rst/blog/480554 看这里
nicozhang
nicozhang
谢谢了,多年前的了
返回顶部
顶部