[Python] Ruft den Gesetzestext aus der e-GOV-Gesetz-API ab

Wir haben zusammengefasst, wie japanische Rechtsdaten von [e-Gov Law API] abgerufen und formatiert werden (https://www.e-gov.go.jp/elaws/pdf/houreiapi_shiyosyo.pdf). Ich verweise auf den folgenden Qiita-Artikel.

Sie können jeden Code in diesem Artikel aus dem GitHub-Repository herunterladen, einschließlich der Klassen, die in der endgültigen "Zusammenfassung" erscheinen.

1. Auslösen

Ich wollte die Ministeriumsverordnung (J-GCP, Ministeriumsverordnung über die Standards für die Durchführung klinischer Studien mit Arzneimitteln) verwenden, die ich bei der Arbeit häufig als Gegenstand des Studiums der Verarbeitung natürlicher Sprache bestätige. Ich mache mir Sorgen, dass der Betrag im Vergleich zu dem auf Twitter veröffentlichten Text gering ist, aber ich dachte, dass er als Thema für die Verarbeitung natürlicher Sprache nützlich sein würde, da es nur wenige Notationsschwankungen gibt.

2. Umwelt

Verwenden Sie "Anfragen" (erfordert Pip-Installation), um auf die API zuzugreifen, und das "XML" -Paket (Standardbibliothek), um XML-Daten zu analysieren. functools.lru_cache reduziert die Anzahl der API-Zugriffe (Funktionsausgabecache), pprint zeigt Wörterbücher und Listen übersichtlich an und re entfernt unnötige Zeichenfolgen (durch reguläre Ausdrücke). Wird verwendet für (Zeichenfolge löschen).

#Standardbibliothek
from functools import lru_cache
from pprint import pprint
import re
from xml.etree import ElementTree
# pip install requests
import requests
Ausführungsumgebung
OS Windows Subsystem for Linux / Ubuntu
Paketverwaltung pipenv
Language Python 3.8.5
requests 2.24.0

3. Erwerb der Gesetzesnummer

Es scheint, dass eine eindeutige ID namens "Gesetznummer" getrennt vom Namen des Gesetzes festgelegt wird. Die Nummer ist keine einfache Seriennummer, sondern eine japanische Zeichenkette ...

Die Gesetzesnummer (Horeibangou) ist eine Nummer, die individuell zur Identifizierung verschiedener Gesetze und Vorschriften vergeben wird, die von den nationalen und lokalen Regierungen erlassen wurden. Nummern werden in jedem festen Zeitraum (Kalenderjahr usw.) (ab Nr. 1), Seriennummern ab einem bestimmten Datum (Unabhängigkeitstag usw.) usw. initialisiert. Management- und Betriebsmethoden sind unterschiedlich. "Gesetznummer" Quelle: Freie Enzyklopädie "Wikipedia"

Überprüfen Sie, wie Sie nach der Gesetzesnummer anhand des Namens suchen, da Sie die Gesetzesnummer verwenden, wenn Sie den Gesetzestext erhalten.

Gesetz Nummer Wörterbuch

Erstellen Sie zunächst eine Funktion, um die Beziehung zwischen dem Gesetznamen und der Gesetzesnummer als Wörterbuch abzurufen.

law_number.py


@lru_cache
def get_law_dict(category=1):
    #Beziehen Sie eine Liste der Gesetze und Vorschriften, die in jedem Gesetzestyp enthalten sind, über die API
    url = f"https://elaws.e-gov.go.jp/api/1/lawlists/{category}"
    r = requests.get(url)
    #XML-Daten analysieren
    root = ElementTree.fromstring(r.content.decode(encoding="utf-8"))
    #Wörterbuch{Name:Gesetz Nummer}Schaffung
    names = [e.text for e in root.iter() if e.tag == "LawName"]
    numbers = [e.text for e in root.iter() if e.tag == "LawNo"]
    return {name: num for (name, num) in zip(names, numbers)}

Es gibt vier Arten von Gesetzen und Vorschriften ("Kategorie" -Argumente).

―― 1: Alle Gesetze und Vorschriften ―― 2: Verfassung, Gesetz ―― 3: Regierungsverordnung, Dekret ―― 4: Ministeriumsverordnung

Ausgabebeispiel:

pprint(get_law_dict(category=2), compact=True)
# ->
{
    "Meiji 22 Gesetz Nr. 34 (Fall der Verbrechensbekämpfung Niseki Suru)": "Meiji 22 Gesetz Nr. 34",
    "Einzahlungsregeln": "Meiji 23 Gesetz Nr. 1",
    "Gesetz zur Kontrolle der Nachahmung von Währungen und Wertpapieren": "Meiji 28 Gesetz Nr. 28",
    "Ablehnungsmethode für den Kauf von Staatsanleihen": "Meiji 29 Gesetz Nr. 5",
    "Zivilrecht": "Meiji 29 Gesetz Nr. 89",
...
    "Gesetz über außergewöhnliche Ausnahmen von nationalen Steuergesetzen zur Bewältigung der Auswirkungen neuer Coronavirus-Infektionen usw.": "Reiwa 2. Jahr Gesetz Nr. 25",
    "Gesetz über das Verbot der Beschlagnahme usw. in Bezug auf besondere Leistungen in fester Höhe usw.": "Reiwa 2. Jahr Gesetz Nr. 27",
    "Gesetz über besondere Maßnahmen zur Förderung der Katastrophenschutzarbeit usw. im Zusammenhang mit dem vorrangigen landwirtschaftlichen Stausee zur Katastrophenverhütung": "Reiwa 2. Jahr Gesetz Nr. 56"
}

Root.iter () von "Create dictionary {name: law number}" unterteilt XML-Daten in Elementeinheiten und gibt sie als Iteration zurück. Es kann ausgeführt werden, indem es durch "root.getiterator ()" ersetzt wird, aber es scheint, dass "DeprecationWarning" wie folgt auftritt.

DeprecationWarning: This method will be removed in future versions.
Use 'tree.iter()' or 'list(tree.iter())' instead.

Zusätzlich werden für jedes Element die Tags ".text" und ".tag" gesetzt.

--Wenn .tag ==" LawName ": .text den Namen des Gesetzes angibt --Wenn .tag ==" LawNo ": .text die Gesetzesnummer angibt

Bild des Elements


elements = [
    f"{e.tag=}, {e.text=}" for e in root.iter()
    if e.tag in set(["LawName", "LawNo"])
]
pprint(elements[:4], compact=False)
# ->
["e.tag='LawName', e.text='Einnahmen- und Ausgabenbudget grobe Reihenfolge'",
 "e.tag='LawNo', e.text='Meiji 22. Kabinettsverordnung Nr. 12'",
 "e.tag='LawName', e.text='Geplante Kostenberechnungsregeln'",
 "e.tag='LawNo', e.text='Meiji 22 Kabinettsverordnung Nr. 19'"]

Damit habe ich im folgenden Teil ein Wörterbuch mit Namen und Gesetznummern erstellt.

get_law_dict()


names = [e.text for e in root.iter() if e.tag == "LawName"]
numbers = [e.text for e in root.iter() if e.tag == "LawNo"]
return {name: num for (name, num) in zip(names, numbers)}

Stichwortsuche nach Namen

Ich denke, dass es selten vorkommt, dass man sich an den offiziellen Namen des Gesetzes erinnert, daher werde ich die Suche nach Stichwörtern ermöglichen.

law_number.py


def get_law_number(keyword, category=1):
    """
    Return the law number.
    This will be retrieved from e-Gov (https://www.e-gov.go.jp/)

    Args:
        keyword (str): keyword of the law name
        category (int): category number, like 1 (all), 2 (Recht), 3 (Verordnung), 4 (Ministerialverordnung)

    Returns:
        dict(str, str): dictionary of law name (key) and law number (value)
    """
    law_dict = get_law_dict(category=category)
    return {k: v for (k, v) in law_dict.items() if keyword in k}

Ausgabebeispiel:

Erwerb der Gesetzesnummer


print(get_law_number("Klinische Studien mit Arzneimitteln", category=4))
# ->
{
    'Ministerialverordnung über Standards für die Durchführung klinischer Arzneimittelstudien': '1997 Verordnung Nr. 28 des Ministeriums für Gesundheit und Soziales',
    'Ministerialverordnung über Standards für die Durchführung klinischer Versuche mit Tierarzneimitteln': '1997 Verordnung Nr. 75 des Ministeriums für Land- und Forstwirtschaft und Fischerei'
}

Das Ziel J-GCP (Ministeriumsverordnung über Standards für die Durchführung klinischer Arzneimittelversuche) war "Verordnung Nr. 28 des Ministeriums für Gesundheit und Soziales von 1997".

4. Erwerb von Rechtstexten

Senden Sie die Gesetzesnummer an die API und erhalten Sie den Text. Analysieren Sie das XML, um den Body zu erhalten und zusätzliche Leerzeichen und Leerzeilen zu entfernen.

law_contents.py


@lru_cache
def get_raw(number):
    """
    Retrieve contents of the law specified with law number from e-Gov API.

    Args:
        number (str): Number of the law, like '1997 Verordnung Nr. 28 des Ministeriums für Gesundheit und Soziales'

    Returns:
        raw (list[str]): raw contents of J-GCP
    """
    url = f"https://elaws.e-gov.go.jp/api/1/lawdata/{number}"
    r = requests.get(url)
    root = ElementTree.fromstring(r.content.decode(encoding="utf-8"))
    contents = [e.text.strip() for e in root.iter() if e.text]
    return [t for t in contents if t]

Ausgabebeispiel:

gcp_raw = get_raw("1997 Verordnung Nr. 28 des Ministeriums für Gesundheit und Soziales")
pprint(gcp_raw, compact=False)
# ->
[
    "0",
    "1997 Verordnung Nr. 28 des Ministeriums für Gesundheit und Soziales",
...
    "Inhaltsverzeichnis",
...
    "Kapitel 1 Allgemeine Regeln",
    "(Bewirken)",
    "Erster Artikel",
    "Diese Ministeriumsverordnung zielt darauf ab, die Menschenrechte der Probanden zu schützen, ihre Sicherheit zu gewährleisten und ihr Wohlergehen sowie die wissenschaftliche Qualität klinischer Studien zu verbessern
Gesetz zur Gewährleistung der Qualität, Wirksamkeit und Sicherheit von Arzneimitteln, Medizinprodukten usw., um die Zuverlässigkeit der Ergebnisse zu gewährleisten
(Im Folgenden als "Gesetz" bezeichnet) Artikel 14 Absatz 3 (entsprechend anwendbar in Artikel 14 Absatz 9 und Artikel 19-2 Absatz 5 des Gesetzes)
Einschließlich des Falles. wie unten. ) Und Artikel 14-4 Absatz 4 und Artikel 14-6 Absatz 4 des Gesetzes (diese Bestimmungen
Einschließlich der Fälle, in denen es gemäß Artikel 19-4 des Gesetzes entsprechend angewendet wird. wie unten. ) Von den in der Verordnung des Ministeriums für Gesundheit, Arbeit und Soziales festgelegten Standards
Vorgeschrieben in Artikel 80-2, Absätze 1, 4 und 5 des Gesetzes sowie in Bezug auf die Durchführung klinischer Studien mit Arzneimitteln.
Die in der Verordnung des Ministeriums für Gesundheit, Arbeit und Soziales festgelegten Standards werden festgelegt.",
    "(Definition)",
    "Artikel 2",
...
    "Ergänzende Bestimmungen",
    "(Datum des Inkrafttretens)",
    "Erster Artikel",
    "Diese Ministerialverordnung tritt am 1. April 1991 in Kraft."
]

5. Formatieren Sie den Text

Extrahiert und verbindet nur die Zeilen, die mit einem Interpunktionszeichen enden. Entfernen Sie auch die Zeichenfolgen in Klammern (Beispiel: "Pharmaceutical Affairs Law ** (Gesetz Nr. 145 von 1955) **") und "". Im Fall von J-GCP bezieht sich Artikel 56 hauptsächlich auf das Ersetzen von Wörtern und wird nicht für die Analyse verwendet, sodass er entfernt wird.

law_contents.py


def preprocess_gcp(raw):
    """
    Perform pre-processing on raw contents of J-GCP.

    Args:
        raw (list[str]): raw contents of J-GCP

    Returns:
        str: pre-processed string of J-GCP

    Notes:
        - Article 56 will be removed.
        - Strings enclosed with ( and ) will be removed.
        - 「 and 」 will be removed.
    """
    # contents = raw[:]
    # Remove article 56
    contents = raw[: raw.index("Artikel 56")]
    # Select sentenses
    contents = [s for s in contents if s.endswith("。")]
    # Join the sentenses
    gcp = "".join(contents)
    # 「 and 」 will be removed
    gcp = gcp.translate(str.maketrans({"「": "", "」": ""}))
    # Strings enclosed with ( and ) will be removed
    return re.sub("([^(|^)]*)", "", gcp)

Ausgabebeispiel:

J-GCP-Formgebung


gcp = preprocess_gcp(gcp_raw)
# ->
"Artikel 14 (3), Artikel 14-4 (4) und Artikel 14-5 (4) des Gesetzes über pharmazeutische Angelegenheiten,
Auf der Grundlage der Bestimmungen von Artikel 80-2, Absätze 1, 4 und 5 sowie Artikel 82
Die Ministerialverordnung über die Kriterien für die Durchführung klinischer Studien mit Arzneimitteln ist wie folgt festgelegt.
Diese Ministeriumsverordnung zielt darauf ab, die Menschenrechte der Untertanen zu schützen, ihre Sicherheit zu wahren und ihr Wohlergehen zu verbessern.
Um die wissenschaftliche Qualität klinischer Studien und die Zuverlässigkeit der Ergebnisse, die Qualität von Arzneimitteln, Medizinprodukten usw. sicherzustellen.
Gesetz zur Gewährleistung von Wirksamkeit und Sicherheit usw....(Weggelassen)
Für die Teilnahme an der Studie muss eine schriftliche Zustimmung eingeholt werden."

Wenn das Teil in Artikel 56 gestrichen werden soll, ersetzen Sie es bei anderen Gesetzen und Vorschriften durch "content = raw [:]" usw.

6. Zusammenfassung

Ich habe es in einer Klasse zusammengestellt.

law_all.py


class LawLoader(object):
    """
    Prepare law data with e-Gov (https://www.e-gov.go.jp/) site.

    Args:
        category (int): category number, like 1 (all), 2 (Recht), 3 (Verordnung), 4 (Ministerialverordnung)
    """

    def __init__(self, category=1):
        self.law_dict = self._get_law_dict(category=category)
        self.content_dict = {}

    @staticmethod
    def _get_xml(url):
        """
        Get XML data from e-Gov API.

        Args:
            url (str): key of the API

        Returns:
            xml.ElementTree: element tree of the XML data
        """
        r = requests.get(url)
        return ElementTree.fromstring(r.content.decode(encoding="utf-8"))

    def _get_law_dict(self, category):
        """
        Return dictionary of law names and numbers.

        Args:
            category (int): category number, like 1 (all), 2 (Recht), 3 (Verordnung), 4 (Ministerialverordnung)

        Returns:
            dict(str, str): dictionary of law names (keys) and numbers (values)
        """
        url = f"https://elaws.e-gov.go.jp/api/1/lawlists/{category}"
        root = self._get_xml(url)
        names = [e.text for e in root.iter() if e.tag == "LawName"]
        numbers = [e.text for e in root.iter() if e.tag == "LawNo"]
        return {name: num for (name, num) in zip(names, numbers)}

    def get_law_number(self, keyword, category=1):
        """
        Return the law number.
        This will be retrieved from e-Gov (https://www.e-gov.go.jp/)

        Args:
            keyword (str): keyword of the law name
            category (int): category number, like 1 (all), 2 (Recht), 3 (Verordnung), 4 (Ministerialverordnung)

        Returns:
            dict(str, str): dictionary of law name (key) and law number (value)
        """
        return {k: v for (k, v) in self.law_dict.items() if keyword in k}

    def get_raw(self, number):
        """
        Args:
            number (str): Number of the law, like '1997 Verordnung Nr. 28 des Ministeriums für Gesundheit und Soziales'

        Returns:
            raw (list[str]): raw contents of J-GCP
        """
        if number in self.content_dict:
            return self.content_dict[number]
        url = f"https://elaws.e-gov.go.jp/api/1/lawdata/{number}"
        root = self._get_xml(url)
        contents = [e.text.strip() for e in root.iter() if e.text]
        raw = [t for t in contents if t]
        self.content_dict = {number: raw}
        return raw

    @staticmethod
    def pre_process(raw):
        """
        Perform pre-processing on raw contents.

        Args:
            raw (list[str]): raw contents

        Returns:
            str: pre-processed string

        Notes:
            - Strings enclosed with ( and ) will be removed.
            - 「 and 」 will be removed.
        """
        contents = [s for s in raw if s.endswith("。")]
        string = "".join(contents)
        string = string.translate(str.maketrans({"「": "", "」": ""}))
        return re.sub("([^(|^)]*)", "", string)

    def gcp(self):
        """
        Perform pre-processing on raw contents of J-GCP.

        Args:
            raw (list[str]): raw contents of J-GCP

        Returns:
            str: pre-processed string of J-GCP

        Notes:
            - Article 56 will be removed.
            - Strings enclosed with ( and ) will be removed.
            - 「 and 」 will be removed.
        """
        number_dict = self.get_law_number("Klinische Studien mit Arzneimitteln")
        number = number_dict["Ministerialverordnung über Standards für die Durchführung klinischer Arzneimittelstudien"]
        raw = self.get_raw(number)
        raw_without56 = raw[: raw.index("Artikel 56")]
        return self.pre_process(raw_without56)

Wie benutzt man:

Verwendung von LawLoader


# The Constitution of Japan
loader2 = LawLoader(category=2)
consti_number = loader2.get_law_number("Die Verfassung Japans")
print(consti_number) # -> 'Showa 21 Verfassung'
consti_raw = loader2.get_raw("Showa 21 Verfassung")
consti = loader2.pre_process(consti_raw)
# J-GCP: Als Methode einschließlich Datenformatierung registriert
loader4 = LawLoader(category=4)
gcp = loader4.gcp()

7. Nachtrag

Als Thema der Verarbeitung natürlicher Sprache habe ich japanische Gesetze und Vorschriften heruntergeladen und gestaltet.

Danke für deine harte Arbeit!

Recommended Posts

[Python] Ruft den Gesetzestext aus der e-GOV-Gesetz-API ab
Holen Sie sich den Inhalt von Git Diff aus Python
Holen Sie sich den Rückkehrcode eines Python-Skripts von bat
Existenz aus Sicht von Python
Verwenden Sie die Flickr-API von Python
Python Holen Sie sich das kommende Wetter von der Wetter-API
Holen Sie sich Ihre Herzfrequenz von der Fitbit-API in Python!
Notizen vom Anfang von Python 1 lernen
So erhalten Sie mithilfe der Mastodon-API Follower und Follower von Python
Erhalten Sie Parlamentsprotokolle über API
[Python] Ruft das Aktualisierungsdatum eines Nachrichtenartikels aus HTML ab
[Python] Ruft den Zeichencode der Datei ab
Notizen vom Anfang von Python 2 lernen
[Python] Holen Sie sich die Hauptfarbe aus dem Screenshot
Holen Sie sich nur den Text aus dem Django-Formular.
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Holen Sie sich Artikelbesuche und Likes mit Qiita API + Python
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
[Python] Ruft die Skalenbezeichnung der Figur ab / bearbeitet sie
[Python] Holen Sie sich die Hauptthemen von Yahoo News
Holen Sie sich den Aufrufer einer Funktion in Python
[Python] Ruft das Datum der letzten Aktualisierung der Website ab
[Python] Holen Sie sich den Tag (Englisch & Japanisch)
Versuchen Sie, direkt von Python 3 aus auf die YQL-API zuzugreifen
Rufen Sie das Aktualisierungsdatum der Python-Memorandum-Datei ab.
der Zen von Python
Die Wand beim Ändern des Django-Dienstes von Python 2.7 auf Python 3-Serie
Python: Japanischer Text: Charakteristisch für Sprache aufgrund von Wortähnlichkeit
Übersetzen von Visual Studio 2017 nach Python (Microsoft Translator Text API)
So ermitteln Sie die Anzahl der Stellen in Python
Lerne Nim mit Python (ab Anfang des Jahres).
[Python] Ruft den offiziellen Dateipfad der Verknüpfungsdatei ab (.lnk)
[Python] Ruft die Liste der im Modul definierten Klassen ab
Studie vom Anfang von Python Hour1: Hallo Welt
Holen Sie sich mit Python + Zeep einen Zeitplan von der Garoon SOAP API
Python zeigt aus der Perspektive eines C-Sprachprogrammierers
Ermitteln Sie die Größe (Anzahl der Elemente) von Union Find in Python
Verwenden wir die Python-Version des Confluence-API-Moduls.
[Python] Ruft die Liste der ExifTags-Namen der Pillow-Bibliothek ab
Python: Japanischer Text: Charakteristisch für Sprache aus Wortkontinuität
Studie aus Python Hour8: Verwenden von Paketen
Holen Sie sich mit Python den Betriebsstatus von JR West
[Python] Ermittelt die Anzahl der Aufrufe aller veröffentlichten Artikel
Rufen Sie die URL des HTTP-Umleitungsziels in Python ab
[Python] Verwenden Sie die Face-API von Microsoft Cognitive Services
Auf dem Weg zum Ruhestand von Python2
Holen Sie sich die Anzahl der Ziffern
[Python] Holen Sie sich den Vormonat
Rufen Sie die API mit python3 auf.
Über die Funktionen von Python
Verwenden Sie die e-Stat-API von Python
Die Kraft der Pandas: Python
Versuchen Sie, die Funktionsliste des Python> os-Pakets abzurufen
Anders als der Importtyp von Python. Bedeutung von aus A Import B.
Holen Sie sich die Anzahl der spezifischen Elemente in der Python-Liste
Berühren wir die API der Netatmo Weather Station mit Python. #Python #Netatmo
Rufen Sie den Wert ab, während Sie den Standardwert aus dict in Python angeben
[Python] Extrahieren Sie Textdaten aus XML-Daten von 10 GB oder mehr.