V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
mokeyjay
V2EX  ›  Python

Python3 用 urllib 下载图片非常慢,会是什么原因呢?

  •  
  •   mokeyjay ·
    mokeyjay · 2017-02-27 18:14:44 +08:00 · 5479 次点击
    这是一个创建于 2828 天前的主题,其中的信息可能已经有所发展或是发生改变。

    初学者想学写个爬虫,边学边写

    想要下载一张 Y 站的图片,代码为

    urllib.request.urlopen('http://xxx.jpg').read()
    

    其中 url 是可以正常访问的。图片不大,浏览器打开只需要几秒(排除缓存原因)。但在 python 中下载它却需要 30+秒,将下载到的数据写出为文件是可以正常查看的

    那么问题来了,究竟是什么原因导致下载一张图片那么慢呢?

    请问是还有什么地方需要配置吗?

    附完整代码:

    # 创建目录存放今天爬下来的图
    dir_name = datetime.datetime.now().strftime('%Y%m%d')
    if not os.path.exists(dir_name):
        os.mkdir(dir_name)
        
    # info[1] 的值为 https://files.yande.re/sample/6718a8caa71a4547a417f41bc9f063bb/yande.re%20385001%20sample%20byakuya_reki%20seifuku.jpg
    print('开始下载……')
    print(info[1])
    i = time.time()
    img = urllib.request.urlopen(info[1]).read()
    print('下载完毕。耗时:'+str(int(time.time() - i))+'s')
    
    # 获取文件名,并将%20 替换为空格
    file_name = info[1].split('/')[-1].replace('%20', ' ')
    file = open(dir_name+'/'+file_name, 'wb')
    file.write(img)
    file.close()
    exit(200)
    
    第 1 条附言  ·  2017-02-27 21:52:24 +08:00
    经测试,是网站对爬虫限速了
    加上 UA 、 Host 、 Referer 等头信息后一切正常, XD 谢谢各位
    17 条回复    2017-02-28 23:02:07 +08:00
    zhanglintc
        1
    zhanglintc  
       2017-02-27 18:20:23 +08:00
    我打开这张图也要很久
    mokeyjay
        2
    mokeyjay  
    OP
       2017-02-27 18:25:07 +08:00 via Android
    @zhanglintc 可能是区域问题?但我浏览器打开很快呀,换个浏览器速度也差不多。我的代码是在本地运行的,怎么速度差那么多呢?
    ltux
        3
    ltux  
       2017-02-27 18:27:35 +08:00
    也许服务器对爬虫限速了呢
    CloudnuY
        4
    CloudnuY  
       2017-02-27 18:58:35 +08:00
    你看看是不是打开了系统代理
    HFcbyqP0iVO5KM05
        5
    HFcbyqP0iVO5KM05  
       2017-02-27 19:04:03 +08:00 via Android
    浏览器有缓存吧
    mokeyjay
        6
    mokeyjay  
    OP
       2017-02-27 19:05:20 +08:00 via Android
    @ltux 还真有这个可能……@CloudnuY 用的是 ss 的 pac 模式,这个不碍事吧?@gulu 换过浏览器一样几秒打开
    fengxiang
        7
    fengxiang  
       2017-02-27 19:17:19 +08:00
    因为你浏览器走代理了,yandex 大一点的图片 2 30m,慢很正常
    fbtfonfp
        8
    fbtfonfp  
       2017-02-27 19:17:48 +08:00
    跑了一下 , 3s
    mokeyjay
        9
    mokeyjay  
    OP
       2017-02-27 20:13:03 +08:00
    @CloudnuY #4 用的是 ss 的 pac 模式,这个不碍事吧?
    @gulu #5 换过浏览器一样几秒打开
    @fengxiang #7 用的是 ss 的 pac 模式,这个不碍事吧?
    @fbtfonfp #8 就用上面的代码跑? 3s ?
    mianju
        10
    mianju  
       2017-02-27 20:20:06 +08:00
    如果挂 ss 的话,推荐使用这个库 PySocks
    具体使用参考 http://stackoverflow.com/questions/31777692/python3-requests-with-sock5-proxy
    mokeyjay
        11
    mokeyjay  
    OP
       2017-02-27 20:22:54 +08:00
    @mianju #10 看起来不错。不过我正是初学,希望尽量以原生的方式实现,先收藏了
    dsg001
        12
    dsg001  
       2017-02-27 20:29:15 +08:00
    一般调用 wget 下载
    fengxiang
        13
    fengxiang  
       2017-02-27 21:00:30 +08:00
    还是挂个代理吧,萌妹的服务器时不时抽风,不太好判断.
    推荐用 requests 代替 urllib
    binux
        14
    binux  
       2017-02-27 21:23:57 +08:00
    根据你的表述,就是系统代理没跑了。
    TTwilight
        15
    TTwilight  
       2017-02-28 10:12:36 +08:00
    我一般用 urlretrieve
    fbtfonfp
        16
    fbtfonfp  
       2017-02-28 11:59:15 +08:00
    @mokeyjay en 跑了上面的代码是 3s 不知道是不是因为挂了代理
    4ever911
        17
    4ever911  
       2017-02-28 23:02:07 +08:00
    1 loop, best of 3: 2.98 s per loop
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3197 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 13:31 · PVG 21:31 · LAX 05:31 · JFK 08:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.