【问题标题】:Flask + feedparser RSS reader takes too much (15 s) to load. How can I reduce this time?Flask + feedparser RSS 阅读器加载时间过长(15 秒)。我怎样才能减少这个时间?
【发布时间】:2015-02-25 13:12:27
【问题描述】:

我在做什么:

带有几个(10 到 15 个)固定提要的 RSS 阅读器。

问题:

当我在浏览器上点击刷新时,加载大约需要 15 秒。

我知道大部分加载时间是等待服务器遍历每个提要并加载每个提要中的所有条目。

也许 AJAX 可能是解决方案?


代码:

这是视图:

@app.route('/')
def index():
    RSS_URLS = [
        'http://feeds.feedburner.com/RockPaperShotgun',
        'http://www.gameinformer.com/b/MainFeed.aspx?Tags=preview',
        'http://www.polygon.com/rss/group/news/index.xml',
        ]

    entries = []
    for url in RSS_URLS:
        entries.extend(feedparser.parse(url).entries)

    entries_sorted = sorted(
        entries,
        key=lambda e: e.published_parsed,
        reverse=True)

    return render_template(
        'index.html',
        entries=entries_sorted
        )

这是模板:

{% block content %}
    <div class="row">
    {% for e in entries %}
        <div class="col-md-4 col-lg-3">
            <h1><a href="{{ e.link }}">{{ e.title }}</a></h1>
            <h5>Published on: {{ e.published }}</h5>
            {% for content in e.content %}
                <p>{{ content.value|safe }}</p>
            {% else %}
                <p>{{ e.summary_detail.value|safe }}</p>
            {% endfor %}
        </div>
    {% endfor %}
    </div>
{% endblock %}

【问题讨论】:

    标签: python flask rss rss-reader feedparser


    【解决方案1】:

    您可以并行获取提要:Practical threaded programming with Python Eventlet 这里有some code examples

    import feedparser
    import multiprocessing
    def parallel_with_gevent():
        import gevent.monkey
        gevent.monkey.patch_all()
        from gevent.pool import Pool
    
        # limit ourselves to max 10 simultaneous outstanding requests
        pool = Pool(10)
    
        def handle_one_url(url):
            parsed = feedparser.parse(url)
            if parsed.entries:
                print 'Found entry:', parsed.entries[0]
    
        for url in LIST_OF_URLS:
            pool.spawn(handle_one_url, url)
        pool.join()
    

    我在相同的场景中使用缓存文件。

    def update_cache(tmp_file,cache):
        """ logic to update cache """
        pass
    def return_cache(tmp_file,update_time_sec):
        if os.path.getctime(tmp_file) < (time.time() - update_time_sec)
            with open(tmp_file,"r") as data:
                    return data
        else:
            return None
    
    @app.route('/')
    def index():
    entries_sorted=return_cache(tmp_file,update_time_sec)
    if entries_sorted!=None:
        return render_template(
        'index.html',
        entries=entries_sorted
        )
    RSS_URLS = [
        'http://feeds.feedburner.com/RockPaperShotgun',
        'http://www.gameinformer.com/b/MainFeed.aspx?Tags=preview',
        'http://www.polygon.com/rss/group/news/index.xml',
        ]
    
    entries = []
    for url in RSS_URLS:
        entries.extend(feedparser.parse(url).entries)
    
    entries_sorted = sorted(
        entries,
        key=lambda e: e.published_parsed,
        reverse=True)
    update_cache(tmp_file,cache)
    return render_template(
        'index.html',
        entries=entries_sorted
        )
    

    【讨论】:

    • return_cache() 检查文件更改时间是否少于 update_time_sec 前。如果不是,则返回文件内容。如果是 - 不返回。在主代码中,如果它是 None,我们将收到 entries_sorted=return_cache() - 使用您的代码。最后我添加了update_cache。它必须用新数据重写缓存文件。
    • 我添加了带有同步示例的链接。您可以同时获取提要并解析它们
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    相关资源
    最近更新 更多