【发布时间】:2016-07-30 04:59:43
【问题描述】:
我有这个代表用户将 mp3 文件上传到网站的 php 脚本。它工作得很好,但我想用python写它:
$id = $argv[1];
$file = $argv[2];
$course = $argv[3];
$audio_column_number = $argv[4];
if( !file_exists( $file ) ) {
die();
}
$curlFile = new CURLFile( $argv[2] );
$curlFile->setPostFilename( basename( $argv[2] ) );
$curlFile->setMimeType( "audio/mpeg" );
$post = array(
'thing_id' => $id,
'cell_id' => $audio_column_number,
'cell_type' => 'column',
'csrfmiddlewaretoken' => '2N829n66bh5Alhbc463wYtoqpyosyON',
'f' => $curlFile,
);
$curl = curl_init( "http://www.memrise.com/ajax/thing/cell/upload_file/" );
curl_setopt_array( $curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_REFERER => $course,
CURLOPT_USERAGENT => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0",
CURLOPT_COOKIE => "Cookie:__uvt=; __utmt=6; csrftoken=2N829n66bh5Alhbc463wYtoqpyosyON; sessionid=zj8suxtx841zlwrn10o6x3suzdjw9wpt; __utma=216705802.691983187.1416840006.1429942996.1430039373.8; __utmb=216705802.4.10.1440411307; __utmc=216705802; __utmz=216705802.1416840006.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); uvts=2Mnc8QsWzuuv8GVh",
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
CURLOPT_TIMEOUT => 60,
) );
$res = curl_exec( $curl );
我正在尝试将其转换为 python。这似乎很简单,我虽然。这是我尝试过的:
import requests
import sys
files = {'f': ('f.mp3', open(sys.argv[2], 'rb'), 'audio/mp3')}
form_data = {
"thing_id": sys.argv[1],
"cell_id": sys.argv[4],
"cell_type": "column",
"csrfmiddlewaretoken": "2N829n66bh5Alhbc463wYtoqpyosyON"}
cookies = {
"__uvt":"",
"__utmt":"6",
"csrftoken":"2N829n66bh5Alhbc463wYtoqpyosyON",
"sessionid":"zj8suxtx841zlwrn10o6x3suzdjw9wpt",
"__utma":"216705802.691983187.1416840006.1429942996.1430039373.8",
"__utmb":"216705802.4.10.1440411307",
"__utmc":"216705802",
"__utmz":"216705802.1416840006.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)",
"uvts":"2Mnc8QsWzuuv8GVh"}
headers = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0",
"referer": sys.argv[3]}
url = "http://www.memrise.com/ajax/thing/cell/upload_file/"
r = requests.post(url, files=files, cookies=cookies, headers=headers, timeout=60)
print(r.text)
与我的预期相反,虽然 php 脚本运行良好,但等效的 python 代码却没有。服务器拒绝它并发送 403。我没有太多的 PHP 经验,但我在尝试理解 PHP 脚本方面付出了坚实的努力。我想知道是否有人可以找到 Python 脚本无法找到的 PHP 脚本正在做什么。如果有帮助,我使用的是 Chrome 的开发人员工具,以查看当我在网站上上传文件时发布请求在网站中执行的操作的示例:
标题:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8,fr;q=0.6,en-CA;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:4271
Content-Type:multipart/form-data; boundary=---- WebKitFormBoundarytv2Kbmk1kUAGBVZ1
Cookie:i18next=en; sessionid=xrxg3zofonxmfmfvoe38gv56mgdefa71; fbm_143688012353890=base_domain=.www.memrise.com; csrftoken=MxIto89I10jvWe45lt5xBJ8xnQkWayh3; fbsr_143688012353890=YBKZYHGnLaxApGPYElgXzoLMgGpF10HWFPMjE4jAq60.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiJBUUR3R1ZibV82V19xTGdzZHFiTTluZXQ3UVdnTjFQdFhJVHpTLWIyQ3dBRnBfVk9vcWNXb2czRlBBVkl0ekpLSE5FbGNNZ2UxelZSV09tVGstODFvZFFPWmdpOUY4TGpVX3ZvNk1VOVRSTEdMVGVrWlQ3Q0Ezd2VwTjJGa044TVltak5rMEt5R2lNTWIzalRPQmlwcFhjeUZ0cS1ROF9zZWlFUDZSc1dwS0l3ZkRFVkRmNWtRb3p2VWtFQUZnZEt5eklKZkZucGozZ3RieTBZakN3bDE0SzB5ZFdDN1JjR3JyNnJQSHZvSzhLUGpJdnE3Ml9YMThybS1aUmZPSDZQNTZqTFhib3ZlSTJLVXctZGtPQUt1TE5SNmRoVUJ4b0hlZmtPSGI2ZTdJcmdtVjdlNlBVeEJuQTZyY05LdW5tLVBVbDZhQTBDTFhONzF4NEg3OHdCejA1dCIsImlzc3VlZF9hdCI6MTQ2OTg1Mzg5NSwidXNlcl9pZCI6IjUwMzc3MTY3OCJ9; _sp_id.7bc7=06d67edb75b91041.1466936153.142.1469853985.1469803261
Host:www.memrise.com
Origin:http://www.memrise.com
Referer:http://www.memrise.com/course/1160304/idioms-and-sentences/edit/database/2129600/
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
请求负载:
------WebKitFormBoundarytv2Kbmk1kUAGBVZ1
Content-Disposition: form-data; name="thing_id"
112172106
------WebKitFormBoundarytv2Kbmk1kUAGBVZ1
Content-Disposition: form-data; name="cell_id"
4
------WebKitFormBoundarytv2Kbmk1kUAGBVZ1
Content-Disposition: form-data; name="cell_type"
column
------WebKitFormBoundarytv2Kbmk1kUAGBVZ1
Content-Disposition: form-data; name="csrfmiddlewaretoken"
MxIto89I10jvWe45lt5xBJ8xnQkWayh3
------WebKitFormBoundarytv2Kbmk1kUAGBVZ1
Content-Disposition: form-data; name="f"; filename="f.mp3"
Content-Type: audio/mp3
------WebKitFormBoundarytv2Kbmk1kUAGBVZ1--
请记住,我更改了一些 cookie 以保护我在其他网站上的帐户。
感谢您的宝贵时间。
【问题讨论】:
-
为什么
$post和form_data如此不同,我不懂python,但似乎post 数据应该相似? -
useragent 中好的语法应该是“User-Agent”。由于语法不正确,服务器可能会拒绝请求。
-
@ArtisiticPhoenix 我怀疑原因是我正在使用请求库。这将自己宣传为“人类的 http 请求”,并且自己完成了很多繁重的工作。
-
@Artemis 查看通过网站发出相同请求并使用 Chrome 的开发人员工具对其进行监控的信息,我发现您是对的,这是问题的一部分。修复后,我的问题仍然存在。当然,感谢您发现这一点。
-
@DrewSSP - 我专门讨论的是 post 参数的命名,而不是 HTTP 请求的发出方式,在 php 中您发布此密钥
thing_id,而在 Python 中则不存在我看到了。在 Python 表单数据中id使用argv[1]并与 phpargv[1]中的thing_id相同,我不知道它是否等效,只是一个观察。
标签: php python-3.x post python-requests