deenfritptrues

Breadcrumbs

Aus gegebenen Anlass hab ich mich mit ein paar Website Spiders bzw Crawler auseinander gesetzt und teile mal meine Erfahrung. :)

 

Ausgiebig gestest habe ich hauptsächlich Sphider-plus, Screaming Frog und Scrapy.

 

Fangen wir mit Sphider-Plus an.

Sphider-Plus basiert auf PHP und ist relativ leicht zu verstehen und schnell einsetzbar.

Sphider-Plus bietet neben dem Admin Panel auch eine User Frontpage, womit man gleich eine Suchseite für die gesammelten Daten hat.

Im Admin Panel kann man sehr viel einstellen und grundsätzlich ist es so, das PHP beim crawlen schon nicht die performanteste Variante ist, aber je mehr man anhakt und sammelt, desto langsamer wird das crawlen.

Dennoch verwende ich Sphider-Plus für manche Webseite ganz gerne. Vorallem für Webseiten die eine sitemap.xml zur Verfügung stellen.

Sphider Plus lässt sich auch sehr gut über die Commandline ausführen, womit man Skipte per Crontab einplanen kann.

 

 

Screaming Frog ist ein auf Java basiertes GUI Tool.

Extrem schnell, aber extrem Speicherhungrig.

Webseiten mit mehreren hunderttausend Unterseiten (zb. Videoportale etc) schaffte ich nicht mal mit 64 GB RAM vollständig zu crawlen.

Zu Beginn lief das crawlen bei mir mit etwa 200 Seiten pro Sekunde an. Wenn mal ca 500.000 Seiten im Speicher sind, fällt auch auch die Geschwindigkeit mal auch 20 Seiten pro Sekunde runter und wenn das OS mal zu swappen beginnt, ist es soweiso gleich mal ziemlich lahm. Selbst das pausieren kann ein Geduldspiel werden und man denkt, das Programm reagiert nicht mehr. ;)

Aber auch hier hat man sehr viele Einstell- und Filtermöglichkeiten. Auch über Commandline soll man Screaming Frog ausführen können, habe ich aber nicht getestet, weil man hier so gut wie keine Optionen mitgeben kann.

 

Scrapy ist das schnellte, sicherlich sehr mächtige, aber für mein Empfinden, komplizierteste Spider Tool.

Wenn man aber mal die Doku zumindest so halbwegs verstanden hat, etwas Programmierlogik versteht und alles im Web raus gegoogelt hat, was einem weiterhilft,  dann ist Scrapy für mich der Sieger dieser drei Tools.

Nicht nur das Scrapy permanent sehr schnell ist, bietet Scrapy auch die Möglichkeit, die Daten in einem JOBDIR zu verarbeiten, anstelle im Hauptspeicher.

Damit braucht man auch keine PC oder Server mit sehr viel Memory und dennoch kann man Millionen Webseiten innerhalb 24 Stunden damit abklappern.

 

Und weil Scrapy Beispiele recht rar sind, schreibe ich hier mal ein Beispiel wie ich es verwende.

Ich möchte dabei die URL, Webseiten Titel und die META Description auslesen und das nur von bestimmen "Ordnern" (zb: www.example.com/folder).

Wie man scrapy bedient und ein Projekt anlegt lasse ich hier aus. Dazu findest man genug im WWW.

 

 

example.py:


from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from scrapy.selector import Selector
from scrapy.item import Item, Field
from scrapy.exporters import CsvItemExporter

class myItem(Item):
    title = Field()
    url = Field()
    meta = Field()

class MySpider(CrawlSpider):
    name = "example"
    allowed_domains = ["www.example.com"]
    start_urls = ["https://www.example.com"]
    rules = (Rule(LxmlLinkExtractor(allow=('https://www.example.com/folder/')), callback='parse_obj', follow=True),)

    def parse_obj(self,response):
       item = myItem()
       item['url'] = []
       item['title'] = []
       for link in LxmlLinkExtractor(allow=(),deny = self.allowed_domains).extract_links(response):
                 item['url'].append(link.url)
                 hxs = Selector(response)
                 item['title'] = hxs.xpath('//title/text()').extract()
                 item['url'] = response.url
                 item['meta'] = hxs.xpath('//meta[@name=\'description\']/@content').extract()
                 return item

 

 

 

Ggf. noch ein JOBDIR Verzeichnis anlegen (zB: mkdir /tmp/example_jobdir)

 

Und schon könnte man mit zb: folgenden Befehlsaufruf loslegen:

scrapy crawl example -o example.csv -s JOBDIR=/tmp/example_jobdir

 

Statt .csv könnte man auch .json angeben.

In der CSV Datei werden URL, DESCRIPTION und TITEL mit einem Komma (,) separiert.

In der JSON Datei sie das dann so aus:

{"url": "https://www.example.com/folder/example.html", "meta": ["Hier steht die Meta Description."], "title": ["Hier steht der Titel der Webseite"]}

 

 

Wie man die Daten aus dem CSV oder JSON File dann weiterverarbeiten möchte, kann sich dann jeder überlegen.

Ich mache daraus SQL Statements und schreibe sie ein eine Tabelle in einer MySQL Datenbank.

 

Sphider-Plus verwendet ja schon eine MySQL DB. Hier kann man dann per SQL die Daten von Sphider-Plus weiterverarbeiten und ggf. in eigene Tabellen kopieren.

 

Mit Screaming Frog ist es ähnlich wie mit Scrapy. Hier kann man die Daten ebenfalls in eine CSV Datei exportieren und dann mit sed,awk,grep etc. so zusammenbauen, wie man es benötigt.

 

 

Hier eine NGINX/Ispconfig 3 Konfiguration die ich mit Googles Hilfe für ownCloud 9.1 zusammengebastelt habe.

 

Im Grunde hab ich es aus diesem Thread
https://www.howtoforge.com/community/threads/ispconfig-3-and-owncloud-nginx-ceontos-6-5-on-vps.68139/#post-324306

 

und mit den von ownCloud für ownCloud 9.1 angegebenen Parametern ergänzt.
https://doc.owncloud.org/server/9.1/admin_manual/installation/nginx_examples.html

 


------------
PHP Settings
------------
upload_max_filesize=20g
post_max_size=20g
always_populate_raw_post_data=-1
max_execution_time = 3600


----------------
nginx Directives
----------------

server_name mydomain.end;
if ($ssl_protocol = "") {
      rewrite ^/(.*) https://$server_name/$1 permanent;
}

add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;

        location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

location ~ \.php$ {
            try_files /b615814d8f2c19dbcb25b1fbae07ce38.htm @php2;
        }

    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

    location = /.well-known/carddav {
        return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
        return 301 $scheme://$host/remote.php/dav;
    }

    location /.well-known/acme-challenge { }

    # set max upload size
    client_max_body_size 20G;
    fastcgi_buffers 64 4K;

    # Disable gzip to avoid the removal of the ETag header
    gzip off;

    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    # pagespeed off;

    error_page 403 /core/templates/403.php;
    error_page 404 /core/templates/404.php;

    location / {
        rewrite ^ /index.php$uri;
    }

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        return 404;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        return 404;
    }

    location ~ ^(.+?\.php)(/.*)?$ {
                        try_files $1 =404;
                        include fastcgi_params;
                        fastcgi_param SCRIPT_FILENAME $document_root$1;
                        fastcgi_param PATH_INFO $2;
                        fastcgi_param HTTPS $https;
                        {FASTCGIPASS}
                        fastcgi_intercept_errors on;
                        fastcgi_index index.php;
                        fastcgi_buffers 64 64K;
                        fastcgi_buffer_size 256k;
                        fastcgi_param modHeadersAvailable true;
                        fastcgi_read_timeout 7200;
        }

    location @php2 {
                        fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
                        include fastcgi_params;
                        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                        fastcgi_param PATH_INFO $fastcgi_path_info;
                        fastcgi_param HTTPS $https;
                        {FASTCGIPASS}
                        fastcgi_intercept_errors on;
                        fastcgi_index index.php;
                        fastcgi_buffers 64 64K;
                        fastcgi_buffer_size 256k;
                        fastcgi_param modHeadersAvailable true;
                        fastcgi_read_timeout 7200;
        }

    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
        fastcgi_param front_controller_active true;
        #fastcgi_pass php-handler;
#fastcgi_pass unix:/var/run/hhvm/hhvm.sock;
    {FASTCGIPASS}
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    }

    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
        try_files $uri/ =404;
        index index.php;
    }

    # Adding the cache control header for js and css files
    # Make sure it is BELOW the PHP block
    location ~* \.(?:css|js)$ {
        try_files $uri /index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=7200";
        # Add headers to serve security related headers (It is intended to have those duplicated to the ones above)
        # Before enabling Strict-Transport-Security headers please read into this topic first.
        # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
        add_header X-Content-Type-Options nosniff;
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header X-Download-Options noopen;
        add_header X-Permitted-Cross-Domain-Policies none;
        # Optional: Don't log access to assets
        access_log off;
    }

    location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
        try_files $uri /index.php$uri$is_args$args;
        # Optional: Don't log access to other assets
        access_log off;
    }

location = /data/htaccesstest.txt {
  allow all;
  log_not_found off;
  access_log off;
}


Wir nutzen Cookies auf unserer Website. Einige von ihnen sind essenziell für den Betrieb der Seite, während andere uns helfen, diese Website und die Nutzererfahrung zu verbessern (Tracking Cookies). Sie können selbst entscheiden, ob Sie die Cookies zulassen möchten. Bitte beachten Sie, dass bei einer Ablehnung womöglich nicht mehr alle Funktionalitäten der Seite zur Verfügung stehen.