我有视频450mb。我想将它上传到我在脚本中使用的xvideos.com
xvideos_log_data = {'login': xv_login,
'password': password,
'referer': 'http://upload.xvideos.com/account',
'log': 'Login to your account'}
def xvideos(f_path):
_print('xvideos started uploading...')
try:
s = requests.Session()
s.post('http://upload.xvideos.com/account', data=xvideos_log_data, headers=headers)
rp = s.get('http://upload.xvideos.com/account/uploads/new')
apc = re.search(r'onclick="launch_upload_basic\(\'(.*?)\'\)', rp.text).group(1)
payload = {'APC_UPLOAD_PROGRESS': apc,
'message': ''}
r = s.post('http://upload.xvideos.com/account/uploads/submit?video_type=other',
data=payload,
files={'upload_file': open(f_path, 'rb')}, headers=headers)
edt = re.search(r'<a href="(.*?)" target="_top"', r.text)
if edt is None:
_print(re.search(r'inlineError.*>(.*?)<', r.text).group(1))
return
payload = {'title': make_title(),
'keywords': ' '.join(make_tags()),
'description': choice(description),
'hide': 0,
'update_video_information': 'Update information'}
r = s.post('http://upload.xvideos.com' + edt.group(1), data=payload, headers=headers)
_print('xvideos finished uploading')
except Exception as error:
_print(error)
finally:
return
问题是上传速度很慢,但成功。我在我的服务器上启动脚本。当我尝试在浏览器中上传时 - 它很快。
可能是什么问题?
答案 0 :(得分:4)
问题很可能是请求库下面的Python httplib
代码。
在较旧的Python版本(2.2)中对于分块编码流是很可怕的,现在它非常糟糕。通过直接在套接字上替换定制的http层并更好地处理缓冲区,我可以使应用程序以2%的CPU流式传输,并在快速网络链路上使用完整链路。由于缓冲效率非常低,Httplib只能达到1 MB / s,CPU使用率达到50%或更高。 httplib适用于短请求,但对于大量上传(不需要调整/黑客攻击)则不太好。
您可以尝试一些方法来改进,这取决于您的网络和操作系统设置:
通过setsockoption
SO_SNDBUF
调整套接字缓冲区,如果您不需要很多连接并拥有快速网络,可以使用4 MB或更多,以减少问题快速管道上的空缓冲区(10GE及更多)
使用不同的http库(例如pycurl或Twisted with some patches),并使用更大的缓冲区进行传输,例如:使每个socket.send()
调用移动几MB的数据而不是一些微小的4kB缓冲区。
如果做得好,Python几乎可以充分利用10 GE链接。
答案 1 :(得分:3)
上传到Amazon S3时遇到了同样的问题。
我的浏览器可以以8MB / s的速度上传,但httplib只能以1MB / s的速度上传。
经过大量搜索,我发现httplib确实是负责任的。
块大小固定为8192。
我创建了这个Monkey Patch并测试了20MB到500MB文件的许多值。
使用400000,我得到的速度与浏览器相同:8MB / s。 :)
import httplib
import httplib2
def patch_httplib(bsize=400000):
""" Update httplib block size for faster upload (Default if bsize=None) """
if bsize is None:
bsize = 8192
def send(self, data, sblocks=bsize):
"""Send `data' to the server."""
if self.sock is None:
if self.auto_open:
self.connect()
else:
raise httplib.NotConnected()
if self.debuglevel > 0:
print "send:", repr(data)
if hasattr(data, 'read') and not isinstance(data, list):
if self.debuglevel > 0: print "sendIng a read()able"
datablock = data.read(sblocks)
while datablock:
self.sock.sendall(datablock)
datablock = data.read(sblocks)
else:
self.sock.sendall(data)
httplib2.httplib.HTTPConnection.send = send