Thread Eure Einschätzung: lokale HTML parsen und Werte in Remote-MySQL einfügen ?
(5 answers)
Opened by mzurhorst at 2012-03-28 12:55
Hallo zusammen!
Mühsam ernährt ich das Eichhörnchen. Aber irgendwie kommt es wohl über den Winter *gg* Ich mache Fortschritte. Allerdings frage ich mich gerade, ob ich mich total ungeschickt verhalte, und das nicht effizienter gemacht werden könnte. Gebt mir doch mal bitte Feedback, falls ich zu kompliziert vorgehe. Ich tue mir insbesondere schwer, in diesem CPAN Verzeichnis die richtigen Module zu finden. Entweder suche ich falsch und finde nichts, oder ich finde 20 Module die alle das gleiche machen (aus Sicht eines Laien zumindest) Mein Vorgehen hat sich doch etwas geändert: 1) ich kann mich nun doch mit der Remote-Datenbank verbinden. Mein Provider hat den Zugang eingerichtet. 2) für's erste werde ich nicht (mühsam) erforschen, welche Unterverzeichnisse sich veränderten oder nicht. (mit Inotify oder so). 3) stattdessen werde ich jedesmal komplett durch alle Verzeichnisse laufen. 4) dann lese ich die Sachen ein und schreibe sie in ein SQLite Datenbank hier lokal. 5) Wenn ich diese Zeile bereits habe, dann prüfe ich lediglich ob sich der Status des Caches geändert hat 6) wenn ja, dann ändere ich den Status und merke mir das in einer Zusatzspalte mit dem Kommentar "UPDATE". Sonst lass' ich diese Zeile fallen. 7) Wenn ich die Zeile noch nicht habe, dann schreibe ich die ganze Zeile und merke mir dies als "NEW" 8) Anschließend kopiere ich die Zeilen mit NEW und UPDATE von der SQLite-Datei auf den Remote-Server Noch nicht gelöst habe ich: a) Ich muss die Zeilen noch sortieren. Da ist eine Datumsstring in der notes.txt Datei drin. Das Sortieren müsste dann aber gesehen, bevor ich in die lokale Datenbank schreibe, nur habe ich da keine Idee. b) ich bekomme das rekursive Öffnen der Verzeichnisse noch nicht hin. Bisher ist alles nur rudimentär, aber es funktioniert jetzt: 1) ich kann den Pfad zum Arbeitsverzeichnis auslesen aus der Config-Datei von Geolog.pl 2) ich kann dann zu dem Verzeichnis wechseln 3) ich kann mich mit den Datenbanken verbinden Und hier mal mein Skript. Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 #!/usr/bin/perl # use 5.006; use utf8; use strict; use warnings; use DBI; use DBD::mysql; use Cwd; # # ********* BEGIN Settings ********* # 1) Remote MySQL Database # a) Remote Database # my $remote_dsn = 'dbi:mysql:dbname=xxxxxxx;host=xxxxxxx'; # my $remote_user = 'xxxxxxx'; # my $remote_password = 'xxxxxxx'; # # b) Local Test-Database my $remote_dsn = 'dbi:mysql:dbname=xxxxxxx;host=xxxxxxx'; my $remote_user = 'xxxxxxx'; my $remote_password = 'xxxxxxx'; # # 2) Local SQLite Database (hosts all geocaches found) my $sqlite_file = "/home/marcus/.gcfounds2mysql/foundcaches.db"; my $local_dsn = 'dbi:SQLite:dbname=$sqlite_file","",""'; # # 3) Geolog.pl option file and search term for the working directory my $geolog_optionfile = "/home/marcus/.geolog/profile.txt"; my $searchstring1 = 'directory: '; # # 4) Relative path from working directory to the found geocaches # Caution: leading and trailing slashes required! my $workdir = "/found/"; # # ********* END Settings ********* # # # # ********* BEGIN "Read geolog.pl working dir from its option file" ********* # # open file; OPTIONFILE is the file handle open (OPTIONFILE,$geolog_optionfile) or die "Error: profile.txt file cannot be opened!\n$!"; # walk line by line through the file while (<OPTIONFILE>){ my $line1 = $_; # read the current line chomp $line1; # remove the trailing character # Test: if line starts with the search string ... if ($line1=~/$searchstring1/) { # split line into separate strings, separated by blanks my @line2=split(/: /,$line1); # the last value of the array is our path # we add this in front of the $workdir $workdir=$line2[-1].$workdir; print "1: found the working directory in file $geolog_optionfile: \n$workdir\n"; last; } } # close file again close(OPTIONFILE); # # ********* END ********* # # # STEP 1 RECURSIVELY WALK THROUGH ALL SUB DIRECTORIES: # STEP 1.1 change to the working directory # # change the directory chdir($workdir) or die "Error: Cannot change to working directory!\n $!"; print "2: changed to the working directory\n$workdir\n"; # # # STEP 1.2 open directory and read all sub directories opendir (DIR,'.') or die "Error: Working directory cannot be opened!\n$!"; while(my $subdir = readdir (DIR)) { print "$subdir\n"; print "$workdir\n"; my $subdir2 = $workdir; print "4: TEST\n"; print "5: Subdir: $subdir2\n"; $subdir2.=$subdir."\/"; # append current directory + trailing slash print "\n\n6: Directory: ",$subdir2,"\n"; print "7: $subdir2\n"; opendir (SUBDIR,'$subdir2') or die $!; while(my $cachefiles = readdir (SUBDIR)) { print $cachefiles,"\n"; } # closes the sub directory after each inner loop closedir (SUBDIR); } # closes the workdir at end of the main loop closedir (DIR); # --> DEBUG: close early exit; # TODO 4 DATABASE LAYOUTS # TODO 4.1 SQLite table layout (temporary) # TODO * Finalize Layout of local SQLite database # Current Layout: (temporary, testing only) # TABLE `main` # `gcnumber` INTEGER PRIMARY KEY # `gcid` TEXT # `gcstatus` TEXT # `dbstatus` TEXT # # STEP 5 CONNECT TO LOCAL SQLite DATABASE # # Establish connection to local SQLite database # my $local_dbh = DBI->connect($local_dsn, { RaiseError => 1, AutoCommit => 1 }) # # DBI->connect failed: # or die('DBI->connect to SQLite File failed:' . DBI->errstr()); # # my $rv = $local_dbh->last_insert_id(undef, undef, undef, undef); # print "last_insert_id: ", $rv, "\n"; # # # Disconnect from the SQLite file # $local_dbh->disconnect; # # --> DEBUG: close early exit; # # # STEP 10 CONNECT TO REMOTE DATABASE # # Establish connection to remote database. # Connection will be held during all transactions. print "Establish connection to remote database...\n"; my $remote_dbh = DBI->connect($remote_dsn, $remote_user, $remote_password, { RaiseError => 1, AutoCommit => 1 }) # DBI->connect fehlgeschlagen: or die('DBI->connect fehlgeschlagen:' . DBI->errstr()); # Danach für jeden Eintrag des Arrays einen Statement-Handle aufmachen # in der Schleife jeweils prepare & execute & finish ## ERSTE TESTS my $db_gcnumber = '138'; # $sth is statement handler my $sth = $remote_dbh->prepare('SELECT * FROM jml_geocaches WHERE gcnumber >= ?') or die('Kann keine Verbindung zur Datenbank aufbauen. Fehler: ' . DBI->errstr()); my $rv = $sth->execute($db_gcnumber) or die('Kann Statement nicht ausführen: ' . DBI->errstr()); print "rv = $rv\n"; # returns the number of search results # Finalize the statement handler. $sth->finish(); # Disconnect from the remote database $remote_dbh->disconnect; # Job done; exit; Ich würde gerne ein paar Abkürzungen nehmen. Allerdings weiß ich nicht wie: 1) ich kenne den genauen Namen meiner "Schlüssel" in den Dateien. Kann ich das einlesen der Dateien auf 1-2 Zeilen reduzieren mit eines geeigneten Moduls ? 2) außerdem weiß ich, dass sämtliche Verzeichnisse dem Muster xxxxxxxxx_GCyyyyy entsprechen. Kann ich davon profitieren, wenn ich auf ein paarmal Fehlerabfangen verzichte ? Viele Grüße und schöne Feiertage! Marcus modedit Editiert von pq: more-tags um code hinzugefügt Last edited: 2012-04-06 17:28:52 +0200 (CEST) |