SliderBot

De Wikipast
Aller à la navigation Aller à la recherche

Objectifs

  • Crée une base de données en associant [Personne, Date, Lieu] via un scrapping de page.
  • Crée un ensemble de cartes affichant les positions de toutes les personnes recensées pour chaque date (discretisation par année ?).
  • Création d’un slider dynamique, où l’annee souhaitée est choisie, et affiche la carte correspondante (JavaScript ou HTML)

Description

Le bot extrait les données nécessaires de Wikipast, en parcourant chaque page existante d'années à travers le temps. Les informations retenues sont d'abord les mentions de villes et deuxièmement les mentions de personnes respectives pour chaque année. Ce travail est fait par un code python, qui va sauvegarder l'information dans un tableaux. Le tableaux va être utilisé pour afficher les villes qui ont été mentionné et les personnes respectives sur une carte, pour une année spécifique. Ceci va être appliquée pour chaque année existante dans la base de données de Wikipast pour créer une carte interactive dont on peut naviguer à travers le temps et l'espace et visualizer la distribution de personnes dans le globe.

Server

Node.js est une plateforme logicielle libre en JavaScript orientée vers les applications réseau qui doivent pouvoir monter en charge. Parmi les modules natifs de Node.js, on retrouve HTTP qui permet le développement de serveurs HTTP.

server.js

const express = require('express');
const app = express();

app.post('/', function(req, res){
    console.log('Post request received: ');
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    req.on('data', function (chunk) {
        var buffer = JSON.stringify(chunk);
        var data = getData(buffer); 
        console.log('GOT DATA : '+data);       
    });
    res.end(JSON.stringify({"data":0}));
});

app.get('/', function(req, res){
    console.log('Get request received: ');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    console.log(req);
    res.end(JSON.stringify({"data": 0}));
});

app.listen(3000, () => {
    console.log('Server listening on port 3000!');
});

function getData(buffer){
    var array = buffer.substr(buffer.indexOf("data")+7, buffer.length);
    var final = array.substr(0, array.indexOf(']'));
    var ascii = final.split(',');
    var dec = "";
    for(var i = 0; i < ascii.length; i++){
        dec += String.fromCharCode(parseInt(ascii[i]));
    }
    return dec;
}

communication.js

var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var IP_ADDRESSE = "128.179.178.60";
var PORT = "3000";

function sendReq(){
    var request = new XMLHttpRequest();
    request.open('POST', 'http://'+IP_ADDRESSE+':'+PORT, true);
    request.setRequestHeader("Content-type", "application/json");
    request.onload = () => {
      if (request.status >= 200 && request.status < 400) {
        const res = JSON.parse(request.responseText);
        console.log(res);
      } else {
        console.log("Error on server side.")
      }
    };
    request.onerror = () => {
        console.log("Error on communication.");
    };
    request.send(JSON.stringify({"year":1996}));
}   

sendReq();

Extraction de données

BeautifulSoup est une librairie Python pour extraire des données de fichiers HTML ou XML

bot.py

from urllib.request import urlopen
from bs4 import BeautifulSoup
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# oldest year found : 1765
# isnumeric() pour détecter si la date est bien récupéree

response=urlopen("http://wikipast.epfl.ch/wikipast/index.php/1963")
page_source=response.read()
soup=BeautifulSoup(page_source,'html.parser')
stringSoup = str(soup)

def getNthDiv(stringSoup, n):
    divStart = stringSoup[stringSoup.index("mw-content-ltr") + len("mw-content-ltr"):]
    for i in range(n):
        try:
            nextIndex = divStart.index("<li")
        except ValueError:
            return None
        divStart = divStart[nextIndex + len("<li"):]
    return divStart

def getYearAndCity(div):
    tagDate = div[div.index("<a"):div.index("</a>")]
    date = tagDate[tagDate.index(">") + 1:]
    year = date.split(".")[0]
    if not year.isnumeric():
        return
    if div[div.index("</a>") + 7] == '-':
        return
    else:
        skipDate = div[div.index("<a")+ 2:]
        tagCityStart = skipDate[skipDate.index("<a"):]
        tagCity = tagCityStart[:tagCityStart.index("</a>")]
        city = tagCity[tagCity.index(">") + 1:]
        return (year, city)

def printTuples(tuples):
    for tuple in tuples:
        print(tuple[0]+" : "+tuple[1])

def tuplesWithMultiplicity(yearCityList):
    tuples = []
    for i in range(0, len(yearCityList)):
        compte = yearCityList.count(yearCityList[i])
        tuples.append((yearCityList[i], compte))
    return [list(item) for item in set(tuple(row) for row in tuples)]

def printBigTuples(tuples):
    for tuple in tuples:
        print(tuple[0][0], tuple[0][1], tuple[1])

counter = 1
divDate = getNthDiv(stringSoup, counter)
yearCityList = []
while divDate != None:
    element = getYearAndCity(divDate)
    if element is not None:
        yearCityList.append(element)
    counter += 1
    divDate = getNthDiv(stringSoup, counter)

#printTuples(yearCityList)
printBigTuples(tuplesWithMultiplicity(yearCityList))

Placement sur la carte

Groupe

Nom et Prénom Pseudo
Guhennec Paul
Wildi Maël
Etienne Bonvin
Mathilde Raynal
Stefano Politi