[PYTHON] Expérimentez pour collecter des tweets pendant une longue période (agrégation et confirmation du contenu)

Jusqu'à la dernière fois.

Essayez d'agréger par heure

Environ une semaine s'est écoulée pour le moment. Pour le moment, il semble fonctionner en toute sécurité. Ensuite, ce que je veux ensuite, c'est le nombre actuel d'entrées ou le total pour chaque heure.

>>> db.xxx.count()

Si vous le faites, vous pouvez voir que le nombre lui-même augmente, mais il est difficile de dire que quoi que ce soit est exact ... D'une manière ou d'une autre, il est nécessaire de l'amener au compte horaire des tweets.

Agréger avec MapReduce

Il semble qu'il existe plusieurs méthodes d'agrégation dans MongoDB, mais pour le moment, je vais essayer d'agréger avec MapReduce sur la base d'un "livre mince". ...... Je pense que c'est la première fois que je touche JavaScript, mais je suis googlé

check.js


db.xxxxx.mapReduce(
    // map
    function() {
    	
    	d = new Date(Date.parse(this.created_at) + 32400000);
    	p = d.getFullYear() + "/" + ("0" + (d.getMonth() + 1)).slice(-2) + "/" + ("0" + d.getDate()).slice(-2) + " " + ("0" + d.getHours()).slice(-2) + ":00:00"
        emit(
            p,
            1
        );
    },

    // reduce
    function(key, values) {
        return Array.sum(values)
    },

    {
        query: {},
        out: "TweetsCount"
    }
)

Comme ça. (Le format de date et d'heure de JavaScript n'est-il pas le seul moyen de le faire?)

# mongo localhost/TwitterDB check.js

Si vous l'exécutez de cette façon, le résultat sera stocké dans une autre Collection "TweetsCount".

(Extrait uniquement au point d'occurrence maximal)
{ "_id" : "2016/10/28 13:00:00", "value" : 67 }
{ "_id" : "2016/10/28 14:00:00", "value" : 47 }
{ "_id" : "2016/10/28 15:00:00", "value" : 102 }
{ "_id" : "2016/10/28 16:00:00", "value" : 103 }
{ "_id" : "2016/10/28 17:00:00", "value" : 2850 }
{ "_id" : "2016/10/28 18:00:00", "value" : 5317 }
{ "_id" : "2016/10/28 19:00:00", "value" : 4324 }

Il semble que cela puisse être pris pour le moment. N'est-ce pas petit dans l'ensemble? Je me sens comme ça, mais (j'ai l'impression d'avoir un pic d'un chiffre ... peut-être à cause de la clé de recherche) </ sub>. Ce niveau d'exécution ne semble pas être une charge importante. Il peut encore changer s'il est réglé pendant 100 jours ...

Vérifions le contenu de DB

Le programme d'acquisition en cours d'exécution ne produit rien sur la sortie standard à l'écran, vous ne pouvez donc pas vérifier ce qui a été stocké. Vous pouvez le voir en regardant directement MongoDB, mais vous ne connaissez pas le statut d'acquisition en temps réel, et si vous le regardez, il y a beaucoup d'éléments inutiles sur JSON, et franchement c'est difficile à voir.

D'une manière ou d'une autre, je veux un script qui puisse vérifier le contenu des tweets en temps réel (ou avec un suivi).

Il semble y avoir différents moyens, mais c'est rapide et pas exagéré, et si vous essayez de ne voir que ce que vous voulez voir, c'est comme ça (mise en œuvre environ 2h).

InsertChecker.py


#!/usr/bin/env python
# -*- coding:utf-8 -*-

from pymongo import MongoClient
import json

import time

#Variables liées à la connexion MongoDB
HOST = 'mongo'      #hôte
PORT = 27017            #Port(Défaut:27017)
DB_NAME = 'TwitterDB'   #Nom de la base de données
COL_NAME= 'xxxxxx'    #Nom de la collection


# ------Traitement principal d'ici------

try:
    Client = MongoClient(HOST, PORT)
    db = Client[DB_NAME]
    Collection = db[COL_NAME]
    print('DB prêt')
    
    twCnt = Collection.count()  #Obtenez le tout premier décompte
    
except pymongo.errors.PyMongoError as exc:
    #Erreur de connexion
    print('Erreur de connexion à la base de données')


while(True):        #boucle infinie
    try:
        
        if(Collection.count() > twCnt):
            for doc in Collection.find(skip=twCnt):
                
                if("retweeted_status" in doc):
                    if("extended_tweet" in doc["retweeted_status"]):
                        #RT longue phrase
                        print("RT @" + doc["retweeted_status"]["user"]["screen_name"] + ": " +doc["retweeted_status"]["extended_tweet"]["full_text"])
                    else:
                        #RT courte phrase
                        print("RT @" + doc["retweeted_status"]["user"]["screen_name"] + ": " +doc["retweeted_status"]["text"])
                else:
                    if("extended_tweet" in doc):
                        #Longue phrase
                        print(doc["extended_tweet"]["full_text"])
                    else:
                        #Courte phrase
                        print(doc["text"])
                
                print(u"{name}({screen}) {created} via {src}".format(name=doc["user"]["name"], screen=doc["user"]["screen_name"],
                    created=doc["created_at"], src=doc["source"]))
                print(u"--------------------------------------------------")
        
        twCnt = Collection.count()
        
        #L'intervalle de vérification est d'environ toutes les 3 secondes(Est-ce que ça va pendant 10 secondes en fonction de la vitesse d'écoulement?)
        time.sleep(3)
        
    except KeyboardInterrupt:
        # CTRL+C
        print('CTRL +Terminez par C.')
        ExitCode = 0
        break

(La notation de l'instruction print () au milieu a changé car le copier-coller à partir du matériau de référence est mélangé) C'est facile à faire, vérifiez régulièrement le nombre de collections, et s'il y en a plus, formatez et sortez le montant augmenté.

D'une manière ou d'une autre, Extension de la formulation des tweets En raison du changement de spécification, les éléments suivants se trouvent à l'étape intermédiaire Pour se ramifier en 4 modèles. ・ Tweets RT et modèles de tweets à spécification étendue (longs) ・ Tweets RT et modèles de tweet standard (courts) ・ Modèle de tweet du tweet normal et spécification étendue (longue phrase) ・ Modèle de tweet du tweet normal et spécification standard (phrase courte)

Après cela, affichez l'heure et affichez le nom d'utilisateur. Même s'il est tellement ultra adapté, il s'affichera comme "tail -f"! Merveilleux!

Remodelage mineur

Cela remplit toujours ce que je veux faire, mais c'est l'humanité qui me donne envie de rechercher la commodité.

Afficher le nombre de favoris et de RT

Combien sont les tweets qui sont RT réellement RT? Je pense que je le veux.

print("\n<RT: " + str(doc["retweeted_status"]["retweet_count"]) + " cnt, Fav: " + str(doc["retweeted_status"]["favorite_count"]) + "cnt >")

Insérez quelque chose comme ça dans la branche qui est affichée pendant RT (alignez les retraits). Vous pouvez voir qu'il compte à chaque fois que c'est RT.

Rendre l'affichage de l'heure plus facile à lire

L'affichage de l'heure dans JSON envoyé depuis Twitter est difficile à lire pour les Japonais, je l'ai donc modifié.

d = datetime.strptime(doc["created_at"],'%a %b %d %H:%M:%S +0000 %Y') + timedelta(hours=9)

Après la conversion au format datetime, modifiez l'emplacement de stockage de l'heure

created=d.strftime("%Y/%m/%d %H:%M:%S")

Si vous le remplacez ainsi, il sera terminé. N'oubliez pas "from datetime import datetime, timedelta".

Supprimer les balises HTML de l'affichage du nom du client

Il est possible d'afficher le type de client à partir duquel le tweet a été envoyé, mais c'est difficile à voir car cet élément et les balises HTML sont inclus, et les balises réelles sont incluses. Si vous activez l'expression régulière comme "import re" et faites quelque chose comme ça à l'endroit où doc ["source"] est spécifié, la balise disparaîtra étrangement.

src=re.sub("<.+?>", "", doc["source"])

(Il est possible qu'il n'y ait que des balises, mais cela fonctionne bien jusqu'à présent.)

Que faire ensuite (pas de plan)

Pour le moment, avec ça ・ Nombre de tweets par heure ・ Affichage des tweets acquis en temps réel

Peut maintenant être fait. Après tout, il est mentalement rassurant de voir les tweets couler correctement.

Le prochain objectif est ・ Extraction de tweets qui sont actuellement les plus RT ・ Statistiques d'utilisation du client Twitter ・ Extrayez le nom du magasin (en d'autres termes) </ sub> du tweet et mesurez le nombre de mentions. Est-ce là? J'essaierai de le faire de temps en temps.

(Continue avec insistance.)

Recommended Posts

Expérimentez pour collecter des tweets pendant une longue période (agrégation et confirmation du contenu)
Expérience de collecte de tweets pendant une longue période (préparation du programme (3))
Expérience pour collecter des tweets pendant une longue période (préparation du programme (1))
Expérience pour collecter des tweets pendant une longue période (préparation du programme (2))
Expérience pour collecter des tweets pendant une longue période (préparation du programme (5))
Expérimentez pour collecter des tweets pendant une longue période (juste avant l'exécution)
Mettre le processus en veille pendant un certain temps (secondes) ou plus en Python
[Python] Créer une liste de date et d'heure (type datetime) pour une certaine période
Une solution de contournement simple pour que les robots essaient de publier des tweets avec le même contenu
L'histoire du serveur Web et du DAG d'Airflow, dont le chargement prend beaucoup de temps
[Python] Créer une liste de dates et d'heures pour une période spécifiée
Expérimentez pour créer un PDF indépendant pour Kindle avec Python
Une méthode d'étude pour les débutants pour apprendre l'analyse des séries chronologiques
Je veux créer un Dockerfile pour le moment.