Freitag, 11. März 2016

Zufällig durch das Internet browsen mit C#

In diesem Post möchte ich zeigen, wie man mit C# durch das Internet surft indem man zufälligen Links folgt. Dabei ist nicht nur einfach unheimlich interessant und aufschlussreich wo man nach ein paar Klicks landet, sondern dies hat auch eine praktische Anwendung: Zum Beispiel Googles Pagerank Algorithmus zur Bewertung der Popularität von Webseiten nutzt ein ähnliches Modell.

Das folgende C# Programm enthält ein Webbrowser Steuerelement und einen Button. Klickt der Benutzer auf den Button, durchsucht das Programm die aktuelle Webseite, sucht einen zufälligen Link aus und zeigt die Zielseite im Webbrowser an.
Der Code sollte relativ selbst erklärend sein: Die Klasse Browser behandelt das Suchen von neuen Links. Sie speichert die aktuelle Seite sowie den aktuellen Seitenquelltext. Wird die Methode GoNext() aufgerufen, ruft diese FindLink() auf, um einen zufälligen Link zu finden. Dafür wird eine zufällige Startposition im Quelltext der aktuellen Seite bestimmt (der Quelltext wird mit einem Webclient heruntergeladen) und ab da nach dem ersten Vorkommen eines HTML Links gesucht. Ich halte dieses Vorgehen für effizienter anstatt zuerst den kompletten Quellcode zu durchsuchen und danach einen zufälligen Link auszuwählen. Aber Achtung: Auf diese Weise werden bestimmte Links bevor- oder benachteiligt, da wir nicht mehr die tatsächliche Wahrscheinlichkeit der Links benutzen! Wir arbeiten nun mit einer Wahrscheinlichkeit über Zeichenketten, und da die Links höchstwahrscheinlich nicht gleichverteilt im Text sind (am Anfang gibt es zum Beispiel einen großen Header usw.), hat unsere Ziehung ein gewisses Bias.
Haben wir einen Link gefunden benutzen wir die Methode aus dem vorigen Post um ggf. relative Links in absolute umzuwandeln, und folgen diesem Link.
Das Programm funktioniert ist aber noch relativ rudimentär, es kann zum Beispiel in Sackgassen laufen etc., auch wie vorhin angemerkt ist die Linkauswahl nicht völlig zufällig. Ich poste es hier in der Form da ich denke dass es für eine Anwendung vom Benutzer eh noch stark personalisiert werden muss und die Anforderungen dafür stark schwanken.
Viel Spaß beim Ausprobieren und schreibt mir interessante Linkketten in die Kommentare!

Hier der Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;

namespace RandomSurfer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Browser B;

        private void Form1_Load(object sender, EventArgs e)
        {
            // start with some arbitrary page, here a random article on Wikipedia
            string StartPage = "https://de.wikipedia.org/wiki/Spezial:Zuf%C3%A4llige_Seite";
            B = new Browser(StartPage);
            webBrowser1.Navigate(StartPage);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate(B.GoNext());
        }
    }

    public class Browser
    {
        string CurrentPage; // stores url current website
        string CurrentContent; // stores content of current website

        public Browser(string Start)
        {
            CurrentPage = Start;
            CurrentContent = GetText(CurrentPage);
        }

        private string GetText(string url)
        {
            // use a webclient to download the source code of a website
            WebClient Webclient1 = new WebClient();
         
            Webclient1.Encoding = System.Text.Encoding.UTF8;
            string Content = ((Webclient1.DownloadString(url)));
            return (Content);
        }

        public string GoNext()
        {
            // randomly go to a new website
            CurrentPage = FindLink(); // for this find a random link
            CurrentContent = GetText(CurrentPage); // and for the next seach store the source code of the current webpage
            return CurrentPage;
        }

        private string FindLink()
        {
            // find a random link
            int Length = CurrentContent.Length;
            Random Rnd = new Random();
            int RndStart;
            int LinkStart = -1;
            int LinkEnd;
            string Link = "";

            // select a random starting point in the source code and find the first link after that
            // repeat if none find
            while (LinkStart == -1)
            {
                RndStart = Rnd.Next(Length);
                LinkStart = CurrentContent.IndexOf("a href=\"", RndStart);
            }

            // extract the link
            LinkEnd = CurrentContent.IndexOf("\"", LinkStart + 8);
            Link = CurrentContent.Substring(LinkStart + 8, LinkEnd - LinkStart - 8);

            // resolve its global url
            System.Uri Base = new System.Uri(CurrentPage);
            System.Uri ResolvedAbsoluteURL = new System.Uri(Base, Link);
            return ResolvedAbsoluteURL.ToString();
        }
    }
}

1 Kommentar:

  1. Der Kommentar wurde von einem Blog-Administrator entfernt.

    AntwortenLöschen