A1K0
@A1K0

Как парсить строки с помощью Python?

Как с помощью Python парсить строки? Например, приходит инф с адресом "Киевская обл. , г. Киев, ул. Крещатик, дом 50, кв. 8" по факту этот адрес должен быть связан с ФИО клиента в БД. Но так как в БД залили не такой формат, то по поиску в БД не ищет ибо адрес может быть в другом порядке записан или без указания букв "кв", "дом" и тд.
  • Вопрос задан
  • 1359 просмотров
Решения вопроса 2
ScriptKiddo
@ScriptKiddo
Для начала вам нужно нормализовать адреса в базе. Сделать это можно, например, с помощью геокодера от Яндекса
/geocoder

Например, ищем "Москва, Тверская 6"

https://geocode-maps.yandex.ru/1.x/?apikey=%apikey...

Ответ

{
  "response": {
    "GeoObjectCollection": {
      "metaDataProperty": {
        "GeocoderResponseMetaData": {
          "request": "Москва,Тверская 6",
          "results": "10",
          "found": "1"
        }
      },
      "featureMember": [
        {
          "GeoObject": {
            "metaDataProperty": {
              "GeocoderMetaData": {
                "precision": "exact",
                "text": "Россия, Москва, Тверская улица, 6с1",
                "kind": "house",
                "Address": {
                  "country_code": "RU",
                  "formatted": "Россия, Москва, Тверская улица, 6с1",
                  "postal_code": "125009",
                  "Components": [
                    {
                      "kind": "country",
                      "name": "Россия"
                    },
                    {
                      "kind": "province",
                      "name": "Центральный федеральный округ"
                    },
                    {
                      "kind": "province",
                      "name": "Москва"
                    },
                    {
                      "kind": "locality",
                      "name": "Москва"
                    },
                    {
                      "kind": "street",
                      "name": "Тверская улица"
                    },
                    {
                      "kind": "house",
                      "name": "6с1"
                    }
                  ]
                },
                "AddressDetails": {
                  "Country": {
                    "AddressLine": "Россия, Москва, Тверская улица, 6с1",
                    "CountryNameCode": "RU",
                    "CountryName": "Россия",
                    "AdministrativeArea": {
                      "AdministrativeAreaName": "Москва",
                      "Locality": {
                        "LocalityName": "Москва",
                        "Thoroughfare": {
                          "ThoroughfareName": "Тверская улица",
                          "Premise": {
                            "PremiseNumber": "6с1",
                            "PostalCode": {
                              "PostalCodeNumber": "125009"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "name": "Тверская улица, 6с1",
            "description": "Москва, Россия",
            "boundedBy": {
              "Envelope": {
                "lowerCorner": "37.607242 55.757926",
                "upperCorner": "37.615452 55.762556"
              }
            },
            "Point": {
              "pos": "37.611347 55.760241"
            }
          }
        }
      ]
    }
  }
}



После чего загружаете в базу в нужной схеме и ищете по нормализованным данным

Ответ по адресу из вопроса
{
  "response": {
    "GeoObjectCollection": {
      "metaDataProperty": {
        "GeocoderResponseMetaData": {
          "request": "Киевская обл. , г. Киев, ул. Крещатик, дом 50, кв. 8",
          "results": "10",
          "found": "2"
        }
      },
      "featureMember": [
        {
          "GeoObject": {
            "metaDataProperty": {
              "GeocoderMetaData": {
                "precision": "exact",
                "text": "Украина, Киев, улица Крещатик, 50",
                "kind": "house",
                "Address": {
                  "country_code": "UA",
                  "formatted": "Украина, Киев, улица Крещатик, 50",
                  "Components": [
                    {
                      "kind": "country",
                      "name": "Украина"
                    },
                    {
                      "kind": "province",
                      "name": "Киев"
                    },
                    {
                      "kind": "locality",
                      "name": "Киев"
                    },
                    {
                      "kind": "street",
                      "name": "улица Крещатик"
                    },
                    {
                      "kind": "house",
                      "name": "50"
                    }
                  ]
                },
                "AddressDetails": {
                  "Country": {
                    "AddressLine": "Украина, Киев, улица Крещатик, 50",
                    "CountryNameCode": "UA",
                    "CountryName": "Украина",
                    "AdministrativeArea": {
                      "AdministrativeAreaName": "Киев",
                      "Locality": {
                        "LocalityName": "Киев",
                        "Thoroughfare": {
                          "ThoroughfareName": "улица Крещатик",
                          "Premise": {
                            "PremiseNumber": "50"
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "name": "улица Крещатик, 50",
            "description": "Киев, Украина",
            "boundedBy": {
              "Envelope": {
                "lowerCorner": "30.516022 50.440632",
                "upperCorner": "30.524232 50.445875"
              }
            },
            "Point": {
              "pos": "30.520127 50.443254"
            }
          }
        },
        {
          "GeoObject": {
            "metaDataProperty": {
              "GeocoderMetaData": {
                "precision": "other",
                "text": "Украина, Киевская область",
                "kind": "province",
                "Address": {
                  "country_code": "UA",
                  "formatted": "Украина, Киевская область",
                  "Components": [
                    {
                      "kind": "country",
                      "name": "Украина"
                    },
                    {
                      "kind": "province",
                      "name": "Киевская область"
                    }
                  ]
                },
                "AddressDetails": {
                  "Country": {
                    "AddressLine": "Украина, Киевская область",
                    "CountryNameCode": "UA",
                    "CountryName": "Украина",
                    "AdministrativeArea": {
                      "AdministrativeAreaName": "Киевская область"
                    }
                  }
                }
              }
            },
            "name": "Киевская область",
            "description": "Украина",
            "boundedBy": {
              "Envelope": {
                "lowerCorner": "29.266411 49.179114",
                "upperCorner": "32.161466 51.554013"
              }
            },
            "Point": {
              "pos": "30.456149 50.29807"
            }
          }
        }
      ]
    }
  }
}


UPD: добавил ответ по адресу из вопроса.
Ответ написан
A1K0, добро пожаловать в дивный мир распарсивания адресов)
Это "кроличья нора".
В идеале адреса в базу данных должны писаться через справочники (КЛАДР, ФИАС): выбираешь из словаря город, потом улицу и т.д.
Если же у тебя адрес зашит в одну строку, в одно текстовое поле в БД, то пользователи могут писать адрес всевозможными способами. Часто имеют место ошибки в написании улиц, использование черточек, дефисов, дробей, запятых, точек с запятой. Если база содержит сотни тысяч записей, то выверить все ошибки будет очень долго и муторно.
Если адрес строго формализован, то проблем почти нет. Парсишь через разделитель.
Но перед этим советую посчитать число этих разделителей в каждой строке. Может оказаться так, что у тебя в одну запись попали два адреса (регистрации и фактического проживания).
list_address = ["Киевская обл. , г. Киев, ул. Крещатик, дом 10, кв. 8",
                "Киевская обл. , г. Киев, ул. Крещатик, 2, 12",
                "Киевская обл. , г. Киев, ул. Крещатик, д.20, кв.118",
                "Киевская обл. ; Киев; Крещатик; 50-8",
                "Киевская обл. , г. Киев, пл. Незалежности, д.12-а, строение 3, помещение 8, офис. 33",]


for adr in list_address:
    # допустим разделитель запятая
    # и корректный адрес должен состоять из 5 частей
    region, city, street, house, flat = "", "", "", "", "",
    if adr.count(",") == 4:
        adr = adr.split(",")
        region = adr[0]
        city = adr[1]
        street = adr[2]
        house = adr[3]
        flat = adr[4]
    print(region, city, street, house, flat)

# распарсятся три адреса и пяти:
# Киевская обл.   г. Киев  ул. Крещатик  дом 10  кв. 8
# Киевская обл.   г. Киев  ул. Крещатик  2  12
# Киевская обл.   г. Киев  ул. Крещатик  д.20  кв.118
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
dimonchik2013
@dimonchik2013
non progredi est regredi
можно

но не копипастом функции, а пониманием исходных данных и методов преобразования

кому тамита парсер понадобится, а кому - простое векторное расстояние названия улицы от массива улиц в базе
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы