InstaLOC, Datenauszüge / Freigabe (Stand: 22.10.2018)

Folgende (Roh)datenauszüge beschreiben den Umfang der gesammelten Informationen.

(1) Die Locations
export_locs_22102018.rar

(2) Die Zeitstempel
times.rar

(3) Die Tagwolken
export_tags_22102018.rar

Bitte beachten.
Die Locationsdatei umfasst 3 Pakete: Auflistung, Zuordnung zu den gesammelten Likes und Zuordnung zu den gesammelten Comments.
Die Zeitstempeldatei umfasst ein Paket.
Die Tagwolkendatei umfasst 3 Pakete: Auflistung, Zuordnung zu den aktiven User_innen und Zuordnung zu den gesammelten Likes.

Die entpackten CSV-Daten schwanken zwischen wenigen 100MB bis zu 5GB und man muss über entsprechende Parser / Ressourcen verfügen, um die Daten interpretieren zu können. Hier gilt: Support wird ausschließlich den Kund_innen und den (Geschäfts)freund_innen geleistet.

InstaLOC, Datenbestand – Überblick

Nach Zusammenführung der fehlerbereinigten Datensätze (Duplikate etc.) in eine Master-DB mit den Inhalten:

-> Städte aus dem RolandBerger-Projekt
-> div. deutsche Groß- und Kleinstädte
-> politische Analyse
-> Themenwelt „Home & Living“
-> 1/3 – Datenbank aus Themenwelt „Tourismus“

kommen wir nun auf den folgenden Bestand:

24.321.643 Beiträge
19.123.483 Tagwolken
8.031.350 (codierte) Nutzer_innen
1.084.069 Locations
14.540.475 Zeitstempel

Die Datenbankdatei ist umfasst ca. 13GB und wird je Durchlauf um 3-5GB wachsen. Der aktualisierte Datenbestand wird zeitnah an die W&L GbR Partner_innen verteilt.

InstaLOC, Zwischenfreigabe der Themendatenbank „Tourismus“

Die aktuelle Datenbank umfasst die Ergebnisse aus 23575 Abfragen und speichert folgende Daten:

4.546.235 Beiträge
4.376.548 Tagwolken
2.031.490 codierte User
380.723 Locations
2.674.339 Zeitstempel

Datenauszüge (unverschlüsselt)

(1) Auflistung Tagwolken und deren Locations
Datei: exp_urlaub_tag_loc.zip
Dateivolumen: ZIP->339MB, Entpackt->1.6GB

(2) Auflistung der Locations und Aufsummierung der Likes JE Location
Datei: exp_urlaub_like_locs.zip
Dateivolumen: ZIP->13MB, Entpackt->42MB

(3) Auflistung Tagwolken (ungefiltert!) und deren Likes
Datei: exp_urlaub_tag_likes.zip
Dateivolumen: ZIP->168MB, Entpackt->600MB

(4) Auflistung der Locations + Postingzeitstempel + Likes
Datei: exp_urlaub_loc_time_likes.zip
Dateivolumen: ZIP->52MB, Entpackt->265MB

(5) Auflistung der Locations + Aufsummierung der Postings
Datei: exp_urlaub_postings_locs.zip
Dateivolumen: ZIP->12MB, Entpackt->42MB

(6) Auflistung der Tagwolken + Aufsummierung der User, welche die Wolken verwendeten
Datei: exp_urlaub_tags_user.zip
Dateivolumen: ZIP->333MB, Entpackt->1.5GB

(7) Auflistung der Locations + Aufsummierung der User, welche an den Locations aktiv waren
Datei: exp_urlaub_loc_user.zip
Dateivolumen: ZIP->13MB, Entpackt->41MB

Die aufgelisteten Datenauszüge geben einen ersten und sehr guten Überblick.
Im Bezug zu den erfassten Datensätzen sind weitere Nachforschungen die Beantwortung hochfaszinierender Fragen, wie:

(a) Wieviele User schreiben in welchem Zeitfenster über den Urlaub an welchen Orten?
(b) Welche Orte werden an Hotspots von welchen Usergruppen besucht und was wird da geschrieben?
(c) Welche User / Usergruppen neigen zur Trendbildung an welchen Orten und / oder zu welchen Tags (Themen, Themenwelten)?
(d) Welche Orte werden zu welchen Zeitfenstern|Jahreszeiten|Monaten besonders stark frequentiert und was wird da geschrieben?

möglich.

Die Anwendungsszenarien sind vielfältig. Ich denke an die folgenden Punkte:

-> Influenceraccountanalysen
-> Schnittstellen zu Socialmediastrategien inkl. Hashtag- und Postzeitplanungen
-> Schnittstellen zu div. Textanalysetools mit Anbindung an WDF*IDF / KWD-Analysen
-> gezielte Steuerung von ortsbezogenen Werbeanzeigen|Flyeraktionen|Plakataktionen|sonst.Promomaßnahmen
-> Gegenprobe auf die üblichen Auswertungstools aus der Socialmedia
-> gezielte Steuerung von ortsbezogenen Werbeanzeigen in den Suchmaschinen, den Socialmedia

Interesse am Austausch? Fragen? Anfragen?
Konkretes Projektangebot?
Ich freue mich auf Rückmeldung unter der eMail: office(at)pontipix.de

Projekt „InstaLOC“ – Update der Scrapertechnologie + Bugfixing

Während der letzten Datendurchläufe stellte ich immer wieder fest, dass der Scraper den Arbeitsspeicher zu stark beanspruchte. Konkret bedeutet das, dass ca. 250 Abfragen an die API einen Scrapingabbruch und einen RAM-Verbrauch i.H.v. 1,8GB (!) provozierte.

Dieses Problem wurde nun final über die Quellcodeanpassung
jsonvalue.Free;
JSON.Free;

gelöst.

Der Speicherverbrauch wurde von 1.8GB auf ca. 100MB / je 250 Abfragen reduziert.

Die fehlerbereinigte Prozedur ist:
procedure TForm1.getmedia_db(mytable: TStringGrid; tagsearch: string; rounds: integer);
var
JSONArray: tJSONArray;
JSONValue,jvalue: tJSONValue;
JSONPair: TJSONPair;
JSON, json_sub: TJSONObject;
size: integer;
j_array: tJSONArray;
s: string;
i,j: integer;
next_id: string;
zaehl: integer;
url,tag,likes,comments,post_id,username,location,filter,pruefzeit: widestring;
erstellzeit: string;
gedoens: TIdHTTP;
zw_db: tmemo;
begin
gedoens := TIdHTTP.Create;
zw_db :=tmemo.Create(self);
sql_befehle.Clear;
try
zw_db.text:=gedoens.Get('https://api.instagram.com/v1/tags/'+escape(tagsearch)+'/media/recent?access_token='+token.text);
JSONValue := TJSONObject.ParseJSONValue(zw_db.text);
JSON := TJSONObject.ParseJSONValue(zw_db.Lines.Text) as TJSONObject;
JSONArray := TJSONArray(JSON.Get('data').JsonValue);
try next_id:= JSONValue.GetValue('pagination.next_url');
except
//-> hier user, locations etc. einbauen!!!
next_id:='N/A';
end;

for i := 0 to JSONArray.Size - 1 do
begin
url:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('link')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('tags')).ToString);
s:= StringReplace(s, '"tags":[', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, ']', '', [rfReplaceAll,rfIgnoreCase]);
tag:=escape(s);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('likes')).ToString);
s:= StringReplace(s, '"likes":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
likes:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('comments')).ToString);
s:= StringReplace(s, '"comments":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
comments:=s;
erstellzeit:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('created_time')).JsonValue.Value);
erstellzeit:=datetimetostr(UnixToDateTime(strtoint(erstellzeit)));
post_id:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('id')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('user')).ToString);
s:= StringReplace(s, '"user":{"username":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '"', '', [rfReplaceAll,rfIgnoreCase]);
username:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('location')).ToString);
s:= StringReplace(s, '"location":', '', [rfReplaceAll,rfIgnoreCase]);
location:=s;
filter:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('filter')).JsonValue.Value);
pruefzeit:=datetimetostr(now);
with sql_befehle.Lines do
begin
add('INSERT INTO `locations` (`url`, `tag`, `likes`, `comments`, `erstellzeit`, `post_id`, `username`, `location`, `filter`, `pruefzeit`) Values ('''+url+''', '''+tag+''', '''+likes+''', '''+comments+''', '''+erstellzeit+''', '''+post_id+''', '''+username+''', '''+location+''', '''+filter+''', '''+pruefzeit+''');');
end;
end;
fdquery3.ExecSQL(sql_befehle.text);
sql_befehle.Clear;
// sql_befehle.Free;
except
tr_break:='1';
end;

// -> Speicherfreigabe
jsonvalue.Free;
JSON.Free;
if next_id<>'N/A' then
begin
repeat
// -> tiefenpruefung
if next_id='N/A' then
break;
delay(strtoint(frequenz1.Text));
try
zw_db.text:=gedoens.Get(next_id);
JSONValue := TJSONObject.ParseJSONValue(zw_db.text);
JSON := TJSONObject.ParseJSONValue(zw_db.Lines.Text) as TJSONObject;
JSONArray := TJSONArray(JSON.Get('data').JsonValue);
try next_id:= JSONValue.GetValue('pagination.next_url');
except
next_id:='N/A';
break;
end;
for i := 0 to JSONArray.Size - 1 do
begin
url:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('link')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('tags')).ToString);
s:= StringReplace(s, '"tags":[', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, ']', '', [rfReplaceAll,rfIgnoreCase]);
tag:=escape(s);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('likes')).ToString);
s:= StringReplace(s, '"likes":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
likes:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('comments')).ToString);
s:= StringReplace(s, '"comments":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
comments:=s;
erstellzeit:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('created_time')).JsonValue.Value);
erstellzeit:=datetimetostr(UnixToDateTime(strtoint(erstellzeit)));
post_id:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('id')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('user')).ToString);
s:= StringReplace(s, '"user":{"username":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '"', '', [rfReplaceAll,rfIgnoreCase]);
username:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('location')).ToString);
s:= StringReplace(s, '"location":', '', [rfReplaceAll,rfIgnoreCase]);
location:=s;
filter:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('filter')).JsonValue.Value);
pruefzeit:=datetimetostr(now);
with sql_befehle.Lines do
begin
add('INSERT INTO `locations` (`url`, `tag`, `likes`, `comments`, `erstellzeit`, `post_id`, `username`, `location`, `filter`, `pruefzeit`) Values ('''+url+''', '''+tag+''', '''+likes+''', '''+comments+''', '''+erstellzeit+''', '''+post_id+''', '''+username+''', '''+location+''', '''+filter+''', '''+pruefzeit+''');');
end;
end;
fdquery3.ExecSQL(sql_befehle.text);
sql_befehle.Clear;
except
tr_break:='1';
break;
end;
// -> Speicherfreigabe
jsonvalue.Free;
JSON.Free;
// -> tiefenpruefung, ende
zaehl:=zaehl+1;
until zaehl=rounds;
end;
form1.Caption:=version+' alle Posts herunter geladen';
gedoens.free;
zw_db.Free;
fdquery.Free;
end;

Datenbanken, Bigdata und die Aufbereitung der Abfragen

Nach Durchsicht der aktuellen Datenbasis aus den Projekten „HashtagDB“ und „InstaLOC“ musste ich etwas nachdenken und mir eine Lösung zur Aufbereitung der extremen Datenfülle überlegen. Das Problem ist, dass zwar via SQLite-Studio und der integrierten SQL-basierten Abfragemöglichkeiten gute Abfrage- und Auswertungsmöglichkeiten vorliegen, jedoch lassen sich keinerlei Gewichtungsprozeduren hier realisieren. Ein angedachter Lösungsweg war die Anbindung von Excel via der bereitgestellten API. Trotz (technischer) Realisierbarkeit tauchten auf verschiedenen Rechnern immer wieder Ressourcenprobleme auf. Ich entschied mich heute (final) für eine 3-Stufenlösung:

(1) Vorgewichtung
Die Vorgewichtung erfolgt via SQLite-Studio in Form der – hier dokumentierten – Abfragen. Wir, oder ein geschulter Externer, setzen entsprechende Metaebenenanfragen an die Datenbanken ab und extrahieren die Ergebnisse im Standard-CSV-Format.
Metaebenenanfragen können sein:
(a) Gib mir alle Tagwolken aus dem Zeifenster 08-2018 aus, die mind. zum Inhalt „urlaub“ haben und in dem Raum Leipzig gepostet wurden.
(b) Zeige mir die beliebtesten Postings aus dem Raum Berlin mit Inhalt „Schmuck“.

(2) Nachgewichtung
Die Nachgewichtung erfolgt hier mit Hilfe einer kleinen Software. Diese importiert die Ergebnisse aus der „Vorgewichtung“ und liefert über geeignete Berechnungsfunktionen Interpretationshinweise zu:
(a) Welche Beziehungen existieren zwischen den Hashtags?
(b) Welche Beziehungen existieren zwischen den Tags, den Locations und den aktiven Accounts?
(c) Wer gewichtet Trends in welchem Zeitfenster, an welcher Location?

(3) Interpretation und Reporting
Die Nachgewichtungssoftware exportiert die generierten Gewichtungsergebnisse in ein geeignetes Standarformat, welches von Openoffice und Excel akzeptiert wird. Die grafische Auswertung und die Aufbereitung für nachgelagerte Beratungsgespräche und Interpretationen im Team / bei den Kund_innen findet genau in diesem Umfeld statt.

Privat vertrete ich den Anspruch an die absolute Transparenz bzgl. der Rohdaten / der Datensätze. Ich habe aber auch, nach verdammt vielen Diskussionen, verstanden, dass 4-20GB große Datensätze von Geschäftsfreund_innen und Kund_innen nicht behandelbar sind. Daher der skizzierte Kompromis der Aufbereitung via Excel, Powerpoint & Co. und Quercheck auf die gefilterten Daten aus der „Nachgewichtung“.

Anfragen, Hinweise oder Nachfragen gerne via Kommentar, eMail oder Telefon.

InstaLOC: Accountrecherchen auf Basis der Likes und Comments

Die modifizierten Datenbankspalten erlauben nun genauere Accountbegutachtungen für Influencerrecherchen, Suche nach Trendursprüngen und die folgenden Queries verdeutlichen die Anwendungsszenarien:

(1) User zu Location
SELECT location, username as Nutzer, Anz_Likes from(
Select location, username, sum(likes) as Anz_likes from locations GROUP BY username ) as my_table
where location like '%hotel%' order by Anz_Likes DESC

Diese Abfrage verschafft einen Überblick zu den Usernames. Hierbei werden die Beiträge den Locations zugeordnet und die Likes aufsummiert.
Aufgaben:
(a) Auflistung der Accounts, welche bei den Locations eventuell Trends setzen
(b) Auflistung der Influenceraccounts, welche an den Locations für Reichweite sorgen (können)

(2) Userbewertung – Basis
SELECT username as Nutzer, Anz_Likes from(
Select username, sum(likes) as Anz_likes from locations GROUP BY username ) as my_table order by Anz_Likes DESC

Diese Abfrage verschafft einen Überblick zu den Usern in Verbindung mit den aufsummierten Likes.
Aufgaben:
(a) Erste Grobrecherche

(3) User zu Location und Zeitfenster
SELECT location, username as Nutzer, Anz_Likes from(
Select location, erstellzeit, username, sum(likes) as Anz_likes from locations GROUP BY username ) as my_table
where (erstellzeit like '%.2016%') and (location like '%hotel%') order by Anz_Likes DESC

Diese Abfrage verschafft einen Überblick zu den Usernames. Hierbei werden die Beiträge den Locations zugeordnet, nach einem Zeitfenster gefiltert und die Likes aufsummiert.
Aufgaben:
(a) Auflistung der Accounts, welche bei den Locations eventuell Trends setzen
(b) Auflistung der Influenceraccounts, welche an den Locations für Reichweite sorgen (können)

Diese Abfragen lassen sich recht problemlos auf die Tagwolken umschreiben.
Die Rechercheoptionen werden zeitnah in den neuen Client überführt und via Reports in die Beratungsprojekte integriert.

InstaLOC – Sichtung und Abfragen bzgl. der „Themenweltdatenbank“

Für die Prüfung und auch „Eichung“ der erweiterten Datenquelle (hier: Tagsearch mit Ergänzung zu den Locations) wurde eine Themenweltdatenbank angelegt, welche auch durch aktuelles Zeitgeschehen inspiriert ist.

Der Scraper benötigte 20 Stunden für die Erfassung der Daten, wobei diese Zeit auf 2 Tage verteilt und eine Liste mit ca. 6000 „Spezialterms“ abgearbeitet wurde.

Datenbankstatistik:
Anz. Einträge: 1238290
Anz. Filter: 45
Anz. Tagsclouds: 1011505
Anz. Locations: 110648
Anz. Accounts: 553799
Anz. Posting/Zeitstempel: 806680
Dateigröße (Byte): 689319936

Beispielabfragen:
(1) select location, erstellzeit from locations where (tag like ‚%22aXX%22‘) and (tag like ‚%22mXXXXXXXXXXXX%22′) and (location <> ’null‘);

Übersetzung:
Hole alle Locations und Erstellzeitpunkte (Zeitstempel) aus der Datenbank, wo die „tag like“ Bedingungen zutreffen und eine Location hinterlegt ist.
Ergebnisse:
771 Einträge

(2) select count(distinct(location)) from locations where (tag like ‚%22aXX%22‘) and (tag like ‚%22mXXXXXXXXXXXX%22′) and (location <> ’null‘);
Übersetzung:
Hole Locations aus der Datenbank, wo die „tag like“ Bedingungen zutreffen und eine Location hinterlegt ist.
Ergebnisse:
99 Einträge (für count(distinct(location)),
Liste (PDF, Locations, für „select location“)
Liste (PDF, Erstellzeit + Location, für „select location, erstellzeit“)

(3) select count(username) from locations where (tag like ‚%22aXX%22‘) and (tag like ‚%22mXXXXXXXXXXX%22‘);
Übersetzung:
Zähle die Accounts zusammen, wo in den Tagwolken die 2 abgefragten Terms vorkommen.
Ergebnisse:
3077 Einträge

Projekt „InstaLOC“ – Datenbankbefüllung auf Basis der Tagsuche

(1) Vorbereitung
Im ersten Schritt wird die Datenbank angelegt.

with sql_befehle do
begin
clear;
lines.Add('drop table if exists locations;');
lines.Add('CREATE TABLE `locations` (');
lines.Add(' `id` integer primary key AUTOINCREMENT,');
lines.Add('`url` varchar(400),');
lines.Add('`tag` varchar(2000),');
lines.Add('`likes` varchar(400),');
lines.Add('`comments` varchar(400),');
lines.Add('`erstellzeit` varchar(400),');
lines.Add('`post_id` varchar(1600),');
lines.Add('`username` varchar(400),');
lines.Add('`location` varchar(400),');
lines.Add('`filter` varchar(400),');
lines.Add('`pruefzeit` varchar(400)');
lines.Add(');');
lines.Add('vacuum;');
end;
fdquery3.ExecSQL(sql_befehle.text);

Die Datei umfasst folgende Spalten:
ID -> Nummerierung der Einträge (Zeilen)
URL -> erfasste Beitragsurl
Tag -> erfasste Tagwolke
Likes -> erfasste Likes als Zahl
Comments -> erfasste Comments als Zahl
Post_ID -> per Instagram vergebene Medien/Beitrags-ID
Username -> Username: Wer hat den Beitrag veröffentlicht?
Location -> Location des Beitrages, falls vom User freigegeben (GeoCode + Name)
Filter -> Fotofilter des veröffentlichten Beitrages
Erstellzeit -> Wann wurde der Beitrag veröffentlicht?
Pruefzeit -> Wann wurde der Beitrag vom Scraper erfasst UND in die Datenbank gespeichert?

(2) Scrapingvorgang
for lauf := strtoint(uebertrag.Text) to memo8.Lines.Count-1 do
begin
randomize;
token.Text:=token.Items[random(token.Items.Count-1)];
getmedia_db(locmedia,memo8.Lines[lauf],200);
end;

(3) Scrapingprozedur

procedure TForm1.getmedia_db(mytable: TStringGrid; tagsearch: string; rounds: integer);
var
JSONArray: tJSONArray;
JSONValue,jvalue: tJSONValue;
JSONPair: TJSONPair;
JSON, json_sub: TJSONObject;
size: integer;
j_array: tJSONArray;
s: string;
i,j: integer;
next_id: string;
zaehl: integer;
url,tag,likes,comments,post_id,username,location,filter,pruefzeit: widestring;
erstellzeit: string;
begin
sql_befehle.Clear;
memo3.Lines.Add('url => https://api.instagram.com/v1/tags/'+escape(tagsearch)+'/media/recent?access_token='+token.text);
try
debug.text:=idhttp1.Get('https://api.instagram.com/v1/tags/'+escape(tagsearch)+'/media/recent?access_token='+token.text);
JSONValue := TJSONObject.ParseJSONValue(debug.text);
JSON := TJSONObject.ParseJSONValue(debug.Lines.Text) as TJSONObject;
JSONArray := TJSONArray(JSON.Get('data').JsonValue);
try next_id:= JSONValue.GetValue('pagination.next_url');
except
next_id:='N/A';
end;
for i := 0 to JSONArray.Size - 1 do
begin
url:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('link')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('tags')).ToString);
s:= StringReplace(s, '"tags":[', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, ']', '', [rfReplaceAll,rfIgnoreCase]);
tag:=escape(s);
memo7.Lines.Add(unescape(tag));
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('likes')).ToString);
s:= StringReplace(s, '"likes":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
likes:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('comments')).ToString);
s:= StringReplace(s, '"comments":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
comments:=s;
erstellzeit:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('created_time')).JsonValue.Value);
erstellzeit:=datetimetostr(UnixToDateTime(strtoint(erstellzeit)));
post_id:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('id')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('user')).ToString);
s:= StringReplace(s, '"user":{"username":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '"', '', [rfReplaceAll,rfIgnoreCase]);
username:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('location')).ToString);
s:= StringReplace(s, '"location":', '', [rfReplaceAll,rfIgnoreCase]);
location:=s;
filter:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('filter')).JsonValue.Value);
pruefzeit:=datetimetostr(now);
with sql_befehle.Lines do
begin
add('INSERT INTO `locations` (`url`, `tag`, `likes`, `comments`, `erstellzeit`, `post_id`, `username`, `location`, `filter`, `pruefzeit`) Values ('''+url+''', '''+tag+''', '''+likes+''', '''+comments+''', '''+erstellzeit+''', '''+post_id+''', '''+username+''', '''+location+''', '''+filter+''', '''+pruefzeit+''');');
end;
end;
fdquery3.ExecSQL(sql_befehle.text);
sql_befehle.Clear;
except
end;
if next_id<>'N/A' then
begin
repeat
// -> tiefenpruefung
if next_id='N/A' then
break;
delay(strtoint(frequenz1.Text));
try
debug.text:=idhttp1.Get(next_id);
JSONValue := TJSONObject.ParseJSONValue(debug.text);
JSON := TJSONObject.ParseJSONValue(debug.Lines.Text) as TJSONObject;
JSONArray := TJSONArray(JSON.Get('data').JsonValue);
try next_id:= JSONValue.GetValue('pagination.next_url');
except
next_id:='N/A';
break;
end;
for i := 0 to JSONArray.Size - 1 do
begin
url:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('link')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('tags')).ToString);
s:= StringReplace(s, '"tags":[', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, ']', '', [rfReplaceAll,rfIgnoreCase]);
tag:=escape(s);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('likes')).ToString);
s:= StringReplace(s, '"likes":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
likes:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('comments')).ToString);
s:= StringReplace(s, '"comments":{"count":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
comments:=s;
erstellzeit:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('created_time')).JsonValue.Value);
erstellzeit:=datetimetostr(UnixToDateTime(strtoint(erstellzeit)));
post_id:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('id')).JsonValue.Value);
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('user')).ToString);
s:= StringReplace(s, '"user":{"username":', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '}', '', [rfReplaceAll,rfIgnoreCase]);
s:= StringReplace(s, '"', '', [rfReplaceAll,rfIgnoreCase]);
username:=s;
s:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('location')).ToString);
s:= StringReplace(s, '"location":', '', [rfReplaceAll,rfIgnoreCase]);
location:=s;
filter:=(TJSONPair(TJSONObject(JSONArray.Get(i)).Get('filter')).JsonValue.Value);
pruefzeit:=datetimetostr(now);
with sql_befehle.Lines do
begin
add('INSERT INTO `locations` (`url`, `tag`, `likes`, `comments`, `erstellzeit`, `post_id`, `username`, `location`, `filter`, `pruefzeit`) Values ('''+url+''', '''+tag+''', '''+likes+''', '''+comments+''', '''+erstellzeit+''', '''+post_id+''', '''+username+''', '''+location+''', '''+filter+''', '''+pruefzeit+''');');
end;
end;
fdquery3.ExecSQL(sql_befehle.text);
sql_befehle.Clear;
except
break;
end;
// -> tiefenpruefung, ende
zaehl:=zaehl+1;
until zaehl=rounds;
end;
end;

Prozeduraufruf.

getmedia_db(locmedia,memo8.Lines[lauf],200);

Erklärung, Prozedurlogik:

Die Variable „locmedia“ ist für das Szenarium relativ uninteressant und wird aktiviert, wenn bspw. die gescrapten Daten in ein Stringgridobjekt zwecks Gegensichtung übergeben werden müssen. Die Variable „memo8.lines[X]“ beschreibt den Zwischenspeicherort der Tagliste(n), wobei „X“ oder „lauf“ die Position des Terms / Tags in der Liste beschreibt. Die Variable „200“ sagt aus, wie tief die Scrapingprozedur forschen soll. In dem Fall handelt es sich um 200×20 (-> 4000) Beiträge je Suchanfrage.

Projekt „InstaLoc“ – Wechsel der Datenscrapertechnologie

Nach diversen Gesprächen, Socialmediabeobachtungen usw. entschied ich mich zur festen Einbindung eines weiteren Datenscraperansatzes.
Dieser interpretiert nun die Stadt nicht als Konstruktion mit einer Grenze, sondern als „Gegend“ mit der Stadt als Mittelpunkt.

Konkrete Beispiele können sein:

Datenbank „Mainz“ -> Mainz + Wiesbaden
Datenbank „Apolda“ -> Apolda + Weimar + Jena + div. Dörfer (falls auslesbar)
Datenbank „Leipzig“ -> Leipzig + Halle + Merseburg

Der Testlauf zum Raum „Mainz“ ergab ca. 25.700 auslesbare Locations zu max. 2000 Beiträge und ein Datenerfassungsdurchlauf beansprucht etwas um die 24 Stunden.

Im Zuge der nächsten Updates werden weitere Erhebungsmethoden getestet und ggf. in die Prozeduren eingebaut.

Die massive Datenausweitung und das feinmaschig erfasste Locationnetz erlaubt nun (auch nach Rückmeldung der Kolleg_innen) die Beantwortung folgender Fragen:

(1) Wo befinden sich ansprechbare (!) Zielgruppen?
(2) Was machen die ansprechbaren Zielgruppen an welchen Orten (gez. durch die Tagwolken, Fotofilter, Emotionsäußerungen etc.)=
(3) Wie sind die Bewegungsstrecken von ansprechbaren Zielgruppen gestaltet? (Hotel->Bar, Hotel->Museum, FashionStore->Bar->Club usw.)
(4) …

Anwendungsszenarien der interpretierbaren Rohdaten / Analysedaten können auch sein:
(1) Genauere Auswahl von Plakatplätzen in Städten
(2) Genauere Auswahl und Briefings von Promotiontrupps (Flyerverteilungen, Werbegeschenkeverteilungen)
(3) div. politische Analysen, pol. Trendanalysen
(4) Trendanalysen in Bezug auf Orte und Ortsverbindungen für Auf- und Abbau v. lokalen Geschäften
(5) Konkurrenzanalysen auf Locationbasis (hier: Sprache und Interaktionen)
(6) Möglichkeiten: Verkauftrigger / Lead- und Saleunterstützungen
(7) Kundengruppen: Interessensschwerpunktanalyse- und reportings (Freizeitverhalten u.a.)

An der Stelle bedanke ich mich bei Georg Grohs, Dr. Klaus Holthausen / Andrea Fetzer (Roland Berger), Lars Heinemann, Mitossi und Dirk Schumann für die treibende und kreative Beurteilung des Projektes.

InstaLOC-Projekt, Freigabe der Version 0.10 Beta

Ich habe soeben die Freigabe für die Versionsnummer 0.10Beta erteilt. Die entsprechende Datei befindet sich in dem – intern geteilten – Dropboxordner und trägt den Namen „insta_loc_15082018_010Beta.zip“.

Bedienungsanleitungsvideos:
InstaLoc-Forschungsprojekt/Software (Basisfunktionen – Likes): https://youtu.be/CkZSVPC8KJY
InstaLoc-Forschungsprojekt/Software (Basisfunktionen – Accountebene): https://youtu.be/VXPzhanL-vw
InstaLoc-Forschungsprojekt/Software (Filter: Tagwolkenanalyse, Locations): https://youtu.be/qh2bowhnMbI
InstaLoc-Forschungsprojekt/Software (Tagwolkenanalyse, Locations): https://youtu.be/5aefOGaGy-o
InstaLoc-Forschungsprojekt/Software (Tagwolkenanalyse): https://youtu.be/Ey9B6Skm9Y4

Wir vergeben an 2 besondere und ausgewählte Kolleg_innen jeweils eine Kopie der Auswertungssoftware und sind offen für entsprechende Gespräche, Anfragen und Nachfragen.