Heritrix 3 konfig receptkönyv

Gondoltam megosztom a tapasztalatokat, hátha akad olyan “elvetemült”, aki szintén Heritrix-szel akar nekiállni site-okat archiválni. 🤪 Az alábbiakban leírom azokat a beállítási lehetőségeket, amelyek munkám során előjöttek, fontosak voltak.

A konfigurációt Heritrix-ben job-onként lehet elvégezni, a crawler-beans.cxml fájl módosításával.

1. Kezdő lépések

1.1. URL-ek hozzáadása

A legfontosabb dolog egy job-nál a forrás URL-ek hozzáadása, vagyis: honnan induljon a letöltés? A CXML-ben keressük meg ezt a részt:

<bean id="longerOverrides" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
  <property name="properties">
    <props>
      <prop key="seeds.textSource.value">

        # URLS HERE

      </prop>
    </props>
  </property>
</bean>

Itt az URL-eket soronként írhatjuk be.

1.2. Operátor kontakt címe

A Heritrix megköveteli, hogy beírjunk egy URL-t, ami a letöltést végző egyén/szervezet honlapjára mutat. Ez az URL hozzá lesz adva a User-agent paraméterhez. (Lesz még szó róla a 2.6.-os bekezdésben.) Nyilván ez a felelősség miatt kell, hogy ha leterheljük valakinek a szerverét egy izmos crawl futammal, és az nemtetszést vált ki, akkor vissza lehessen keresni minket.

Keressünk rá az alábbira, hogy megtaláljuk, hova kell írni ezt a címet:

metadata.operatorContactUrl=

2. Testreszabás

2.1. Tárolási mód

A Heritrix 3 alapesetben WARC fájlokba írja a letöltött adatokat. Előfordulhatnak esetek, amikor nekünk nem erre van szükségünk, hanem esetleg konkrétan a fájlokra, vagy esetleg WARC helyett ARC fájlokra.

Ehhez a warcWriter bean class paraméterét kell megfelelően beállítanunk:

<bean id="warcWriter" class="org.archive.modules.writer.WARCWriterProcessor">

Lehetőségek (a package ugyanaz):

  • WARCWriterProcessor
  • ARCWriterProcessor
  • MirrorWriterProcessor - ez tükrözi a mappaszerkezetet

2.2. Domain-en belül maradás

Ha egy site-ot archiválunk, általában nem akarjuk követni az összes linket a végtelenségig rekurzívan, mert végtelen időnk és tárkapacitásunk nincs. Az lenne a cél, hogy a rekurzív bejárás az adott kiinduális domain-re szorítkozzon, ne lépjen ki onnan.

Ezt egy Heritrix 3 job esetén úgy tehetjük meg, hogy az alábbi bean-t konkrétan kitöröljük/kikommentezzük a config CXML-ből:

<!--
  <bean class="org.archive.modules.deciderules.TransclusionDecideRule">
    ...
  </bean>
-->

2.3. Bizonyos URL minták tiltása

Azon túl, hogy domain-en maradunk, site-on belül is lehetnek olyan részek, amik minket nem érdekelnek, esetleg fájltípusok, vagy akár crawler csapdák (pl. egy végtelen calendar, ami ráadásul minden aloldalról elérhető különböző URL-en).

Ezeket reguláris kifejezések formájában mondhatjuk meg a Heritrix-nek, hogy kerülje el:

<bean id="scope" class="org.archive.modules.deciderules.DecideRuleSequence">
  ...
  <property name="rules">
    <list>

      ...

      <bean class="org.archive.modules.deciderules.MatchesListRegexDecideRule">
        <property name="decision" value="REJECT"/>
        <property name="regexList">
          <list>
            <value>regexp1</value>
              ...
            <value>regexpN</value>
          </list>
        </property>
      </bean>
    </list>
  </property>
</bean>

2.4. Gyorsítás

A Heritrix alapból nagyon komótosan tölt, akár másodperceket is vár URL-enként. A konfigban én 2 helyet találtam, ahol fel lehet turbózni a dolgot:

<bean id="disposition" class="org.archive.crawler.postprocessor.DispositionProcessor">
  <property name="delayFactor" value="1.0" />
  <property name="minDelayMs" value="100" />
  <property name="respectCrawlDelayUpToSeconds" value="1" />
  <property name="maxDelayMs" value="100" />
</bean>

Illetve:

<bean id='veryPolite' class='org.archive.spring.Sheet'>
  <property name='map'>
    <map>
      <entry key='disposition.delayFactor' value='1'/>
      <entry key='disposition.minDelayMs' value='100'/>
      <entry key='disposition.maxDelayMs' value='1000'/>
      <entry key='disposition.respectCrawlDelayUpToSeconds' value='1'/>
    </map>
  </property>
</bean>

Az egyes property-k értékeinek magyarázatához lásd a doksit.

2.5. robots.txt figyelmen kívül hagyása

A robots.txt-ben a webszerverek bizonyos robotokat, böngészőket (vagy akár mindenféle programot) tilthatnak el bizonyos mappáktól, illetve crawl delay-t is megszabhatnak. Persze ezek csak információk, ajánlások a programoknak, az már egy másik kérdés, hogy be is akarják-e ezt tartani. A Heritrix persze alapvetően illedelmes robot, betartja, amit e szabályzatban megszabnak neki, de szerencsére tartalmaz konfigurálási lehetőséget a robots.txt ignorálására.

<bean id="metadata" class="org.archive.modules.CrawlMetadata" autowire="byName">
  ...
  <property name="robotsPolicyName" value="ignore"/>
  ...
</bean>

2.6. Saját User-agent megadása

Vannak olyan site-ok, ahol akár robots.txt szabályokkal, akár egy szerveroldali szkript segítségével szűrik, hogy milyen böngészővel lehet őket meglátogatni. A User-agent HTTP paraméter szolgál arra, hogy megnevezze a HTTP kérést küldő programot és annak verzióját, illetve esetleg a platformot, amin fut. Az ilyen szűréseket nagyon egyszerű kikerülni: beállítjuk ennek a paraméternek az értékét mondjuk egy népszerű böngészőére.

Heritrix-ben is beállítható ez természetesen, viszont annyi megkötés van, hogy a Heritrix verziószámának és az operátor URL-nek (lásd 1.2) szerepelnie kell benne. A konfigfájlban egy template string-et kell megadni, amiben szerepel egyrészt a @VERSION@, másrészt a +@OPERATOR_CONTACT_URL@ karakterlánc. Felhívom a figyelmet, hogy a + jel is kell, különben hibát jelez a Heritrix a job build-elésekor.

<bean id="metadata" class="org.archive.modules.CrawlMetadata" autowire="byName">
  ...
  <property name="userAgentTemplate" value="Mozilla/5.0 (compatible; heritrix/@VERSION@ +@OPERATOR_CONTACT_URL@)"/>
  ...
</bean>

2.7. Auto pause kikapcsolása

A Heritrix-nek van egy olyan érdekessége, hogy alapértelmezésben ha egy job-ot elindítasz, rögtön lepauzálja. Külön rá kell menned az unpause gombra, hogy ténylegesen meginduljon a letöltés. (Érdekes dolog, én még nem jöttem rá mire jó ez… ha elindítok egy job-ot, akkor azért indítom el, hogy töltsön, nem? 😃) De ezt is ki lehet kapcsolni, itt:

<bean id="crawlController" class="org.archive.crawler.framework.CrawlController">
  <property name="pauseAtStart" value="false" />
</bean>

3. Megfigyelések

3.1. Memóriaigény

A doksi azt írja, hogy az alapértelmezett 256MB heap memória több száz oldal letöltéséhez jó. Tapasztalatom szerint 8-10 párhuzamosan futó job-tól konkrétan meghal az egész OutOfMemoryException-nel, szóval az Xmx paramétert érdemes megadni, és GB-okban kell gondolkodni. Én speciel 3GB-ot adok neki, ez elég arra, hogy 10 job fusson párhuzamosan.

export HERITRIX_HOME=/path/to/heritrix-3.1.1
export JAVA_HOME=/path/to/jre
export JAVA_OPTS=-Xmx3G
$HERITRIX_HOME/bin/heritrix -a admin:admin

Amit még érdemes megtenni: az épp nem futó job-okat teardown-olni, ha sok van.

3.2. URL problémák

A MirrorWriter-rel az a tapasztalat, hogy érdekes dolgokat produkál. Bizonyos URL-ekből én azt látom, hogy nem képes (valid) fájlnevet generálni, tehát az a letöltött bájthalmaz elveszik az éterben. Konkrétan én ezt /?a=b/c alakú relatív linkeknél tapasztaltam.

Ami nagy probléma, hogy a parszere elég érdekes felfogás mentén lett implementálva. A Heritrix mindenhonnan ki akar parszolni URL-t, onnan is, ahol nincs. Kutat a CSS-ekben, JS-ben, és gazdagon kapok olyan fájlokat, amelyek neve egy stíluslapon használt szelektor, vagy egy szkriptben használt feltétel egyik fele. 😃

A forráskódban azt láttam, hogy ilyen “likely-URL”-eket keres, tehát ami “olyasmi, mint egy URL”… Találkoztam olyan mappanévvel is, ami egy komplett <iframe> tag volt.

Itt nyilván felmerül az emberben, hogy esetleg nem ez a “smart crawler” a hibás, hanem az adott oldal forráskódja… de egyrészt ezt nem egy oldalnál csinálja, másrészt pedig ezeket az adott oldalakat a WGET hibamentesen leszedte.

Azt olvastam, hogy érdemes kikapcsolni a job konfigban az ExtractorJS és ExtractorCSS modulokat, mert így megszabadulok ezektől a felesleges fájloktól (amelyek egyébként növelik az idő- és tárigényt, valamint redundáns adatot tartalmaznak!) - de még nem próbáltam ki. 🙂

További észrevétel a közelmúltból: Drupal-os oldalt nem tud jól kezelni, kaptam egy ilyen URL-t a crawl log-ban:

http://***/calendar/month/2013-06/field/theme/sites/all/modules/ctools/css/sites/all/modules/ctools/css/modules/user/user.css

…amiben én egy ciklust vélek felfedezni. Természetesen a letöltött fájl sem egy stíluslap lett, hanem egy HTML, valószínűleg a Drupal rendszer olyan jószívű, hogy 404 hibalap helyett visszadobja a leghosszabb valid prefix-hez tartozó lapot. Bár talán pont azzal jártunk volna jobban, ha hibát ad vissza, mert akkor nem keletkezik redundáns adat… no mindegy. 🙂

Zsolt vagyok, full-stack fejlesztő.
Crawlereket, webalkalmazásokat, statikus honlapokat és interaktív vizualizációkat készítek.
Copyright © 2019 Zsolt Jurányi | All rights reserved.