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
pythonfan
V2EX  ›  Python

实时处理进度条如何实现?

  •  
  •   pythonfan · 2014-12-06 15:38:42 +08:00 · 11177 次点击
    这是一个创建于 3633 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需求:
    点击按钮时,会去a、b、c、d 四个网站实时抓取对应的数据,然后对数据做相应的处理返回前端展现。
    现在想实现在这个等待过程中,能向用户展现abcd每个站点的抓取结果进度。比如a抓取完成,b抓取失败...最后四个站点完成,跳转到展现页面。这个该如何实现好呢?
    10 条回复    2014-12-09 14:30:36 +08:00
    imn1
        1
    imn1  
       2014-12-06 16:23:55 +08:00
    GUI 基本上要线程或协程
    CLI 要flush
    web的话,不建议做实时进度条,因为要不断在服务器端和客户端之间传递状态才能实现
    pythonfan
        2
    pythonfan  
    OP
       2014-12-06 17:16:33 +08:00
    @imn1 我想在web做呢,不过其实也不是完全实时。只需要在每个站点抓取完,给用户提示这一步已经完成了。点击按钮调用后台一个方法,然后方法中同时发起对4个站点的抓取,抓取完成的返回一个状态到前台,最后总的方法处理完余下逻辑,跳转到展现页面。现在就是有点不明白,每个站点的状态怎么返回到前端?有点困扰。。。以前都是前端单个ajax请求,后台完成自动返回一个状态的情况。
    imn1
        3
    imn1  
       2014-12-06 17:55:23 +08:00   ❤️ 1
    web做这事总是感觉有点不靠谱
    服务器端长时间执行一个任务,换个角度其实就是B/S的壳在做C/S的事
    C/S倒简单,一个长连接,状态随便传;web基本上是短连接,获取状态可能要循环定时 client pull
    当然也可以 websocket 完成,但总感到不爽

    我有段长时间没做web了,知识都停留在久远的时间点上,等等其他能人的建议吧
    datou552211
        4
    datou552211  
       2014-12-06 21:44:56 +08:00   ❤️ 1
    websocket 主要考虑浏览器的问题, ajax也可以胜任
    14
        5
    14  
       2014-12-06 21:50:08 +08:00   ❤️ 1
    长轮询吧
    beordle
        6
    beordle  
       2014-12-07 00:07:37 +08:00 via iPhone   ❤️ 1
    一个不错的优美方案是 协议好传输固定1k的数据流 但每次只传输很少的固定的bit 用来表示进度 flask 参考yield可
    bluemonster
        7
    bluemonster  
       2014-12-07 00:23:12 +08:00
    我做过类似的, 当时是自己摸索了一个比较笨的方法。
    后台任务(比如你的抓取进程)每隔一段时间(或是每完成一部分任务)就更新数据库中的一个进度字段,比如从10变成20
    前端页面js定时轮询数据库,就可以获取进度信息了。

    这个方法只适用于小规模网站,对于你的case不知道合适么
    Lucups
        8
    Lucups  
       2014-12-07 00:47:25 +08:00
    建议使用@bluemonster 的方案,如果对效率有要求可以考虑使用缓存替代数据库。
    ETiV
        9
    ETiV  
       2014-12-07 05:01:40 +08:00
    @bluemonster

    QQ旋风的离线网站应该也是这么做的. 不笨~

    它是从前端发起请求, 查询所有"未完成"任务的进度. 每隔x秒重复提交, 如此往复.

    http://lixian.qq.com/
    LZ 可以自行添加个任务试试看, 如果有QQ会员的话.

    ----

    不过如果抓取过程很快可以完成的话, LZ也可以直接从前端直接发起abcd 4次请求, 然后在每个请求完成的callback 里更新结果.

    比如导入 textarea 多行数据的时候, 每行我都会提交一次...这样就可以做出进度条的效果. 后端的逻辑也会简单许多.
    ----

    关于可能的运行时间很长的后台任务, 我还做过另外一种实现, 不去关心任务进度, 只关心结果.

    在任务跑完之后, 直接在内网 RTX 上发通知给目标用户(RTX 有HTTP接口可以调用). 通知是带有链接的, 点进去就查看结果了.
    pythonfan
        10
    pythonfan  
    OP
       2014-12-09 14:30:36 +08:00
    @Lucups
    @bluemonster
    @ETiV
    感谢各位,想明白了,因为抓取过程时间不长,2,3秒,就像@ETiV 说的,直接从前端直接发起abcd 4个请求, 然后在每个请求完成的callback 里更新结果,4个都完成后再进行后续任务。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2006 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:48 · PVG 08:48 · LAX 16:48 · JFK 19:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.