"Création d'un service qui modifie l'historique d'utilisation de Suica mobile afin qu'il puisse être facilement utilisé pour le règlement des dépenses" La dernière fois, j'ai créé un environnement d'exécution avec Docker Cliquez ici pour le produit fini https://www.mobilesuica.work
tabula-py tabula-py Tout d'abord, j'ai essayé cela facilement
test.py
import tabula
import pandas as pd
df = tabula.read_pdf('a.pdf')
print(df.head())
Malheureusement c'était une erreur
AttributeError: 'list' object has no attribute 'head'
Apparemment, il est retourné dans un tableau Si oui, dois-je le faire?
test.py
df = tabula.read_pdf('a.pdf')
print(df[0].head())
Cela a été fait (le nom de la station résultante a changé)
Type de date Type de station utilisée.1 Station utilisée.1 Différence d'équilibre
0 2 6 Répéter NaN NaN NaN\9,753 NaN
2 2 7 Entrer à Tokyo Sortie Yokohama\9,573 -180
3 2 7 Entrer à Yokohama Sortie Tokyo\9,393 -180
Par défaut, seule la première page est utilisée, donc ajoutez pages = 'all' et combinez les deux pages. L'historique d'utilisation maximum de Mobile Suica est de 100, et s'il est différé, il y en a 101, et s'il est converti en PDF, il fera jusqu'à 2 pages.
test.py
df = tabula.read_pdf('a.pdf',pages='all')
for i in range(len(df)):
print(f"{i+1}Sur la page{len(df[i])}Il y a une ligne")
Résultat d'exécution
(app-root) bash-4.2# python3 test.py
Il y a 51 lignes sur une page
Il y a 50 lignes sur 2 pages
Vous pouvez voir que la première page a une ligne de plus pour "différé". Comme il est difficile de gérer s'ils sont séparés, nous utiliserons un DataFrmae. Utilisez concat.
test.py
df = tabula.read_pdf('a.pdf',pages='all')
d = pd.concat(df,ignore_index=True)
print(f"{len(d)}Il y a une ligne")
Résultat d'exécution
(app-root) bash-4.2# python3 test.py
Il y a 101 lignes
** ignore_index = True **, mais si vous ne l'incluez pas, l'index ne sera pas un numéro de série correctement. Comparons.
ignore_index = Vrai Aucun L'index revient à 0 à la limite entre les 1ère et 2ème pages
50 3 4 Entrer à Tokyo Sortie Yokohama\9,443 -180
0 3 5 Cash NaN NaN NaN\9,543 100
ignore_index = True Oui C'est un numéro de série tel quel
50 3 4 Entrer à Tokyo Sortie Yokohama\9,443 -180
51 3 5 Cash NaN NaN NaN\9,543 100
Si vous allez jusque-là, vous pouvez faire de même avec plusieurs fichiers. Il y a aussi convert_into_by_batch dans tabula-py, mais c'est un peu difficile à utiliser car c'est comme spécifier un répertoire et collecter les fichiers PDF sous celui-ci. (Comme je n'avais qu'un seul historique d'utilisation, j'ai lu le même fichier plusieurs fois)
test.py
fileList = ['a.pdf','a.pdf','a.pdf']
dfList = []
for fileName in fileList:
df = tabula.read_pdf(fileName,pages='all')
for i in range(len(df)):
dfList.append(df[i])
d = pd.concat(dfList,ignore_index=True)
print(f"{len(d)}Il y a une ligne")
Résultat d'exécution
(app-root) bash-4.2# python3 test.py
Il y a 303 lignes
Jusqu'à présent, j'ai remarqué qu'il y avait une légère différence entre la première et la deuxième page.
Charger une partie sur la première page
24 2 21 Espèces NaN NaN NaN\9,883 +100
Charge partie sur la deuxième page
78 3 21 Espèces NaN NaN NaN\10,317 100
Il n'y a pas de "+" sur la deuxième page. Je peux le faire sans aucun problème en termes de traitement des données, mais ça fait du mal. Quand je l'ai recherché, c'était la différence entre le reconnaître comme un nombre (deuxième page) et le reconnaître comme un caractère (première page).
14 2 15 Bus etc. OKK NaN NaN\9,103 -2,000
S'il dépasse 3 chiffres, le séparateur de mille (,) sera inclus, il semble donc que toutes les pages soient reconnues comme des caractères. La page 2 a été reconnue comme un nombre parce qu'elle n'y figurait pas (toutes à moins de 3 chiffres). Puisqu'il est plus pratique de le prendre tel quel en tant que caractère, j'ai cherché avec des pandas et j'ai trouvé que ** dtype = 'object' ** devrait être utilisé. tabula-py est un excellent moyen de transmettre les options de pandas telles quelles. La forme finale est la suivante.
test.py
fileList = ['a.pdf','a.pdf','a.pdf']
dfList = []
for fileName in fileList:
df = tabula.read_pdf(fileName,pages='all',pandas_options={'dtype':'object'})
for i in range(len(df)):
dfList.append(df[i])
d = pd.concat(dfList,ignore_index=True)
C'est incroyable que vous puissiez déposer un tableau PDF dans un DataFrame avec juste cela.
Recommended Posts