Tag: cpan

feed2twitter

Seit einiger Zeit nutze ich für ein paar Feeds ein Perlskript mit dessen Hilfe ich Feeds aus einem Blog im Twitter verlinke. Das Skript heisst originellerweise dann auch feed2twitter.pl . Das Skript wird von Hand über die Shell oder über Cron aufgerufen.

Ein Beispielaufruf könnte so aussehen:

   ./feed2twitter.pl --twitter=xwolf --feed=http://blog.xwolf.de/tag/piraten/feed/ --hashtag=piraten --quiet

Das Skript ließt dabei zunächst den Feed meines Blogs in der Kategorie “Piraten” ein. Danach nimmt es den Titel jedes Artikels und die URL um daraus eine Twitternachricht zu erzeugen. Die Nachricht wird dann auf meinen Twitteraccount gepostet.

Wenn Artikel und URL länger sind als 140 Zeichen, wird der Bestandteil des Titels optional gekürzt. Um zu verhindern, daß bei mehreren aufeinander folgenden Aufrufen über Cron dieselben Artikel nochmals getweetet werden, speichert das Skript ein Index aller bereits gesendeten Artikel ab.

Das Skript ist kann ab sofort bei Github heruntergeladen werden: https://github.com/xwolfde/feed2twitter

Zum Einsatz ist sehr wahrscheinlich die Nachinstallation des Perlmodules Net::Twitter::Lite notwendig. Ausserdem muss man die eigene Kopie des Skriptes bei https://dev.twitter.com/ registrieren um sich einen eigenen  API-Key, einen Consumer-key und den Consumer-Schlüssel zu besorgen.

Es ist möglich, unterschiedliche Feeds und unterschiedliche Twitter-Accounts zu nutzen. Ein möglicher Einsatzzweck des Skriptes wäre daher z.B. auch der, Artikel verschiedener Blogs oder mit RSS-publizierte Nachrichten abzurufen und über ein gemeinsamen Twitter-Account zu promoten.

 

Kommentare deaktiviert :, , , , , , Mehr...

Webseiten auslesen und importieren

Wer mehrere Webauftritte auf unterschiedlichen Plattformen betreibt, hat mitunter das Problem, das selbe Texte auf verschiedenen Auftritten stehen sollen. Diese möchte man aber natürlich nicht dauernd kopieren oder mehrfach pflegen.

Auf Basis der Perl-Module HTML::TreeBuilder und LWP::UserAgent hab ich daher ein Skript geschrieben, welches definierte Webseiten einließt und über ein SSI-Befehl dann in der jeweiligen Seite anzeigt: import-url.pl.

Das Skript besteht aus drei Teilen: Zuerst wird die Liste der auszulesenden URLs aus einer CSV-Datei eingelesen. Welche dieser URL eingebunden wird, liefert die ID, welche im Aufrufparameter des Skriptes liegt. Eine direkte Angabe der URL wäre zu gefährlich, da ansonsten Dritte beliebige URLs importieren könnten, bzw. die Webseite für ungewollte Webpipes ausnutzen könnten.
Im zweiten Teil wird über LWP die URL ausgelesen:

 	use LWP::UserAgent;
    	my $ua = LWP::UserAgent->new;
    	$ua->agent($CONST{'Agentname'});
    		# Create a request
    	my $req = HTTP::Request->new(GET => $url);
	    	# Pass request to the user agent and get a response back
    	my $res = $ua->request($req);
	    	# Check the outcome of the response
	my $plaincontent;
    	if ($res->is_success) {
      		$plaincontent = $res->content;
        } else {
       	 	return "No response";
        }

Der Inhalt wird dann mit HTML::TreeBuilder analysiert.
Die Webseiten, die ich betreibe haben eine klar definierte Semantik, in der der eigentlich Inhalt von einem <div id=”content”> … </div> umschlossen wird. Danach suche ich um alle Teile der Webseite wegzulassen, die bspw. Menu oder Metainformationen enthalten:

	use HTML::TreeBuilder;
	my $tree = HTML::TreeBuilder->new;
	$tree->no_space_compacting(1);
	$tree->parse($htmltext);
	$tree->eof;

	my $subpart;
	my $bereich = $tree->look_down('_tag', 'div',
		sub {
			return unless $_[0]->attr('id') =~ /content/;
		}
	)	;
	my $out = join  '', map(
		ref($_) ? $_->as_HTML(undef,undef,{}) : $_,
		$bereich->content_list
	);
	if (not $out) {
		$out=$bereich->as_HTML;
	}
	$tree->delete;

Die Variable $out enthält somit den Inhalt der Seite.
Wenn die Seite keine Bilder oder Links enthielte, wäre ich damit fertig. Diese muss ich aber noch anpassen.
Dazu suche ich in einer while()-Schleife und ein paar Regular Expressions einfach nach den Vorkommen von src=”" und href=”" innerhalb der HTML-Tags.
Das sieht dann im wesentlichen so aus (Beispiel nur für die Suche nach Links):

		while ($content =~ /href="([^"]+)"/i)  {
			$link =$1;
			$pre = $`;
			$post = $';

			if (($link =~ /^\//i)  && ($link !~ /^([a-z]+):\/\//i) && ($link !~ /^mailto/i)) {
				$link = "href=\"".$base.$link."\"";
			} elsif (($link !~ /$base/i) && ($link !~ /^([a-z]+):\/\//i) && ($link !~ /^mailto/i)) {
				$link = "href=\"".$uripath."/".$link."\"";
			} else {
				$link = "href=\"$link\"";
			}
			$content = $post;
			$tcontent .= "$pre$link";
		}
		$tcontent .= $content;

$content ist der HTML-Text, $content ist dabei das Ergebnis. Ausgehend von der ursprünglichen URL verfüge ich ausserdem über die beiden Variable $base und $uripath, welche die Adresse der Website und die URI der Seite enthalten.

Das Skript ließe sich nun noch leicht erweitern. Zum Beispiel über spezifische RegExp pro einzulesender URL oder auch um eine noch genauere Filterung des Inhaltes nach anderen Bereichen.

Kommentare deaktiviert :, , , Mehr...