簡體   English   中英

在嵌套字典中按子字符串查找值

[英]Find a value by substring in a nested dictionary

只是為了給我一個問題一個上下文:我正在編寫一個包含多個應用程序的Django Webapp。 其中之一用於顯示RSS源中的文章。 目前,我僅顯示鏈接,源和描述。 我想為這些文章添加縮略圖。 我正在嘗試為任何 RSS或ATOM供稿獲取這些縮略圖。 這些提要是針對某些部分(例如圖像)以完全任意的方式構造的。 由於我不想為Web上的每個提要編寫一個特定的腳本,因此我的想法是在我獲取並獲取該URL的每篇文章中查找“ .jpg”,“。png”子字符串。 python Feedparser模塊很好地處理了從RSS或ATOM提要到文章的獲取,例如輸出:

 {'guidislink': False,
  'href': '',
  'id': 'http://www.bbc.co.uk/sport/football/39426760',
  'link': 'http://www.bbc.co.uk/sport/football/39426760',
  'links': [{'href': 'http://www.bbc.co.uk/sport/football/39426760',
             'rel': 'alternate',
             'type': 'text/html'}],
  'media_thumbnail': [{'height': '576',
                       'url': 'http://c.files.bbci.co.uk/44A9/production/_95477571_joshking2.jpg',
                       'width': '1024'}],
  'published': 'Wed, 05 Apr 2017 21:49:14 GMT',
  'published_parsed': time.struct_time(tm_year=2017, tm_mon=4, tm_mday=5, tm_hour=21, tm_min=49, tm_sec=14, tm_wday=2, tm_yday=95, tm_isdst=0),
  'summary': 'Joshua King scores a dramatic late equaliser for Bournemouth as '
             'Liverpool drop two crucial points at Anfield.',
  'summary_detail': {'base': 'http://feeds.bbci.co.uk/news/rss.xml',
                     'language': None,
                     'type': 'text/html',
                     'value': 'Joshua King scores a dramatic late equaliser '
                              'for Bournemouth as Liverpool drop two crucial '
                              'points at Anfield.'},
  'title': 'Liverpool 2-2 Bournemouth',
  'title_detail': {'base': 'http://feeds.bbci.co.uk/news/rss.xml',
                   'language': None,
                   'type': 'text/plain',
                   'value': 'Liverpool 2-2 Bournemouth'}}

在這里, http://c.files.bbci.co.uk/44A9/production/_95477571_joshking2.jpg ://c.files.bbci.co.uk/44A9/production/_95477571_joshking2.jpg嵌套在列表和詞典中。 雖然我知道在這種特定情況下如何訪問它,但提要的結構卻千差萬別。 主要是:

  • 包含網址的字典鍵並不總是相同的
  • 網址嵌套的“深度”並不總是相同的

但是,幾乎總是這樣,帶有圖像擴展名的網址就是該文章的縮略圖。 如何獲取該網址?

為了進一步說明它,現在我使用幫助函數(基於Feedparser模塊)來處理feeds上下文變量,該變量是字典,可在我的模板中使用。 我直接在模板中循環顯示和顯示標題,描述等,這歸功於feedparser,它們始終是該詞典的一部分:

...
{% for feed in feeds %}
  <h3>{{ feed.feed.title }}</h3>
  {% for entry in feed.entries %}
...

在后端:

def parse_feeds(urls):
    parsed_feeds = []
    for url in urls:
        parsed_feed = feedparser.parse(url)
        parsed_feeds.append(parsed_feed)
    return parsed_feeds

class IndexView(generic.ListView):
    template_name = 'publisher/index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView,self).get_context_data(**kwargs)
        reacted_feeds = RSSArticle.objects.all()
        context['reacted_feeds'] = reacted_feeds
        parsed_feeds = parse_feeds(urls)
        delete_existing_entries(parsed_feeds)
        context['feeds'] = parsed_feeds
        return context

因此,基本上,每次調用該IndexView時,您都會從訂閱的供稿中獲取所有文章的列表。 那就是我要包含圖像的地方,由於它們在提要中的位置不一致,因此Feedparser並未提供這些圖像。

如果要包含這些圖片,則在宏級別上我基本上有兩種解決方案:

  • 除了現有系統之外,還要寫一些東西,但是由於太多事情必須同時發生,這可能會損害性能。
  • 重寫整個過程,這也可能會損害性能和一致性,因為我不再使用Feedparser的功能了

也許我應該保留原始XML並使用Beautifulsoup來試試運氣,而不是使用Feedparser翻譯成字典。

PS:這是圖像位於其他地方的另一個示例。

{'guidislink': False,
 'id': 'http://www.lemonde.fr/tiny/5106451/',
 'link': 'http://www.lemonde.fr/les-decodeurs/article/2017/04/05/presidentielle-les-grands-clivages-qui-divisent-les-onze-candidats_5106451_4355770.html?xtor=RSS-3208',
 'links': [{'href': 'http://www.lemonde.fr/les-decodeurs/article/2017/04/05/presidentielle-les-grands-clivages-qui-divisent-les-onze-candidats_5106451_4355770.html?xtor=RSS-3208',
            'rel': 'alternate',
            'type': 'text/html'},
           {'href': 'http://s1.lemde.fr/image/2017/04/05/644x322/5106578_3_0f2b_sur-le-plateau-du-debat-de-bfmtv-et-cnews_0e90a3db44861847870cfa1e4c3793b1.jpg',
            'length': '40057',
            'rel': 'enclosure',
            'type': 'image/jpeg'}],
 'published': 'Wed, 05 Apr 2017 17:02:38 +0200',
 'published_parsed': time.struct_time(tm_year=2017, tm_mon=4, tm_mday=5, tm_hour=15, tm_min=2, tm_sec=38, tm_wday=2, tm_yday=95, tm_isdst=0),
 'summary': 'Protection sociale, Europe, identité… Avec leurs programmes, les '
            'proximités idéologiques entre candidats bousculent de plus en '
            'plus le traditionnel axe «\xa0gauche-droite\xa0».',
 'summary_detail': {'base': 'http://www.lemonde.fr/rss/une.xml',
                    'language': None,
                    'type': 'text/html',
                    'value': 'Protection sociale, Europe, identité… Avec leurs '
                             'programmes, les proximités idéologiques entre '
                             'candidats bousculent de plus en plus le '
                             'traditionnel axe «\xa0gauche-droite\xa0».'},
 'title': 'Présidentielle\xa0: les grands clivages qui divisent les onze '
          'candidats',
 'title_detail': {'base': 'http://www.lemonde.fr/rss/une.xml',
                  'language': None,
                  'type': 'text/plain',
                  'value': 'Présidentielle\xa0: les grands clivages qui '
                           'divisent les onze candidats'}}

如果您只需要縮略圖,我認為最簡單的方法就是忽略其他所有內容,而只需在每個值字符串中搜索所需的尾巴即可。 有很多鏈接可以幫助您遍歷結構,如果您願意的話,但是我將其轉換為字符串然后進行解析。

您的觸發器是冒號,后跟空格和引號。 抓住引號之間的內容。 調用該

extensions = [".jpg", ".png"]
...
if value[-4:] in extensions:
    # You've found a desired URL

那會讓你動起來嗎?

我基於此片段編寫了一個解決方案。

def get_image_url(substring, dictionary):
    for key, value in dictionary.items():
        # try is for handling Booleans
        try:
            if substring in value:
                yield value
            elif isinstance(value, dict):
                for result in get_image_url(substring, value):
                    yield result
            elif isinstance(value, list):
                for list_item in value:
                    for result in get_image_url(substring, list_item):
                        yield result
        except:
            pass

>>> list(get_image_url('.jpg', article_dict))
>>> ['https://static01.nyt.com/images/2017/04/09/us/10OBAMA-alt/10OBAMA-alt-moth.jpg']

PS:雖然它不能回答在嵌套詞典中找到值的確切問題,但我發現,以一致的方式從RSS提要中獲取文章圖片的一種好方法就是簡單地將URL追溯到原始文章,解析HTML並搜索og:image標簽。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM