Итерация по словарям JSON (Bing API)

Я пытаюсь извлечь все значения DisplayUrl из JSON, возвращаемые Bing API. Я не уверен, что я делаю неправильно. Любое понимание ценится!

search_response = urllib2.urlopen(request)
search_results = search_response.read()
results = json.loads(search_results)
for item in results.get(u'Web', []):
     print item.get(u'DisplayUrl')

Мой запрос настроен на возврат двух результатов, поэтому я хочу получить два отпечатка с ключа DisplayUrl.

Полученное results:

{
    u'd': {
        u'results': [
            {
                u'Web': [
                    {
                        u'Description': u'Test.comprovidesacompletesoftwaresolutionforcreatingonlinetestsandmanagingenterpriseandspecialistcertificationprograms,
                        inupto22languages.',
                        u'Title': u'Test',
                        u'Url': u'http: //www.test.com/',
                        u'__metadata': {
                            u'type': u'WebResult',
                            u'uri': u"https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/ExpandableSearchResultSet(guid'51264a7c-1d14-44a2-bbcc-afa43e7fac29')/Web?$skip=0&$top=1"
                        },
                        u'DisplayUrl': u'www.test.com',
                        u'ID': u'6987b446-c20a-4521-a998-f7cf62cff0aa'
                    },
                    {
                        u'Description': u"Test your Internet Connection with Speakeasy's reliable and accurate broadband speed test. What's your speed?",
                        u'Title': u'SpeakeasySpeedTest-MegaPath',
                        u'Url': u'http: //www.speakeasy.net/speedtest/',
                        u'__metadata': {
                            u'type': u'WebResult',
                            u'uri': u"https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/ExpandableSearchResultSet(guid'51264a7c-1d14-44a2-bbcc-afa43e7fac29')/Web?$skip=1&$top=1"
                        },
                        u'DisplayUrl': u'www.speakeasy.net/speedtest',
                        u'ID': u'b2cab0a5-9866-481b-86aa-1621616ca9c9'
                    }
                ],
                u'VideoTotal': u'',
                u'RelatedSearch': [

                ],
                u'Image': [

                ],
                u'__metadata': {
                    u'type': u'ExpandableSearchResult',
                    u'uri': u"https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Composite?Sources='web'&Query='test.com'&$skip=0&$top=1"
                },
                u'ImageOffset': u'',
                u'AlterationOverrideQuery': u'',
                u'ImageTotal': u'',
                u'WebTotal': u'707000000',
                u'SpellingSuggestionsTotal': u'',
                u'WebOffset': u'0',
                u'Video': [

                ],
                u'News': [

                ],
                u'AlteredQuery': u'',
                u'SpellingSuggestions': [

                ],
                u'VideoOffset': u'',
                u'NewsTotal': u'',
                u'ID': u'51264a7c-1d14-44a2-bbcc-afa43e7fac29',
                u'NewsOffset': u''
            }
        ]
    }
}

person Chris Hall    schedule 17.11.2013    source источник


Ответы (2)


У вас есть внешняя оболочка, которую нужно пройти здесь; ваш объект results — это словарь с одним ключом 'd', ссылающийся на значение словаря, которое имеет ключ 'results', и это список словарей, и здесь мы наконец находим словарь с ключом 'Web':

for result in results['d']['results']:
    for item in result.get('Web', []):
        print item.get(u'DisplayUrl')

Демо:

>>> for result in results['d']['results']:
...     for item in result.get('Web', []):
...         print item.get(u'DisplayUrl')
... 
www.test.com
www.speakeasy.net/speedtest
person Martijn Pieters    schedule 17.11.2013
comment
неудачно. Я попытался сделать результаты строчными, так как это так в JSON, но все равно ничего. - person Chris Hall; 17.11.2013
comment
@ChrisHall: не могли бы вы предоставить нам образец JSON, который вы получаете, пожалуйста? Отредактируйте свой вопрос. - person Martijn Pieters; 17.11.2013
comment
@ChrisHall: мы работаем с документацией, в которой четко указано, что results['Web'] — это словарь с ключом 'Results', последний — список. Но если ваш запрос возвращает какой-то другой JSON, я бы хотел это увидеть. - person Martijn Pieters; 17.11.2013
comment
оператор if фактически никогда не вводится, даже если в результатах есть «Web»: - person Chris Hall; 17.11.2013
comment
@ChrisHall: сделайте print results и опубликуйте этот вывод. - person Martijn Pieters; 17.11.2013
comment
получение сообщения об ошибке: для элемента в результатах ['d']['results'].get('Web', []): AttributeError: объект 'list' не имеет атрибута 'get' - person Chris Hall; 17.11.2013
comment
@ChrisHall: да, я все еще неправильно понял формат, уже исправлен и добавлен демо. - person Martijn Pieters; 17.11.2013

Он более вложен, чем кажется.

Вот пример вывода json из документов:

"Web":{
            "Total":5100,
            "Offset":0,
            "Results":[
               {
                  "Title":"Testign part 2 - Tiernan OTooles Programming Blog",
                  "Description":"If this works, it means nothing really, but i have managed to build a .TEXT blog posting app. could be handy if i move my main blog to .TEXT, which i am thinking about..",
                  "Url":"http:\/\/weblogs.asp.net\/tiernanotoole\/archive\/2004\/09\/24\/233830.aspx",
                  "DisplayUrl":"http:\/\/weblogs.asp.net\/tiernanotoole\/archive\/2004\/09\/24\/233830.aspx",
                  "DateTime":"2008-10-21T05:08:05Z"
               }

Обратите внимание, что DisplayUrl находится внутри списка, сохраненного с ключом Results. Итак, чтобы получить:

for item in results.get('Web'. {}).get('Results', []):
        print item.get('DisplayUrl', "Not Found")

Надеюсь это поможет!

person aIKid    schedule 17.11.2013
comment
Нет радости. Документация API, по-видимому, не охватывает синтаксический анализ, а только отправку запроса. - person Chris Hall; 17.11.2013
comment
@aIKid: попробуйте запустить свой код с помощью results = {}; теперь вы получите ошибку атрибута. - person Martijn Pieters; 17.11.2013