German (Deutsch) translation by Wei Zhang (you can also view the original English article)

Einführung
Willkommen in der neuesten Folge unserer Twitter API-Serie. In unserer letzten Episode habe ich Twixxr.com gebaut, mit dem du einflussreiche Frauen auf Twitter entdecken kannst, damit dein Konto folgen kann. Heute werde ich den Fokus nach innen richten, um meine eigenen Anhänger zu betrachten.
Während ich Facebook seit 2013 nicht wirklich genutzt habe, bin ich auf Twitter aktiv geblieben - selbst als sie meinen Feed mit Werbung pumpten und mich ärgerten, indem ich versuchte, sie algorithmisch zu optimieren.
Vor kurzem wurde ich verifiziert und fing an, Anhänger in einer etwas schnelleren Rate zu sammeln. Ich hatte die Hoffnung, dass ich mehr Antworten auf meine Tweets sehen würde. Im Allgemeinen war ich überrascht, wie wenig Reaktion normalerweise auf Twitter für die durchschnittliche Person ist.

Ich habe fast 1.900 Anhänger, aber selten kommentieren oder retweeten die Stücke, die ich für wichtig und von allgemeinem Interesse halte. Zum Beispiel teilte keine einzige Person mein Stück über die scharfe Spitze der Vergewaltigungsberichte in Seattle oder den Kommentar zu Bill Gates in seiner unverschämt scheinheiligsten Art.
Lange wollte ich mir meine Twitter-Follower genauer ansehen und einige Fragen beantworten: Wer genau folgt mir? Und warum sind sie nicht interaktiver? Ist es möglich, dass nur 10% meiner Anhänger echte Menschen sind?
Twitter hat Probleme, einen Käufer zu finden, und vielleicht hat das etwas damit zu tun.
Die Twitter-API ist ein gutes Werkzeug, um dies zu untersuchen. Aber es hat eine Menge Ratenbegrenzungen, die sogar etwas so einfaches wie die Analyse Ihrer Follower ziemlich komplex machen. In der heutigen Folge zeige ich Ihnen, wie ich mit den Grenzwerten gearbeitet habe, um eine Anzeigetafel meiner Anhänger zu bewerten und zu erstellen.
Wenn Sie Fragen oder Feedback haben, bitte posten Sie sie unten in den Kommentaren oder erreichen Sie mich auf Twitter @reifman.
Analysieren Sie unsere Twitter Follower

Direkt darüber kannst du die grundlegende Anzeigetafel sehen, die ich erstellt habe. Die heutige Folge wird sich hauptsächlich auf die Infrastruktur und den Ansatz konzentrieren, den ich für die Erstellung dieses Themas verwendet habe. Ich hoffe, dass ich eine Chance bekomme, mehr über die Verbesserung des Punktemechanismus zu schreiben.
Und ja, wie Sie oben sehen können, folgt der bekannte Gay-Rights-Führer und Sex-Rat-Kolumnist Dan Savage mir, aber rettet nie etwas, das ich teile. Wenn heute Zeit ist, analysieren wir dies, um wichtige Fragen zu beantworten, wie zum Beispiel: Ist er echt, ein Bot, oder folge ich einfach nur meinem persönlichen Sex-Ratschlag? Was können wir aus seinem Bericht lernen, um festzustellen, ob er wahrscheinlich jemals mit mir auf Twitter oder mit anderen meinen Followern interagiert?
Der Scoreboard-Code ist hauptsächlich ein Prototyp, den ich auf den Twixxr-Code der letzten Episode gebaut habe, aber es ist keine Live-Demo für Leute, die es benutzen. Ich teile es, damit du daraus lernen und darauf aufbauen kannst.
Hier sind die grundlegenden Elemente des Codes:
- Erstellen der Datenbank zum Speichern meiner Follower und verwandter Daten
- Laden Sie meine Follower auf Seiten mit je 20 Followern herunter.
- Tracking der Cursor für die Seiten, während ich 15 Seiten pro Rate-limited-Fenster herunterladen.
- Speichern von gesammelten Daten über meine Follower in der Datenbank.
- Erstellen eines Prototyp-Scoring-Algorithmus, um alle Follower zu bewerten.
- Erstellen einer Ansicht zum Durchsuchen der Anzeigetafel.
Tauchen in den Code ein
Erstellen der Datenbanktabellenmigrationen
Ich habe drei verschiedene Tabellen erstellt, um alle Daten zu speichern und mir dabei zu helfen, mit der Twitter-API-Ratenbegrenzung zu arbeiten. Wenn Sie mit Yii-Datenbankmigrationen nicht vertraut sind, lesen Sie bitte Wie Sie mit Yii2 programmieren: Mit der Datenbank und dem aktiven Datensatz arbeiten.
Zuerst habe ich die SocialProfile-Tabelle erweitert, um viel mehr Daten von den Follower-Accounts zu erfassen, z. B. ob sie verifiziert sind, ihren Standort und wie viele Artikel sie bevorzugt haben:
<?php use yii\db\Schema; use yii\db\Migration; class m161026_221130_extend_social_profile_table extends Migration { public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->addColumn('{{%social_profile}}','social_id',Schema::TYPE_STRING.' NOT NULL'); $this->addColumn('{{%social_profile}}','name','string NOT NULL'); $this->addColumn('{{%social_profile}}','screen_name',Schema::TYPE_STRING.' NOT NULL'); $this->addColumn('{{%social_profile}}','description',Schema::TYPE_TEXT.' NOT NULL'); $this->addColumn('{{%social_profile}}','url',Schema::TYPE_STRING.' NOT NULL'); $this->addColumn('{{%social_profile}}','protected',Schema::TYPE_SMALLINT. ' NOT NULL DEFAULT 0'); $this->addColumn('{{%social_profile}}','favourites_count',Schema::TYPE_BIGINT. ' NOT NULL DEFAULT 0'); $this->addColumn('{{%social_profile}}','verified',Schema::TYPE_SMALLINT. ' NOT NULL DEFAULT 0'); $this->addColumn('{{%social_profile}}','location',Schema::TYPE_STRING.' NOT NULL'); $this->addColumn('{{%social_profile}}','profile_location',Schema::TYPE_STRING.' NOT NULL'); $this->addColumn('{{%social_profile}}','score',Schema::TYPE_BIGINT. ' NOT NULL DEFAULT 0'); }
Dann habe ich eine Indextabelle namens SocialFriend
erstellt, um Follower für bestimmte Accounts zu verfolgen. Wenn ich mich entscheide, diesen Service öffentlich zu formalisieren, brauche ich das. Er verknüpft die Tabelle Benutzer mit den Followern des Benutzers in der Tabelle SocialProfile.
<?php use yii\db\Schema; use yii\db\Migration; class m161026_233916_create_social_friend_table extends Migration { public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->createTable('{{%social_friend}}', [ 'id' => Schema::TYPE_PK, 'user_id' => Schema::TYPE_BIGINT.' NOT NULL', 'social_profile_id' => Schema::TYPE_BIGINT.' NOT NULL', ], $tableOptions); }
Als Nächstes erfordert die Twitter-API, dass Sie Anforderungen von jeweils 20 Follower gleichzeitig durchblättern. Um die nächste Seite zu kennen, müssen Sie die Cursor verfolgen, im Wesentlichen Tags, die die nächste Seite markieren, die abgerufen werden soll.
Da Sie alle 15 Minuten nur 15 Anfragen für Follower stellen dürfen, müssen Sie diese Cursor in der Datenbank speichern. Die Tabelle heißt SocialCursor
:
<?php use yii\db\Schema; use yii\db\Migration; class m161027_001026_social_cursor_table extends Migration { public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->createTable('{{%social_cursor}}', [ 'id' => Schema::TYPE_PK, 'user_id' => Schema::TYPE_BIGINT.' NOT NULL', 'next_cursor' => Schema::TYPE_STRING.' NOT NULL', ], $tableOptions); }
Schließlich werde ich Hintergrund-Cron-Aufgaben erstellen, um all das zu verwalten, aber für den heutigen Prototyp führe ich diese Aufgaben von Hand aus.
Sammeln der Follower und ihrer Kontodaten
Als nächstes habe ich eine Methode Twitter::getFollowers()
erstellt, um die Anfrage zu stellen. Hier sind die Grundlagen des Codes:
public function getFollowers($user_id) { $sp = new SocialProfile(); $next_cursor = SocialCursor::getCursor($user_id); ... while ($next_cursor>0) { $followers = $this->connection->get("followers/list",['cursor'=>$next_cursor]); if ($this->connection->getLastHttpCode() != 200) { var_dump($this->connection); exit; } if (isset($followers->users)) { foreach ($followers->users as $u) { $n+=1; $users[]=$u; $sp->add($user_id,$u); } $next_cursor= $followers->next_cursor; SocialCursor::refreshCursor($user_id,$next_cursor); echo $next_cursor.'<br />'; echo '======================================================<br />'; } else { exit; } }
Er ruft den next_cursor
ab und fragt wiederholt nach Followern, $followers=$this->connection->get("followers/list",['cursor'=>$next_cursor])
, bis er die Ratengrenzen erreicht.
Die Ausgabe sieht ungefähr so aus, als würde sie jede Seite mit 20 Ergebnissen durchlaufen:
refresh cursor: 1489380833827620370 ====================================================== refresh cursor: 1488086367811119559 ====================================================== refresh cursor: 1486452899268510188 ====================================================== refresh cursor: 1485593015909209633 ====================================================== refresh cursor: 1485330282069552137 ====================================================== refresh cursor: 1485256983607000799 ====================================================== refresh cursor: 1484594012550322889 ====================================================== refresh cursor: 1483359799854574028 ====================================================== refresh cursor: 1481615590678791493 ====================================================== refresh cursor: 1478424827838161031 ====================================================== refresh cursor: 1477449626282716582 ====================================================== refresh cursor: 1475751176809638917 ====================================================== refresh cursor: 1473539961706830585 ====================================================== refresh cursor: 1471375035531579849 ======================================================
Die Daten werden von diesen $sp->add($ user_id,$u);
gespeichert; Methoden. Die Methode SocialProfile::add()
ist eine andere Version der Methode fill()
aus dem Twixxr-Lernprogramm. Es speichert mehr Daten und verwaltet den SocialFriend-Index:
public static function add($user_id,$profileObject=null) { $sp = SocialProfile::find() ->where(['social_id'=>$profileObject->id_str]) ->one(); if (!isset($profileObject->name) || empty($profileObject->name)) { $profileObject->name='Nameless'; } if (!isset($profileObject->url) || empty($profileObject->url)) { $profileObject->url=''; } if (!isset($profileObject->screen_name) || empty($profileObject->screen_name)) { $profileObject->screen_name='error_sn'; } if (!isset($profileObject->description) || empty($profileObject->description)) { $profileObject->description='(empty)'; } if (!isset($profileObject->profile_location) || empty($profileObject->profile_location)) { $profileObject->profile_location=''; } if (!isset($profileObject->profile_image_url_https) || empty($profileObject->profile_image_url_https)) { $profileObject->profile_image_url_https=''; } if (!is_null($sp)) { $sp->social_id = $profileObject->id; $sp->image_url = $profileObject->profile_image_url_https; $sp->follower_count= $profileObject->followers_count; $sp->status_count = $profileObject->statuses_count; $sp->friend_count = $profileObject->friends_count; $sp->listed_in = $profileObject->listed_count; $sp->url=$profileObject->url; if ($profileObject->protected) { $sp->protected=1; } else { $sp->protected=0; } if ($profileObject->verified) { $sp->verified=1; } else { $sp->verified=0; } $sp->favourites_count=$profileObject->favourites_count; $sp->location=$profileObject->location; $sp->profile_location=$profileObject->profile_location; $sp->name = $profileObject->name; $sp->description = $profileObject->description; $sp->image_url = $profileObject->profile_image_url_https; if ($sp->validate()) { $sp->update(); } else { var_dump($sp->getErrors()); } } else { $sp = new SocialProfile(); $sp->social_id = $profileObject->id; $sp->score = 0; $sp->header_url=''; $sp->url=$profileObject->url; $sp->favourites_count=$profileObject->favourites_count; if ($profileObject->protected) { $sp->protected=1; } else { $sp->protected=0; } if ($profileObject->verified) { $sp->verified=1; } else { $sp->verified=0; } $sp->location=$profileObject->location; $sp->profile_location=$profileObject->profile_location; $sp->name = $profileObject->name; $sp->description = $profileObject->description; $sp->screen_name = $profileObject->screen_name; $sp->image_url = $profileObject->profile_image_url_https; $sp->follower_count= $profileObject->followers_count; $sp->status_count = $profileObject->statuses_count; $sp->friend_count = $profileObject->friends_count; $sp->listed_in = $profileObject->listed_count; if ($sp->validate()) { $sp->save(); } else { var_dump($sp->getErrors()); } } $sf = SocialFriend::find() ->where(['social_profile_id'=>$sp->id]) ->andWhere(['user_id'=>$user_id]) ->one(); if (is_null($sf)) { $sf = new SocialFriend(); $sf->user_id = $user_id; $sf->social_profile_id = $sp->id; $sf->save(); } return $sp->id; }
Es wurde geschrieben, um neue Datensätze zu speichern oder alte Datensätze zu aktualisieren, so dass Sie in Zukunft Ihre Follower-Daten verfolgen und diese regelmäßig aktualisieren und alte Daten überschreiben können.
Dieser letzte Abschnitt am Ende stellt sicher, dass ein SocialFriend-Index zwischen der Benutzertabelle und der Tabelle SocialProfile vorhanden ist.
$sf = SocialFriend::find() ->where(['social_profile_id'=>$sp->id]) ->andWhere(['user_id'=>$user_id]) ->one(); if (is_null($sf)) { $sf = new SocialFriend(); $sf->user_id = $user_id; $sf->social_profile_id = $sp->id; $sf->save(); }
Twitter Follower zu zählen

Ich hatte eine Handvoll Ziele für mein Twitter-Scoring:
- Eliminiere Accounts, die jedem folgen, der ihnen folgt. Zum Beispiel haben sie 12.548 Anhänger und folgen 12.392 Menschen (siehe oben).
- Eliminiere Accounts, die mehr als 1.500 Accounts folgen, die wahrscheinlich nie sehen werden, was ich teile. Zum Beispiel folgt Dan Savage 1.536 Menschen.
- Beseitigen Sie Konten mit sehr wenigen Posts oder sehr wenigen Konten, die sie wahrscheinlich verlassen haben.
- Beseitigen Sie Konten mit wenigen Favoriten - das sind wahrscheinlich Bots, die die App nicht wirklich nutzen.
Ebenso möchte ich einige positive Aspekte hervorheben:
- Konten, die überprüft werden
- Konten, die viele Follower haben
- Konten, die weniger als 1.000 Personen haben, denen sie folgen - ein guter Punkt für mich
Hier ist ein grober grundlegender Code von SocialProfile ::score()
, der einige der positiven Aspekte hervorhebt:
foreach ($all as $sp) { // score sp $score =0; // RULE IN if ($sp->verified==1) { $score+=1000; } // POSITIVE if ($sp->protected==1) { $score+=500; } if ($sp->follower_count > 10000) { $score+=500; } else if ($sp->follower_count > 3500) { $score+=750; } else if ($sp->follower_count > 1100) { $score+=1000; } else if ($sp->follower_count > 1000) { $score+=250; } else if ($sp->follower_count> 500) { $score+=250; }
Hier ist ein Code, der einige der fehlerhaften Konten entfernt:
// RULE OUT // make this a percentage of magnitude $magnitude = $sp->follower_count/1000; if ($sp->follower_count> 1000 and abs($sp->follower_count-$sp->friend_count)<$magnitude) { $score-=2500; } if ($sp->friend_count > 7500) { $score-=10000; } else if ($sp->friend_count > 5000) { $score-=5000; } else if ($sp->friend_count > 2500) { $score-=2500; }else if ($sp->friend_count > 2000) { $score-=2000; } else if ($sp->friend_count > 1000) { $score-=250; } else if ($sp->friend_count > 750) { $score-=100; } if ($sp->follower_count<100) { $score-=1000; } if ($sp->status_count < 35) { $score-=5000; }
Offensichtlich gibt es hier eine Menge zu spielen und eine Vielzahl von Möglichkeiten, dies zu verbessern. Ich hoffe, ich bekomme eine Chance, mehr Zeit dafür zu haben.
Wenn die Methode ausgeführt wird, sieht das so aus, aktualisiert jedoch die Tabelle "SocialProfile" mit den Scores:
DJMany -6300 gai_ltau -7850 Michal92B -900 InvestmentAdvsr -2900 TSSStweets -7500 sandcageapp -1750 dominicpouzin 1950 daletdykaaolch1 -7850 suzamack -8250 writingthrulife -7500 ryvr -1550 RichardAngwin -8300 DanielleMorrill -7300 ReversaCreates 2750 BoKnowsMarkting -7500 TheHMProA -8500 HouseMgmt101 750 itsmeKennethG -1250 drbobbiwegner -8500 Mizzfit_Bianca -7300 wilsonmar 700 CoachVibeke -7300 jhurwitz 0 PiedPiperComms 500 Prana2thePeople -1100 singlemomspower -2250 mouselink -7300 MotivatedGenY -7300 brett7three -7300 JovanWalker 2950 ITSPmagazine 450 RL_Miller -2250
Anzeige des Anzeigers
Das Standardraster von Yii macht es sehr einfach, die Tabelle SocialProfile anzuzeigen und die Spalten der Anzeigetafeln anzupassen.
Hier ist SocialProfileController::actionIndex ()
:
/** * Lists all SocialProfile models. * @return mixed */ public function actionIndex() { $searchModel = new SocialProfileSearch(); $dataProvider = $searchModel->search(Yii::$app->request->queryParams); return $this->render('index', [ 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, ]); }
Und hier ist die Rasteransicht angepasst:
<?php use yii\helpers\Html; use yii\grid\GridView; use yii\widgets\Pjax; /* @var $this yii\web\View */ /* @var $searchModel frontend\models\SocialProfileSearch */ /* @var $dataProvider yii\data\ActiveDataProvider */ $this->title = Yii::t('frontend', 'Social Profiles'); $this->params['breadcrumbs'][] = $this->title; ?> <div class="social-profile-index"> <h1><?= Html::encode($this->title) ?></h1> <?php // echo $this->render('_search', ['model' => $searchModel]); ?> <?php Pjax::begin(); ?> <?= GridView::widget([ 'dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], [ 'label'=>'Name', 'format' => 'raw', 'value' => function ($model) { return '<div><span><strong><a href="http://twitter.com/'.$model->screen_name.'">'.$model->name.'</a></strong><br />'.$model->screen_name.'</span></div>'; }, ], 'score', [ 'label'=>'Follows', 'format' => 'raw', 'attribute'=>'friend_count', ], [ 'label'=>'Followers', 'format' => 'raw', 'attribute'=>'follower_count', ], [ 'label'=>'Tweets', 'format' => 'raw', 'attribute'=>'status_count', ], [ 'label'=>'Favs', 'format' => 'raw', 'attribute'=>'favourites_count', ], [ 'label'=>'Listed', 'format' => 'raw', 'attribute'=>'listed_in', ], [ 'label'=>'P', 'format' => 'raw', 'attribute'=>'protected', ], [ 'label'=>'V', 'format' => 'raw', 'attribute'=>'verified', ], // 'location', // 'profile_location', [ //'contentOptions' => ['class' => 'col-lg-11 col-xs-10'], 'label'=>'Pic', 'format' => 'raw', 'value' => function ($model) { return '<div><span><img src="'.$model->image_url.'"></span></div>'; }, ], ], ]); ?> <?php Pjax::end(); ?></div>
So sehen die Top-Scores mit meinem ursprünglichen Algorithmus aus:

Es gibt so viele Möglichkeiten, das Scoring zu verbessern und zu optimieren. Ich freue mich darauf, mehr damit zu spielen.
Darüber hinaus möchte ich Code schreiben und meine Nutzung der API erweitern, zum Beispiel:
- Verwenden Sie PHP Gender, um Unternehmen von Personen zu eliminieren (Unternehmen interagieren nicht viel).
- Schlage die Häufigkeit von Posts nach, die Leute gemacht haben und das letzte Mal, als sie Twitter benutzt haben.
- Verwenden Sie die Such-API von Twitter, um zu sehen, welche Follower tatsächlich jemals mit meinen Inhalten interagiert haben.
- Geben Sie der Bewertung Feedback, um sie abzustimmen.
Vorausschauen
Ich hoffe, Sie finden den Scoring-Ansatz faszinierend. Es gibt so viel mehr, was getan werden kann, um dies zu verbessern. Bitte fühlen Sie sich frei, damit zu spielen und Ihre Ideen unten zu posten.
Wenn Sie Fragen oder Anregungen haben, schreiben Sie diese bitte in die Kommentare. Wenn Sie mit meinen zukünftigen Envato Tuts + Tutorials und anderen Serien fortfahren möchten, besuchen Sie bitte meine Instructor-Seite oder folgen Sie @reifman. Sehen Sie sich auf jeden Fall meine Startup-Serie und den Meeting Planner an.
verwandte Links
- Twixxr (aktuelle Beispiel Twitter API App um einflussreiche Frauen zu entdecken)
- Twitter Entwickler Dokumentation
- So programmieren Sie mit der Yii2-Serie (Envato Tuts +)
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post