0

我有 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

问题是上传很慢,但是成功了。我在我的服务器上启动脚本。当我尝试在浏览器中上传时 - 它很快。

可能是什么问题呢?

4

2 回答 2

4

问题很可能是httplib请求库下的 Python 代码。

在较旧的 Python 版本(2.2)中分块编码流是可怕的,现在它非常糟糕。通过直接在套接字上用自定义构建的 http 层替换它并更好地处理缓冲区,我可以让应用程序以 2% 的 CPU 流式传输,并且像快速网络链接上的完整链接利用率一样。由于缓冲效率非常低,Httplib 在 CPU 使用率达到 50% 或更多的情况下只能达到 1 MB/s。httplib 适用于短请求,但不适用于大量上传(无需调整/黑客)。

根据您的网络和操作系统设置,您可以尝试一些方法来让事情变得更好:

  1. 调整你的套接字缓冲区setsockoption SO_SNDBUF,如果你不需要很多连接并且有一个快速的网络,4 MB 或更多是可能的,以减少快速管道上总是空缓冲区的问题(10GE 和更多)

  2. 使用不同的 http 库(例如带有一些补丁的 pycurl 或 Twisted)并使用更大的缓冲区进行传输,例如让每个socket.send()调用移动几 MB 的数据,而不是一些微小的 4kB 缓冲区。

如果操作正确,Python 几乎可以完全利用 10 GE 链路。

于 2013-08-07T21:39:32.870 回答
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
于 2016-09-15T19:08:37.413 回答