KoDa Korrupt Data
Hej!
Jag försöker ladda ned data från KoDa och har stött på ett problem med korrupta datafiler.
Jag har:
Skapat konto på Trafiklab
Skapat API-nyckel för KoDa på min profil (i ett projekt)
Laddat ner pykoda på lämpligt ställe på min dator (s.a. python hittar det)
importerat pykoda till mitt pythonscript
Skapat en configfil med API-nyckel etc.
Kontrollerat att denna API-nyckel nås av pykoda.
(ändrade lite kod i min configutils för att den skulle leta efter min configfil istället för en config folder, kan det vara ett problem?)
Nu när jag använder pykoda.datautils.get_data_range(....) så hämtas en zipfil innehållande massa data men när jag försöker läsa denna och sätta datan till en dataframe får jag felmeddelandet att filen inte kunde läsas korrekt.
I terminalen har jag kört:
python -c "import bz2; print(bz2.open(r'C:\Users\harri\AppData\Local\pykoda\pykoda\cache\otraf-vehiclepositions-2024-10-03.bz2').read(100))"
och erhållit:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\harri\AppData\Local\Programs\Python\Python39\lib\bz2.py", line 171, in read
return self._buffer.read(size)
File "C:\Users\harri\AppData\Local\Programs\Python\Python39\lib\_compression.py", line 68, in readinto
data = self.read(len(byte_view))
File "C:\Users\harri\AppData\Local\Programs\Python\Python39\lib\_compression.py", line 103, in read
data = self._decompressor.decompress(rawblock, size)
OSError: Invalid data stream
Vad kan vara problemet?
Jag har gång på gång rensat cache-foldern och försökt igen men samma problem uppstår. Kan problemet ligga i att jag modifierade min configutils eller vad kan det vara? Den nerladdade datan verkar vara korrupt och jag vet inte riktigt vad jag ska göra.
All hjälp uppskattas!
Bästa hälsningar Harriet Källberg
Jag försöker ladda ned data från KoDa och har stött på ett problem med korrupta datafiler.
Jag har:
Skapat konto på Trafiklab
Skapat API-nyckel för KoDa på min profil (i ett projekt)
Laddat ner pykoda på lämpligt ställe på min dator (s.a. python hittar det)
importerat pykoda till mitt pythonscript
Skapat en configfil med API-nyckel etc.
Kontrollerat att denna API-nyckel nås av pykoda.
(ändrade lite kod i min configutils för att den skulle leta efter min configfil istället för en config folder, kan det vara ett problem?)
Nu när jag använder pykoda.datautils.get_data_range(....) så hämtas en zipfil innehållande massa data men när jag försöker läsa denna och sätta datan till en dataframe får jag felmeddelandet att filen inte kunde läsas korrekt.
I terminalen har jag kört:
python -c "import bz2; print(bz2.open(r'C:\Users\harri\AppData\Local\pykoda\pykoda\cache\otraf-vehiclepositions-2024-10-03.bz2').read(100))"
och erhållit:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\harri\AppData\Local\Programs\Python\Python39\lib\bz2.py", line 171, in read
return self._buffer.read(size)
File "C:\Users\harri\AppData\Local\Programs\Python\Python39\lib\_compression.py", line 68, in readinto
data = self.read(len(byte_view))
File "C:\Users\harri\AppData\Local\Programs\Python\Python39\lib\_compression.py", line 103, in read
data = self._decompressor.decompress(rawblock, size)
OSError: Invalid data stream
Vad kan vara problemet?
Jag har gång på gång rensat cache-foldern och försökt igen men samma problem uppstår. Kan problemet ligga i att jag modifierade min configutils eller vad kan det vara? Den nerladdade datan verkar vara korrupt och jag vet inte riktigt vad jag ska göra.
All hjälp uppskattas!
Bästa hälsningar Harriet Källberg
Följ inlägget
1
följare
Detta beror på att filerna har blivit korrupt på KoDa-sidan. De måste skapas på nytt för att lösa problemet, något som vi måste rätta för hand.
Problemet orsakas typiskt av för många anrop som görs samtidigt till KoDa-servern, det är av denna anledning att man borde hämta 1 fil åt gången, och endast börja ladda ner nästa fil när förra filen har blivit färdigt.
Jag har nu rensat bort de korrupta filer, så de borde skapas om när du försöker ladda dem på nytt.
Hälsningar,
Bert
Tack för snabbt svar!
Jag hade en ambition om att använda pykodas metod pykoda.datautils.get_data_range() för att hämta in datan vi är intresserad av. Tar denna metod inte hänsyn till KoDas belastningskapacitet? Bör jag skriva ett eget skript för att hämta in datan istället (med API-kallningar var 30e sekund enligt tidigare mailtråd)? Jag tänkte att det hade varit smidigt att använda pykoda eftersom det finns så många andra funktioner där men det känns ju inte toppen att överbelasta systemet det första man gör. Hur hade du gjort?
Tacksam för svar och hjälp!
Bästa hälsningar Harriet
Jag kollade lite på källkoden i det där paketet, och det verkar att det finns flera fel i det paketet:
- Koden väntar inte till filer är färdiga
- Koden använder sig av ett felaktig komprimeringsformat (filerna är zippade med 7zip, koden försöker packa upp ett tar-arkiv
- Koden hanterar filstrukturen fel, tror att det ska finnas en prefix (/mnt/kodashare/...) till all data, denna prefix finns inte.
Jag ser nu att du i originalfrågan nämnde bz2 (som de använder i pykoda biblioteket), här måste du byta till 7zip. Filarna är komprimerade med LZMA2 algoritmen. Det finns flera bibliotek som pyunpack och py7zr för att hantera detta i python.
Själv skulle jag köra ett skript som loopar genom alla url:ar jag vill ladda ner, och gör anrop var 30e sekund så länge att de returnerar HTTP 202. När de inte längre returnerar HTTP 202 är filerna färdiga eller har något annat fel uppståd. Sen kan man välja att ladda ner filen, eller kan man ladda ner filen sen (det ligger cachad i all oändlighet, så det går fort att ladda ner efter att det har skapats en gång).
När filerna har laddats ner och har packats upp kan man loopa genom datat med hjälp av gtfs-realtime-bindings som översätter de binära protobuf-filerna (som finns i arkivet) till python-objekt. Mer om det hittar du här: https://gtfs.org/documentation/realtime/language-bindings/python/.
Hälsningar,
Bert