Найти список внутри json данных с регулярными выражениями - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь найти список внутри JSON данных с помощью RegEx. Вот мой код:

import requests
from bs4 import BeautifulSoup
import re
import json

source = requests.get('https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-Coronado_Hotel-Zurich.html#REVIEWS').text

soup = BeautifulSoup(source, 'lxml')

pattern = re.compile(r'window.__WEB_CONTEXT__={pageManifest:(\{.*\})};')
script = soup.find("script", text=pattern)
dictData = pattern.search(script.text).group(1)
jsonData = json.loads(dictData)


pattern2 = re.compile(r'^\"[0-9]*\":{\"data\":{\"locations\":(.*)},')    
data_list = pattern2.search(str(jsonData)).group(1)
print(data_list)

С этим регулярным выражением pattern2 = re.compile(r'^\"[0-9]*\":{\"data\":{\"locations\":(.*)},') Я хочу найти значение (список) locations, но я получаю ошибку AttributeError: «У объекта NoneType нет атрибута» group '.

Часть данных JSON, которую я хочу найти, выглядит следующим образом:

"3960485871": {
            "data": {
                "locations": [
                    {
                        "detail": {
                            "hotel": {
                                "aliases": [
                                    {
                                        "id": 1099146,
                                        "locale": "de",
                                        "score": 390000,
                                        "text": "hotel coronado"
                                    },
                                    {
                                        "id": 1261196,
                                        "locale": "es",
                                        "score": 260000,
                                        "text": "hotel coronado"
                                    },
                                    {
                                        "id": 261321,
                                        "locale": null,
                                        "score": 112500,
                                        "text": "coronado hotel z\u00fcrich"
                                    }
                                ],
                                "details": {
                                    "numRooms": 40
                                }
                            },
                            "priceRange": {
                                "maximum": 212,
                                "minimum": 133
                            }
                        },
                        "formerName": null,
                        "locationId": 228146,
                        "neighborhoods": [],
                        "parents": [
                            {
                                "locationId": 188113,
                                "name": "Z\u00fcrich",
                                "placeType": "MUNICIPALITY"
                            },
                            {
                                "locationId": 188111,
                                "name": "Kanton Z\u00fcrich",
                                "placeType": "CANTON"
                            },
                            {
                                "locationId": 188045,
                                "name": "Schweiz",
                                "placeType": "COUNTRY"
                            },
                            {
                                "locationId": 4,
                                "name": "Europa",
                                "placeType": "CONTINENT"
                            },
                            {
                                "locationId": 1,
                                "name": "Welt",
                                "placeType": null
                            }
                        ]
                    }
                ]
            }
        },

1 Ответ

0 голосов
/ 10 января 2020

Попробуйте (входные данные уменьшены, поскольку они слишком велики)

jsonData = {
    "3960485871": {
        "data": {
            "locations": [
                {
                    "detail": {},
                    "formerName": None,
                    "locationId": 228146,
                    "neighborhoods": [],
                    "parents": []
                }
            ]
        }
    },
}


def find_recursive(data, type_):
    # If we found what we are looking for, return it
    if isinstance(data, type_):
        return data

    # If we didn't find it, recursively look for it
    # Lists and tuples
    if isinstance(data, (list, tuple)):
        for item in data:
            item = find_recursive(item, type_)
            if item is not None:
                return item
    # Dicts
    elif isinstance(data, dict):
        for item in data.values():
            item = find_recursive(item, type_)
            if item is not None:
                return item
    # Add here other containers that you want to recursively look for

    # If we weren't able to find it recursively, return None
    return None

find_recursive(jsonData, list)

Использование: find_recursive(DATA, TYPE) где DATA - вложенные контейнеры, а TYPE тип python, который вы хотите найти , Он принимает списки и запросы как вложенные контейнеры, но его можно распространить на другие (например, set), просто перебирая их элементы и возвращая их, если они не None. Вы можете использовать один if для нескольких типов, как я сделал с list и tuple, если они ведут себя одинаково.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...