[PYTHON] Den Zeitplan der Keikyu-Linie abkratzen

Einführung

Als ich das Büro verließ, konnte ich automatisch von meinem Smartphone aus twittern Als nächstes möchte ich die Abfahrts- und Verspätungsinformationen des Bahnhofs anzeigen, der meinem Arbeitsplatz am nächsten liegt. Auf diese Weise können Sie einen Umweg machen, weil Sie Zeit haben, oder Sie können einfach gehen, weil Sie keine Zeit haben.

Es gibt "Station Spaato Web Service" als API, um den Zeitplan zu erhalten, aber es wird eine Gebühr erhoben.

"Station Spa und Web Service" https://docs.ekispert.com/v1/

Dann dachte ich, ich sollte es selbst machen, und als ich verschiedene Dinge recherchierte, kam ein interessanter Artikel heraus.

Blog "Auslassen der Schere": Gedanken zu Zeitplan-Schabewerkzeugen https://nkth.info/blog/dia_scraping/

Es scheint kein Problem für den persönlichen Gebrauch zu geben, indem Fahrplaninformationen extrahiert werden, ohne den Server zu belasten. Daher erhalten wir den Zeitplan und die Verzögerungsinformationen durch Scraping. Ich pendle zur Arbeit an der Keikyu-Linie, also werde ich mich dieses Mal auf die Keikyu-Linie konzentrieren.

In diesem Artikel erhalten wir die Abfahrts- und Verzögerungsinformationen der Keikyu-Linie durch Schaben.

2.png Was dieser Artikel anstrebt ↑

Annahme- und Ausführungsumgebung

Die Annahmen dieses Mal sind wie folgt. Verwendete Eisenbahnlinie: Keikyu Main Line Nächste Station zur Arbeit: Koganecho Station (Es hat nichts mit meiner Adresse zu tun) Zug benutzt: Normaler Zug runter

Ausführungsumgebung: Ubuntu18.04LTS (unter der Annahme von Android oder AWS in der Zukunft) Python 3.6.9

Umgebung

Eine bekannte Bibliothek zum Schaben ist beautifulsoup.

Code Zine: Versuchen Sie, HTML mit Python zu analysieren und Daten zu sammeln? "Python zweite Klasse", die das Schaben von Anfang an versteht https://codezine.jp/article/detail/12230

Im Fall des Fahrplans der Keikyu-Linie kann die schöne Suppe jedoch nicht gut damit umgehen. Die Daten, die von einer schönen Suppe zum Testen erhalten wurden, sind wie folgt.

Erfasste Daten


<html>
<head>
<title>Keikyu Main Line: Fahrplan der Keikyu Taura Station</title>
<meta content="max-age=1" http-equiv="Cache-Control"/>
</head>
<body>
★ Suchergebnisse<br/>
Keikyu Hauptlinie<br/>
Keikyu Taura Station Fahrplan<br/>

Nach Uraga<br/>
Wochentags Diamant<br/>
23:04 Uraga<font color="#000000">gewöhnlich</font><br/>
23:17 Uraga<font color="#000000">gewöhnlich</font><br/>
23:27 Uraga<font color="#000000">gewöhnlich</font><br/>
23:40 Uraga<font color="#000000">gewöhnlich</font><br/>
23:52 Uraga<font color="#000000">gewöhnlich</font><br/>
 0:04 Uraga<font color="#000000">gewöhnlich</font><br/>
 0:23 Uraga<font color="#000000">gewöhnlich</font><br/>
2020/7/20 ab sofort<br/>
<hr/>
<a href="T5?uid=27329&amp;dir=38&amp;path=2020102623438741&amp;slCode=250-40&amp;time=2125&amp;d=2&amp;dw=0&amp;date=&amp;pFlg=2&amp;reFlg=0&amp;USR=IM">↑ Vorherige Zeit</a><br/>
<a accesskey="1" href="T3?uid=27329&amp;dir=38&amp;path=2020102623438741&amp;sf=%8B%9E%8B%7D%93%63%89%59&amp;sfCode=2053&amp;slCode=250-40&amp;d=2&amp;time=2300&amp;dw=0&amp;USR=IM">1.Richtung/Zur Zeitauswahl</a><br/>
<hr width="80%"/>
Der Fahrplan der Stationen im ganzen Land<a href="http://1069.jp/">Stationssuche ★ Fahrplan</a>Was<hr width="80%"/>
<a accesskey="8" href="/transit/norikae/T1?USR=IM&amp;sf=%8B%9E%8B%7D%93%63%89%59">8.Bahnhofsfahrplan oben</a><br/>
<a accesskey="9" href="http://www.keikyu.co.jp/m/index.html">9.Nach oben</a><br/>
<center>(C)KEIKYU</center>
</body>
</html>

Es wird nur ein Teil des Diamanten angezeigt. Dies liegt daran, dass der Webserver von Keikyu nur Informationen sendet, die der Browser zeichnen kann. Informationen, die im Browser angezeigt werden ≠ Vom Server zurückgegebene Daten Korrekt.

GAMMASOFT: So kratzen Sie Webseiten, die mit Anforderungen nicht abgerufen werden können https://gammasoft.jp/blog/how-to-download-web-page-created-javascript/

Verwenden Sie also wie im obigen Artikel "request-html", um die Seiteninformationen abzurufen, nachdem sie vom Browser verarbeitet wurden. Geben Sie den folgenden Befehl ein, um "request-html" zu installieren.

requests-HTML-Installation


$ pip install requests #requests-HTML-Abhängigkeitsbibliothek
$ pip install requests-html

Ändern Sie die Beispieldatei, geben Sie die URL der Koganecho Station und den normalen Abstieg im Fahrplan der Keikyu-Linie an, verarbeiten Sie sie mit einem Browser und rufen Sie dann die Quelle ab.

req.py


from requests_html import HTMLSession

url = "https://norikae.keikyu.co.jp/transit/norikae/T5?uid=34683&dir=7&path=202010272317801&USR=PC&dw=0&slCode=250-28&d=2&rsf=%89%A9%8B%E0%92%AC"
#Keikyu Line Koganecho Station Downhill Gewöhnliche URL

#Sitzung starten
session = HTMLSession()
r = session.get(url)

#Generieren Sie HTML in der Browser-Engine
r.html.render()#Generieren Sie HTML im Browser
print(r.text)#Vom Browser generiertes HTML ausgeben

Erst beim ersten Start wird "Chrom" ohne Erlaubnis installiert.

Zustand zum Zeitpunkt der ersten Hinrichtung


$ python req.py 
[W:pyppeteer.chromium_downloader] start chromium download.
Download may take a few minutes.
100%|████████████████████████████████████████████████████████| 108773488/108773488 [00:09<00:00, 11116758.16it/s]
[W:pyppeteer.chromium_downloader] 
chromium download done.

Stellen Sie sicher, dass die Seiteninformationen sicher ausgegeben werden. (Es ist zu lang, um alle anzuzeigen, lassen Sie es also weg.)

Übrigens können Sie mit nur dem folgenden Befehl feststellen, ob es normal funktioniert.

$ python req.py |Informationen zum Grep-Betrieb-A 1 #Gibt die Zeile mit der Suchzeichenfolge "Operationsinformationen" und der nächsten Zeile aus
<div style="font-size: larger;">[Betriebsinformationen]<a href="https://unkou.keikyu.co.jp/?from=top" target="_blank">
Funktioniert wie gewohnt

Erstellen einer Stationstabelle

Wir erstellen eine Korrespondenztabelle mit dem Namen der Station, dem Tag (Wochentage, Samstage, Feiertage), der Richtung (Izumidakeji, Uraga) und der URL.

Werfen wir einen Blick auf die URL der Keikyu Line-Fahrplanseite.

Stationsname: Koganecho, Tag: Wochentage, Richtung: Uraga URL


https://norikae.keikyu.co.jp/transit/norikae/T5?uid=6403&dir=18&path=20201029203818692&USR=PC&dw=0&slCode=250-28&d=2&rsf=%89%A9%8B%E0%92%AC

Es gibt verschiedene URL-Parameter, aber der wesentliche ist ・ Dw (Wochentag? 0 ist normal, 1 ist Samstag, 2 ist ein Feiertag) ・ SlCode (Eindeutiger Stationscode: von 250-00 (Shinagawa)) ・ D (Richtung: Abkürzung für Richtung? 1 geht hoch und 2 geht runter) Es war nur. Daher sind die Seiten, auf die mit der obigen URL zugegriffen werden kann

Stationsname: Koganecho, Tag: Wochentage, Richtung: Uraga URL (nur erforderliche Parameter)


https://norikae.keikyu.co.jp/transit/norikae/T5?dw=0&slCode=250-28&d=2

Ist das gleiche wie. Ich fühle mich erfrischt. Es scheint, dass die Programmierung einfach ist, wenn es darum geht. SlCode (253-7) am Flughafen Haneda fehlte übrigens.

Implementierung

Nachdem wir die Seiteninformationen haben, werden wir sie kratzen. Erstellen Sie das folgende Programm. Siehe Kommentare für Details. Dieses Programm (keikyu_futsu.py) und die Stationstabellendatei (station_table.csv) werden ebenfalls auf git-hub veröffentlicht. https://github.com/zakuzakuzaki/zaki-aws/blob/main/station/koganecho.py

keikyu_futsu.py


from requests_html import HTMLSession #Schaben
import datetime #Aktuelle Zeit abrufen
import csv #CSV-Datei lesen
import sys #Befehlszeilenargument, Programmbeendigung

def get_info(st, r):

    #In Zeilenumbrüche aufgeteilt
    #Referenz-URL: https://karupoimou.hatenablog.com/entry/2019/07/08/112734
    page = r.text.split("\n")
    for i in range(len(page)):
        p = page[i]
        if "Betriebsinformationen" in p:
            unko = page[i+1]#Der Inhalt wird in die nächste Zeile der Zeichenfolge "Operationsinformationen" geschrieben.
    return st +"Die Station ist"+ unko

def get_timetable(r):

    #Fahrplan abrufen (Uhrzeit)
    hour = r.html.find(".side01")#Wochentags
    if len(hour)==0:
        hour = r.html.find(".side02")#Außer an Wochentagen
    hour_list = []
    for h in hour:
        hour_list.append(int(h.text))
    train = hour_list[0]#Holen Sie sich die erste Zugzeit

    #Fahrplan abrufen (Minuten)
    minute = r.html.find(".min1001")#Regelmäßige Zugklasse
    minute_list = []
    for m in minute:
        minute_list.append(int(m.text))
    del minute_list[0]#Löschen Sie das erste und das letzte Element, da es keine Zeiten sind
    del minute_list[-1]#Das gleiche wie oben

    #Initialisierung eines zweidimensionalen Arrays zur Speicherung des Zeitplans
    num = len(minute_list)
    dep = [[0 for i in range(2)] for j in range(num)]

    #Zeitplan Bauarbeiten
    for i in range(num):
        if  i>0 and minute_list[i-1] > minute_list[i]:
            train+=1
        dep[i] = (train, minute_list[i])
    return dep

def echo_dep(dep, time):

    #Array-Definition zum Speichern der drei Abfahrtszeiten vor der angegebenen Zeit
    dep_time = []
    #Holen Sie sich die nächste Abfahrtszeit von der aktuellen Zeit
    next=0
    now_i=0
    num = len(dep)
    for i in range(num):#Suchen Sie nacheinander nach dem ersten Stromerzeugungsfahrzeug.
        if dep[i][0]==time.hour:#Vergleiche mit der aktuellen Zeit (Zeit)
            now_i = i
            if dep[i][1]>time.minute:#Vergleiche mit der aktuellen Zeit (Minuten)
                next = i
                break
    if next==0:#Verarbeitung, wenn Minuten nicht getroffen werden (Vorlaufzeit)
        next=now_i+1

    #Erstellen einer Liste zur Anzeige
    for i in range(3):
        if next+i>=num:
            next = -1
            dep_time.append("~ letzter Zug ~")
        dep_time.append(str(dep[next+i][0]).zfill(2)+":"+str(dep[next+i][1]).zfill(2))

    return dep_time

def get_url(st , dir, dw):

    #Erstellen des Parameters slCode
    #Referenz: https://note.nkmk.me/python-csv-reader-writer/
    with open('station_table.csv') as f:
        reader = csv.reader(f)
        l = [row for row in reader]
    num = len(l)
    for i in range(num):
        if l[i][0]==st:#Suche nach Stationsname
            slCode = l[i][1]
    if i==l:
        print("Fehler: Unbekannter Stationsname.")
        sys.exit(1)
    #Parameter d,dw bleibt wie es ist
    return "https://norikae.keikyu.co.jp/transit/norikae/T5?dw="+dw+"&slCode="+slCode+"&d="+dir

if __name__ == '__main__':

    if len(sys.argv) != 4:
        print("Geben Sie die folgenden Befehlszeilenargumente an.\n1->Stationsname (Japanisch), 2->Bergauf:1, runter:2,3->Wochentags:0, Samstag:1, Urlaub:2")
        sys.exit(1)

    url = get_url(sys.argv[1], sys.argv[2], sys.argv[3])
    #① Stationsname (Japanisch), ② Bergauf:1, runter:2, ③ Wochentage:0, Samstag:1, Urlaub:2

    #Sitzung starten
    session = HTMLSession()
    r = session.get(url)

    #Generieren Sie HTML in der Browser-Engine
    r.html.render()

    #Betriebsinformationen abrufen
    info = get_info(sys.argv[1],r)

    #Holen Sie sich den Zeitplan
    dep = get_timetable(r)

    #Holen Sie sich die aktuelle Zeit
    #Referenz-URL: https://note.nkmk.me/python-datetime-now-today/
    time = datetime.datetime.now()

    #Holen Sie sich die nächste Abfahrtszeit
    dep_time = echo_dep(dep, time)

    #Ergebnisausgabe
    print("Vielen Dank für Ihre Unterstützung heute.")
    print(info)
    print("Die nächste Abfahrt ist,")
    [print(i) for i in dep_time]

    sys.exit(0)

Auf das obige Programm wurde unter Bezugnahme auf den folgenden Artikel verwiesen. ・ Zeichenkettenextraktion Naro-Analysedatensatz: [Python-Beispielcode] Erklärt eine einfache Methode, wenn Sie nur "Zeilen mit einer bestimmten Zeichenfolge" durch Scraping extrahieren möchten. https://karupoimou.hatenablog.com/entry/2019/07/08/112734

note.nkmk.me: Zeichenketten mit Python extrahieren (Position / Anzahl der Zeichen, regulärer Ausdruck) https://note.nkmk.me/python-str-extract/

・ Aktuelle Uhrzeit abrufen note.nkmk.me: Mit Python können Sie die aktuelle Uhrzeit, das Datum, das Datum und die Uhrzeit abrufen https://note.nkmk.me/python-datetime-now-today/

・ CSV-Datei lesen note.nkmk.me: CSV-Datei (Eingabe / Ausgabe) mit Python lesen / schreiben https://note.nkmk.me/python-csv-reader-writer/

Prüfung

Das Ausführungsergebnis ist wie folgt.

$ python keikyu.py Koganecho 2 1#Bezeichnen Sie "Goldene Stadt / Abfahrt / Wochentage"
Vielen Dank für Ihre Unterstützung heute.
Die Koganecho Station arbeitet wie gewohnt
Die nächste Abfahrt ist,
22:12
22:22
22:30

Ich konnte den Betriebsstatus und die Abfahrtszeit des nächsten Zuges sicher anzeigen. Wir haben bestätigt, dass es normal funktioniert, auch wenn der Stationsname geändert wird.

abschließend

Ich konnte die Abfahrts- und Verspätungsinformationen des Bahnhofs anzeigen, der meinem Arbeitsplatz am nächsten liegt, vorausgesetzt, ich würde das Büro verlassen. Ich habe es zum ersten Mal geschabt, aber es macht ziemlich viel Spaß. Der Python-Code ist jedoch schmutzig, daher hoffe ich, dass ich ihn etwas sauberer machen kann. Diesmal war es übrigens nur ein regulärer Zug, aber wenn Sie die zu extrahierende Klasse ändern, kann er von anderen Zügen unterstützt werden. Es schien, dass es einige Zeit dauern würde, mehrere Züge anzugeben, also habe ich diese Zeit bestanden.

Korrespondenz zwischen Fahrzeugtyp und Klasse (ab Fahrplan des Bahnhofs Yokohama)


<span class="syasyu1004"><span class="min1004">10</span>Vergnügen</span>&nbsp;&nbsp;
<span class="syasyu1003"><span class="min1003">10</span>Eingeschränkter Express</span>&nbsp;&nbsp;
<span class="syasyu1010"><span class="min1010">10</span>Airport Express</span>&nbsp;&nbsp;
<span class="syasyu1001"><span class="min1001">10</span>gewöhnlich</span>

URL der obigen Seite (Fahrplan für Yokohama Station Uraga) https://norikae.keikyu.co.jp/transit/norikae/T5?uid=22537&dir=34&path=2020102723533416&USR=PC&dw=0&slCode=250-25&d=2&rsf=%89%A1%95%6C

Recommended Posts

Den Zeitplan der Keikyu-Linie abkratzen
Schaben 1