<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Apache Nutch &#8211; Smals Research</title>
	<atom:link href="https://www.smalsresearch.be/tag/apache-nutch/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.smalsresearch.be</link>
	<description></description>
	<lastBuildDate>Thu, 09 Apr 2026 12:12:11 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.smalsresearch.be/wp-content/uploads/2026/01/cropped-cropped-Smals_Research-32x32.png</url>
	<title>Apache Nutch &#8211; Smals Research</title>
	<link>https://www.smalsresearch.be</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Doorzoek je interne websites met Nutch</title>
		<link>https://www.smalsresearch.be/doorzoek-je-interne-websites-met-nutch/</link>
		
		<dc:creator><![CDATA[Bob Lannoy]]></dc:creator>
		<pubDate>Mon, 11 Mar 2013 09:16:53 +0000</pubDate>
				<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Apache Nutch]]></category>
		<category><![CDATA[enterprise search]]></category>
		<category><![CDATA[Information management]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[solr]]></category>
		<guid isPermaLink="false">/?p=5218</guid>

					<description><![CDATA[In een grotere organisatie heb je wel meerdere teams die een eigen website/wiki hebben naast het klassieke intranet. Vaak is dit niet geïntegreerd, terwijl dit een interessante bron van informatie kan zijn. Zoekmachines zijn de methode bij uitstek om disparate bronnen samen te brengen en doorzoekbaar te maken zonder alle sites samen te brengen op [&#8230;]]]></description>
										<content:encoded><![CDATA[<div>
<p><a href="/?attachment_id=5358" rel="attachment wp-att-5358"><img decoding="async" class="alignright size-full wp-image-5358" alt="nutch_logo_tm" src="/wp-content/uploads/2013/02/nutch_logo_tm.gif" width="210" height="83" /></a>In een grotere organisatie heb je wel meerdere teams die een eigen website/wiki hebben naast het klassieke intranet. Vaak is dit niet geïntegreerd, terwijl dit een interessante bron van informatie kan zijn. Zoekmachines zijn de methode bij uitstek om disparate bronnen samen te brengen en doorzoekbaar te maken zonder alle sites samen te brengen op één platform.</p>
</div>
<div>
<p>In de open source wereld zijn Apache <a href="https://lucene.apache.org" target="_blank">Lucene</a> en <a href="https://lucene.apache.org/solr/" target="_blank">Solr</a> de vaakst genoemde oplossingen om een zoekmachine te bouwen. Het probleem is dat deze geen &#8216;web crawler&#8217; bevatten, namelijk een systeem dat webpagina&#8217;s opvraagt, de inhoud indexeert en de aanwezige links op hun beurt verwerkt, net zoals Google doet. <a href="https://nutch.apache.org" target="_blank">Apache Nutch</a> is een zusterproject van Lucene dat zich op dit terrein waagt, namelijk een &#8220;Google&#8221; voor intern gebruik. In deze post gaan we eens kijken hoe je Nutch opzet en gebruikt. Merk op dat dit een technische uitleg zal zijn.</p>
</div>
<h1>Voorbereiding</h1>
<div>Nutch bestaat al sinds 2005 als Apache project en bestaat momenteel in twee versies: 1.6 (de stabiele versie waar er nog releases op gebeuren) en 2.1 (een vernieuwde versie met ondersteuning voor NoSQL backends). Voor de tests heb ik gekozen voor de laatste versie (2.1). Het eerste wat opvalt is het gebrek aan goede documentatie voor de 2.x reeks. Er zijn wat startpunten (<a href="https://wiki.apache.org/nutch/Nutch2Tutorial" target="_blank">Nutch op HBase</a> en op <a href="https://nlp.solutions.asia/?p=180" target="_blank">MySQL</a>) maar vaak ben je toch aangewezen op forums en blogposts van anderen.</div>
<div>Al snel bleek dat het opzetten niet zo evident was aangezien de onderliggende database tijdens het crawlen crashte. Na pogingen met HBase, MySQL en Cassandra, is het uiteindelijk toch gelukt met HBase, nadat de onderliggende machine genoeg RAM geheugen had gekregen (6GB in dit geval). Let op dat je niet de laatste versie gebruikt van HBase maar een versie die compatibel is met Nutch, zoals de versie 0.90.6.</div>
<div>Nutch zal volgende stappen doorlopen bij een eerste crawl:</div>
<div>
<ul>
<li>initiële URL&#8217;s worden aan Nutch gegeven, bijv. de lijst met websites die je wenst te indexeren (<em>inject</em>)</li>
<li>en dan doorloopt Nutch een aantal maal het proces (dit wordt de <em>depth</em> genoemd)</li>
</ul>
</div>
<div>
<ul>
<ul>
<li>generatie van lijst van URLs die moet behandeld worden (g<em>enerate</em>)</li>
<li>pagina&#8217;s ophalen (f<em>etch</em>)</li>
<li>inhoud van de pagina&#8217;s verwerken (p<em>arse</em>). Hierbij kunnen zowel gewone html pagina&#8217;s geïndexeerd worden als documenten (PDF, DOC, &#8230;)</li>
<li>de Nutch DB update (<em>updatedb</em>)</li>
<li>opslag van de resultaten in Solr (<em>solrindex</em>)</li>
</ul>
</ul>
<p><a href="https://techvineyard.blogspot.be/2010/12/build-nutch-20.html#Crawl_Script" target="_blank">Hier</a> kan je een voorbeeldscript vinden dat alle stappen samenbrengt. Je kan ook gebruiken maken van het &#8216;crawl&#8217;-commando dat de stappen combineert, maar dan heb je minder zicht op de verschillende stappen van het proces.</p>
</div>
<p>Nutch kan zowel websites crawlen (http(s)://) als filesystemen (file:// en ftp://). Bij websites waar een HTTP authenticatie vereist is kunnen de nodige credentials in een configuratiebestand opgenomen worden. Let natuurlijk wel op dat dit credentials zijn die geen beschermde of gevoelige inhoud kunnen beschikbaar maken omdat de zoekresultaten publiek beschikbaar zullen zijn.</p>
<h2>Configuratie</h2>
<div>De configuratie van Nutch gebeurt in<em> nutch-site.xml</em> waar je de standaardparameters uit <em>nutch-default.xml</em> kan aanpassen. De interessante parameters zijn daar:</div>
<div>
<ul>
<li><em>http.agent.name</em>&nbsp;: welke browser agent string wordt er door doelwebsites gezien zodat je op die sites een crawler kan toelaten en ook een verschil kan maken tussen crawler-traffiek en gewone traffiek.</li>
<li><em>parser.character.encoding.default</em>&nbsp;: welke encoding er moet gebruikt worden als deze ontbreekt (bijv. utf-8).</li>
<li><em>storage.data.store.class</em>&nbsp;: welke backend er wordt gebruikt, bijv. org.apache.gora.hbase.store.HBaseStore voor Hbase.</li>
<li><em>plugin.includes</em>&nbsp;: Nutch heeft een plugin architectuur die het mogelijk maakt om bepaalde functionaliteit toe te voegen. Er zijn een aantal plugins die standaard geconfigureerd zijn. In het geval van de tests werden volgende plugins gebruikt</li>
</ul>
<pre>protocol-httpclient|urlfilter-regex|parse-(html|tika)|index-(basic|anchor|more)|urlnormalizer-(pass|regex|basic)|scoring-opic</pre>
<ul>
<li><em>db.ignore.external.links</em>&nbsp;: geeft aan of de crawler buiten de initieel aangegeven websites links mag volgen.</li>
<li><em>file.content.limit &amp; http.content.limit</em>: hoe groot mogen de geïndexeerde bestanden of webpagina&#8217;s zijn. Dit moet overeenkomen met wat je als groottebeperking opgeeft in de onderliggende databank.</li>
</ul>
<h2>Backend</h2>
<p>De HBase backend kan ook getuned worden maar dat is eigenlijk een topic op zich. Je kan <a href="https://gbif.blogspot.be/2012/07/optimizing-writes-in-hbase.html" target="_blank">hier</a> en <a href="https://www.packtpub.com/article/hbase-basic-performance-tuning" target="_blank">hier</a> wat  informatie vinden. Het belangrijkste is dat er genoeg geheugen beschikbaar is.</p>
</div>
<h2>Plugins</h2>
<div>Zoals gezegd zijn er verschillende plugins die het proces kunnen sturen. Je kan die plugins ook apart aanroepen om het effect van een bepaalde configuratie te testen, wat uitermate handig is.</div>
<div>De standaardplugins die mij goed van pas kwamen:</div>
<div>
<ul>
<li><strong>URLfilter-regex</strong></li>
</ul>
<p style="padding-left: 30px;">Je kan URL&#8217;s filteren en bepalen welke URL&#8217;s in aanmerking komen en welke niet. In het configuratiebestand &#8220;regex-urlfilter.txt&#8221; kan je dit met behulp van reguliere expressies configureren. URL&#8217;s die voldoen aan de expressie kan je dan uitsluiten door er &#8216;-&#8216; voor te zetten of expliciet toevoegen door &#8216;+&#8217;. Zo zal de regel</p>
<pre style="padding-left: 30px;">-index.php/Help:.*</pre>
<p style="padding-left: 30px;">Wikimedia links met de hulppagina&#8217;s niet indexeren of kan je bijvoorbeeld instellen dat het url-pad niet dieper mag zijn dan 7 niveau&#8217;s:</p>
<pre style="padding-left: 30px;">"-.*/(?:[^/]+/){7,}</pre>
<p style="padding-left: 30px;">Je kan een regel toevoegen aan het bestand en dan testen met:</p>
<pre style="padding-left: 30px;"> <em>&lt;installatiedir&gt;/bin/nutch plugin urlfilter-regex org.apache.nutch.urlfilter.regex.RegexURLFilter</em></pre>
<p style="padding-left: 30px;">Je geeft dan een url in en krijgt dan het resultaat of deze al dan niet gefilterd wordt.</p>
<ul>
<li><strong>URLNormalizer-regex</strong></li>
</ul>
<p style="padding-left: 30px;">De opgehaalde URL&#8217;s kan je normalizeren naar een bepaalde vorm. Dit is vooral handig als je bijvoorbeeld een site indexeert waarvan documenten op verschillende locaties terugkomen maar met een verschillend pad. Dit was in de tests het geval met een website gebaseerd op IBM Lotus Domino. De url naar een document hangt af van het pad langswaar je er naar toe gaat.</p>
<p style="padding-left: 30px;">Eenzelfde document heeft bijvoorbeeld als urls (met zijn identifier als laatste parameter):</p>
<pre style="padding-left: 60px;">http://website/databank.nsf/&lt;id1&gt;/&lt;id&gt;?OpenDocument
http://website/databank.nsf/&lt;id2&gt;/&lt;id&gt;?OpenDocument</pre>
</div>
<div>
<p style="padding-left: 30px;">Als je dan weet dat er een URL bestaat om het document rechtstreeks op te vragen door</p>
<pre style="padding-left: 60px;">http://website/databank.nsf/View/&lt;id&gt;</pre>
<p style="padding-left: 30px;">dan kan je de bovenstaande urls normalizeren met behulp van volgende expressies</p>
</div>
<pre style="padding-left: 60px;">&lt;regex&gt;
 &lt;pattern&gt;(\.nsf)/[^/]*/(.*OpenDocument$)&lt;/pattern&gt;
 &lt;substitution&gt;$1/View/$2&lt;/substitution&gt;
&lt;/regex&gt;</pre>
<ul>
<li><strong>index-more</strong></li>
</ul>
<p style="padding-left: 30px;">Deze plugin indexeert onder andere ook het content-type van de gecrawlde inhoud. Dit kan je achteraf gebruiken om in de zoekmachine te kunnen vernauwen op bepaalde content types zoals een PDF.</p>
<h2>Integratie met Solr</h2>
<div>Nutch heeft zijn eigen index maar je kan de gecrawlde pagina&#8217;s in Solr stoppen. Dit heeft als voordeel dat je een centrale Solr server kan gebruiken voor allerlei zoekfuncties en dat je de kracht, flexibiliteit en mogelijkheden van Solr kan gebruiken. De configuratie van Solr valt echter buiten het bestek van deze post. Je kan facetten gebruiken op specifieke velden zoals de beschikbare websites, de content types en zelfs de taal die gedetecteerd werd.</div>
<div>Als je geen gebruik wenst te maken van Solr kan je ook <a href="https://www.elasticsearch.org/" target="_blank">ElasticSearch</a> gebruiken.</div>
<div>Het feit dat er nog een extra index wordt gebruikt heeft natuurlijk wel als resultaat dat je twee backends hebt met de gegevens. Het voordeel is wel dat de Solr instantie los staat van Nutch en dus ook gevoed kan worden met andere data.</div>
<p>Aangezien Nutch 2.1 zelf geen userinterface heeft om de index te doorzoeken ben je zowiezo aangewezen op een UI die bijvoorbeeld bovenop Solr staat. In de tests werd geëxperimenteerd met <a href="https://github.com/evolvingweb/ajax-solr" target="_blank">Ajax-solr</a>, een set Javascript libraries om een UI te bouwen.</p>
<h1>3,2,1 &#8230; start</h1>
<p>Na alles te hebben geïnstalleerd en configureerd kan je een crawl starten. Het blijkt al snel dat er redelijk wat tuning nodig is om de crawl snel genoeg te laten verlopen.</p>
<h2>Snelheid</h2>
<p>De standaardconfiguratie van Nutch beperkt sterk het aantal pagina&#8217;s per tijdseenheid die worden opgehaald. In een eerste run (7 iteraties van het hierboven beschreven proces) duurde het verschillende uren om 6000 pagina&#8217;s op te halen. Je kan dit sneller laten verlopen door te spelen met de parameter <em>fetcher.server.delay</em> (aantal seconden tussen requests op eenzelfde server, zodat je een server niet overspoelt met requests, ) en een aantal parameters van de Fetcher threads (<em> fetcher.threads.fetch,  fetcher.threads.per.queue, fetcher.threads.per.host</em>). Met de waarden 3, 30, 15 en 3 voor deze vier parameters verliep dezelfde crawl een heel stuk sneller. Er werden uiteindelijk 80 000 urls verwerkt op 2.5 uur. Je moet wel in de gaten houden of de server nog meekan, de onderliggende backend en de Solr-instantie.</p>
<h2>Onderhoud</h2>
<div>De resultaten van de crawl kan je gaan bekijken door zoekopdrachten uit te voeren en te gaan kijken of er ongewenste resultaten bij zijn of andere vreemde URLs. Die kan je dan in de Nutch configuratie uitsluiten of omvormen.</div>
<p>Daarnaast moet je ook gaan kijken in de Solr index en configuratie wat er daar allemaal is van mogelijkheden en verbeteringen. Na aanpassingen te hebben gedaan in Solr kan je  de volledige Nutch-index opnieuw in Solr stoppen door volgend commando:</p>
<pre style="padding-left: 30px;">&gt; bin/nutch solrindex &lt;Url van solr&gt; -reindex</pre>
<h2>Vernieuwen van pagina&#8217;s</h2>
<p>Een onduidelijk punt dat bleef is het verversen van de pagina&#8217;s. Het zogenaamd &#8220;recrawlen&#8221; is niet goed gedocumenteerd. In de Nutch index wordt er bijgehouden wanneer een pagina opnieuw mag opgehaald worden. Deze waarde wordt ingesteld aan de hand van de parameters rond de &#8220;Fetchschedule&#8221; zoals <em>db.fetch.interval.default</em>. Standaard zal Nutch maar na 30 dagen een pagina opnieuw ophalen. Je kan voor een pagina gaan kijken wanneer ze de volgende keer zal opgehaald worden via volgend commando:</p>
<div>
<pre style="padding-left: 30px;">&gt; bin/nutch readdb -url http://website.com/pagina</pre>
<blockquote>
<pre>key: http://website.com/pagina
baseUrl: http://website.com/pagina
status: 2 (status_fetched)
fetchInterval:  83000
fetchTime:      1360246212783
prevFetchTime:  1360162351060
....
title:  Title</pre>
</blockquote>
<div>De parameter <em>fetchTime</em> geeft de datum &amp; tijd vanaf wanneer de pagina opnieuw mag opgehaald worden. In dit geval is dit 1360246212(783) wat je via het commando <em>date</em> kan omzetten:</div>
<div>
<pre style="padding-left: 30px;">&gt; date -u -d @1360246212
Thu Feb  7 14:10:12 UTC 2013</pre>
</div>
<p>Het <em>fetchInterval</em> zal worden toegevoegd aan de moment dat de pagina opnieuw wordt opgevraagd, in dit geval 83000 seconden of 23 uur. Zo zal je dus elke dag de pagina&#8217;s kunnen vernieuwen.</p>
<p>Voor een recrawl kan je je bijvoorbeeld beperken tot 2 iteraties van het crawlproces. Zo worden bestaande pagina&#8217;s opnieuw overlopen en eventueel nieuwe links gedetecteerd. Deze worden dan in de volgende iteratie ook mee geïndexeerd. Het heeft ook als gevolg dat je index nog verder groeit als er bij vorige iteraties nog extra links werden gedetecteerd. Zo werd in de test een index van 80 000 pagina&#8217;s er snel eentje van 220 000 pagina&#8217;s.</p>
<p>Pagina&#8217;s die verdwijnen worden niet uit de Solr-index verwijderd. In Nutch 1.6 was er hiervoor een aparte job, voor Nutch 2.x is dit momenteel voorzien in de trunk en zal dit met de nieuwe versie beschikbaar zijn.</p>
<p>Gezien de indexatietijd redelijk beperkt is kan je er ook voor opteren om telkens een nieuwe crawl uit te voeren en de vorige index steeds te wissen.</p>
<h1>Conclusie</h1>
<p>Met de end-to-end implementatie van deze test is duidelijk dat er heel wat komt kijken bij de implementatie van een zoekoplossing, niet alleen voor de pure installatie/configuratie maar ook voor het iteratieve onderhoud zoals het opsporen/weren van ongewenste URLs.  Het ter beschikking stellen van de nodige Solr functionaliteit (zoals omgaan met meertaligheid, facetten, autocompletion, spellingscontrole, &#8230;) neemt ook een heel stuk van de implementatie in beslag. Dan spreken we nog niet over het nut van statistiek achteraf, zodat de zoekmachine meer kan aangepast worden naar de noden van de eindgebruiker. De implementatie van een zoekmachine is in dit aspect geen project maar een continu proces.</p>
<p>Nutch 2.1 is nog wat ruw, vooral op documentatievlak en ontbreekt ook nog een aantal belangrijke features zoals het schoonmaken van de Solr-index bij het verdwijnen van pagina&#8217;s. Maar het is alleszins een bruikbaar systeem. De nodige competenties gaan echter verder dan Nutch alleen want als je een NoSQL backend zoals HBase gebruikt heb je daar uiteraard ook kennis van nodig en met Solr heb je enorme mogelijkheden tot je beschikking.</p>
<p>Een gebruiker van een dergelijke zoekmachine kan alleen maar beter worden van een systeem dat alle interne websites ter beschikking stelt. Daar staat natuurlijk tegenover dat dit niet zo evident is om dit op een gebruiksvriendelijke manier aan te brengen. De aangeboden functionaliteit van een crawler is ook beperkt tot de gegevens die beschikbaar zijn in de webpagina. Standaard zal je dus de inhoud van de pagina in de index stoppen met wat metadata (zoals datum, content-type, url). Wil je meer specifieke informatie zoals de auteur van de tekst dan kan je dit niet met de crawler (tenzij je een specifiek veld hebt en de nodige logica om de auteur uit een metadata veld te halen op de pagina). Daarom dat een content management systeem dat zelf zijn inhoud in de zoekmachine stopt meer rijke informatie kan ter beschikking stellen.</p>
</div>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
