Das einfache Verarbeiten von Inhalten auf Internetseiten in der node.js Umgebung ist bequem mit dem Modul cheerio möglich. Hierbei läd man die Webseite wie gewohnt mit einem der verfügbaren HTTP Module. Injiziert nun zusätzlich die jQuery Bibliothek und läd den DOM in das jQuery Module. Ab diesem Punkt ist es möglich auf alle Elemente der Internetseite mit den gewohnten jQuery Funktionen zu bearbeiten bzw. Inhalte zu extrahieren.

Das Beispielskript sollte copy & paste funktionieren. 🙂

#!/usr/bin/env node
'use strict';
 
var http = require('http');
var cheerio = require('cheerio');
 
// socket timeout
var myTimeout = 100;
 
// on error
var err = function(e) {
	console.log(e)  
}
 
// used to set socket timeout
var timeout = function(socket) {
    socket.setTimeout(myTimeout);  
    socket.on('timeout', function() {
        req.abort();
    });
}
 
var req = http.get({host: 'example.com', port: 80, path: '/'}, function(res) {
 
    var html = '';
 
    // executed if part of data comes in
    res.on('data', function(data) {    
    	html += data;
 
    // executed if all data received
    }).on('end', function() {
 
        // check HTTP status / errors   	
	 console.log(res.statusCode);
 
	// load jquery (cheerio) to your received HTML document
	var $ = cheerio.load(html);
 
	// *** JQUERY LIKE CODE ***	  
	// use code like in browser
	$('h1').each(function() {
	    console.log($(this).text());
	});
     });
}).on('error', err).on('socket', timeout);

Alternativ kann natürlich auch ein synchroner HTTP Client verwendet werden.

Vorher die Installation des cheerio Moduls in der Shell nicht vergessen:

npm install cheerio
Keine Kommentare »
 

Nach längerer Blog Pause schreibe ich über die Implementierung eines Datei Upload mittels POST nach dem RFC1867. Das Vorgehen beim Datei Upload auf der Server Seite wird im Netz oft publiziert. Eine Beschreibung eines Upload Vorgang von der Client Seite aus findet jedoch wenig Verbreitung im Netz. Ich versuche meine Beschreibung möglichst allgemein zu halten. Desweiteren weiß ich das von der hier verwendeten Programmiersprache Ruby kaum Unterschiede zu Perl oder PHP bestehen. Alle genannten Sprachen bieten HTTP Client Funktionalitäten. Folgend ein Script und die Vorgehensweise nach RFC1867 im Detail.

#! /usr/bin/ruby
 
## HTTP Klasse einbinden
require 'net/http'
 
## Anfrageninstanz erstellen
http = Net::HTTP.new('example.com', 80)
 
## Das Timeout festlegen (So lange wartet das Script bis der Server nach einer Anfrage antwortet)
http.read_timeout = 100
 
## Eine zufällige Nummer die zum separieren des Anfragen Inhalts verwendet wird.
## Dieser String darf im Anfrage String vorkommen.
luckynumber = rand(9999999999).to_s();
 
## Die HTTP Header der Anfrage.
## Wichtig ist hierbei den Content-Type entsprechend zu setzen. (multipart/form-data; nicht www-urlencoded)
## luckynumber der Wert hinter boundary= ist hierbei die Variable die zur Trennung von Inhalten verwendet wird.
header = {
        'User-Agent' => 'Mozilla/5.0 (en-US) Gecko/20100303'
	'Content-Type' => 'multipart/form-data; boundary=luckynumber'+luckynumber
}
 
## Die Daten die an den Webserver gesendet werden.
## Der Platzhalter *Inhalt der Datei in dem nicht luckynumber123456789 vorkommt* muss durch deinen Datei Inhalt ersetzt werden.
## --luckynumber"+luckynumber wird als Seperator der Datei verwendet.
## Die Kopdaten der Datei, Dateiname und Dateicodierung, müssen mit zwei
## Umbrüchen (nn) vom Inhalt separiert werden.
data =
"--luckynumber"+luckynumber+"
Content-Disposition: form-data; name="Filedata"; filename="dateiname.txt"
Content-Type: text/plain
 
*Inhalt der Datei in dem nicht luckynumber123456789 vorkommt*
 
--luckynumber"+luckynumber+"--
" 
 
## Absenden der HTTP POST Dateiupload-Anfrage
resp = http.post('upload.php', data, header)
 
## Von der Anfrage erhalten wir die Angefragten Daten und
## einen Status Code. Ist der Status Code ungleich 200
## ist ein Fehler aufgetreten.
if resp.code != "200"
	puts '# An error has occurred...'
endif

Die Ruby interne Net/HTTP Klasse wird für die Socketarbeiten für das Script verwendet. Die Anfragen werden über diese Ruby standard Klasse versandt. Der im Kopf Bereich angegebene Separator (boundary=) darf nicht zufällig im String der Anfrage vorkommen.

Allgemein ist es wichtig die Anfrage multipart/form-data; Formatiert zu übertragen. Im Kopf Bereich der HTTP-Anfrage der gesandt wird ist dabei diese Zeichenkette ausschlaggebend:

Content-Type: multipart/form-data; boundary=luckynumber123456789

Bei den Daten in der Anfrage ist zu beachten das einzelne Werte mit Hilfe eines Strings separiert werden. Hier nochmals „luckynumber123456789“ als seperator.

--luckynumber123456789
Content-Disposition: form-data; name="Filedata"; filename="dateiname.txt"
Content-Type: text/plain
 
*Inhalt der Datei in dem nicht luckynumber123456789 vorkommt*
 
--luckynumber123456789--

Ein Plain-Text Beispiel für den Inhalt einer Anfrage-Zeichenkette. Die Content-Type Angabe übermittelt den Mime-Typ der Datei. Eine alphabetisch sorierte Liste der Mime-Typen findest du hier. Weitere HTTP Fehler Codes zum auswerten von HTTP-Response Codes findest du hinter diesem Link.

Viel Freude beim Dateien Uploaden nach RFC1867.

Keine Kommentare »