Maak sitemap.xml met bash script

Doel

Maak zelf geautomatiseerd je sitemap.xml bestand. De aanwezigheid van het bestand maakt het voor zoekmachines makkelijker om de website te indexeren.

Aanleiding/overwegingen

  • De website https://vanroekel-peppink.nl bestaat uit een export van 4 geslachten vanuit een genealogie programma. Daarbij worden ruim 17000 html pagina’s aangemaakt. Daaronder veel pagina’s die ik uit de sitemap.xml wilde weren. Dat bracht mij ertoe om even uit te zoeken hoe ik de sitemap zelf zou kunnen genereren.
  • Het is makkelijker om dit bestand als maatwerk zelf te creëren, door b.v. weglaten van pagina’s, die je niet in indexering wilt laten opnemen.
  • Optionele parameters als ‘changefreq’ en ‘priority’ voor het sitemap.xml bestand heb ik niet opgenomen, maar zijn indien gewenst redelijk eenvoudig toe te voegen. lastiger is het om automatisch te bepalen wat een zinvolle waarde voor deze opties zou zijn.
  • Het is nu eenvoudig om het script opnieuw uit te voeren na aanpassingen van de website met nieuwe pagina’s of berichten, zodat de sitemap.xml ook weer snel up to date is.
  • Hieronder het voorbeeld voor de huidige website.

Voorbereiding

  • Hernoem het bestand na download tot Setuwwebsite.sh of iets dergelijks.
    Bestandsnaam: Setictwebsite.sh
  • Zelf voer ik het script uit op mijn Synology NAS, waar ook de website wordt gehost. Staat de website elders online? Pas één en ander aan aan de omstandigheden. bv. draai het script op lokale Linux machine en doe daarna een ftp upload van het nieuw gemaakte sitemap.xml bestand.
  • Maak het script uitvoerbaar met het commando chmod +x.
  • Controleer en pas aan: paden en domein namen.
  • Voor betere leesbaarheid is het venster hieronder te vergroten. Selecteer de rechter onder hoek en versleep deze om het breder te maken.
  • Ik documenteer al mijn scripts met steenkolen Engels.
  • Verdere uitleg en tips worden onder het venster gegeven met verwijzing naar de regelnummers.

Uitvoering

#!/bin/bash
#-----------------------------------
# Script to create sitemap.xml by Jan Peppink - https://ict.peppink.nl
#-----------------------------------
#
######################################################################
# Set Environment
#-----------------------------------
# when calling /home/user/scripts/ScriptTemplate.sh "'option one'" "'optiontwo'"
# ${@}     = 'option one' 'optiontwo'
# $1       = 'option one'
# $2       = 'optiontwo'
# ${0}     = /home/user/scripts/ScriptTemplate.sh - Full Path and filename
# ${0%/*}  % removes from the end. Everything including last found slash. Given path remains.
#          = /home/user/scripts (or . when calling ./ScriptTemplate.sh)
# dirname ${0} is saver. Always gives the full path.
# ${0##*/} ## removes from the start. Everything including last found slash. Filname remains.
#          = ScriptTemplate.sh = Script name
  MYPATH=$(dirname $0)
  MYNAME=${0##*/}
  VERBOSE=0

######################################################################
# Functions go here
#-----------------------------------
# Display verbose output if wanted (started with -v option)
function verbose {
	if [[ $VERBOSE -eq 1 ]] ; then
		echo `date +"%Y-%m-%d %H:%M"` - $1
	fi
}

######################################################################
# Startup Checks go here
#-----------------------------------
# Get start options
#-----------------------------------
  if [[ "$#" -ge 1 ]] ; then
	if [[ $1 == "verbose" ]] || [[ $1 == "--verbose" ]] || [[ $1 == "-v" ]] ; then
		VERBOSE=1
	fi
  fi

######################################################################
# Start to do something
verbose "Starting ${MYNAME}"

#-----------------------------------
# When needed stop services before running my code
#-----------------------------------
#verbose "Stop some services."
# sudo service cron stop

######################################################################
# Main script 
#-----------------------------------
# Your job code comes here.
#-----------------------------------
	verbose "Start working on website ict.peppink.nl"
	verbose "Save the original .htaccess file"
	cp -p /volume1/web/ict/.htaccess /volume1/web/ict/.htaccess.org

	verbose "Remove the deny of Wget in .htaccess during Wget spider action"
	sed -i '/Wget /d' /volume1/web/ict/.htaccess 

	verbose "Do the Wget spider action"
	sitedomain=https://ict.peppink.nl/
	wget --spider --recursive --level=inf --no-verbose --output-file=ict-linkfile.txt $sitedomain

	verbose "Restore the original .htaccess file"
	mv /volume1/web/ict/.htaccess.org /volume1/web/ict/.htaccess

	verbose "Create the new sitemap.xml"
	grep -i URL ict-linkfile.txt | awk -F 'URL:' '{print $2}' | awk '{$1=$1};1' | awk '{print $1}' | grep -v feed | grep -v author | grep -v wp-json | grep -v tag | sort -u | sed '/^$/d' > ict-sortedlinks.txt
	
header='<?xml version="1.0" encoding="UTF-8"?>
<urlset
	xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
	http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<!-- Created by Jan Peppink - https://ict.peppink.nl with sitemap generator script -->'
echo "$header" > ict-sitemap.xml

	while read line; do
		case "$line" in 
		*/ | *.html | *.htm)
			timestamp=`date +%Y-%m-%dT%H:%M:%S+01:00`
			echo '<url><loc>'$line'</loc><lastmod>'$timestamp'</lastmod></url>' >> ict-sitemap.xml
		;; 
		*)
		;;
		esac
	done < ict-sortedlinks.txt

	echo "</urlset>" >> ict-sitemap.xml

	verbose "Copy the new sitemap.xml to production"
	cp ict-sitemap.xml /volume1/web/ict/sitemap.xml
	chmod 644 /volume1/web/ict/sitemap.xml
	chown http:http /volume1/web/ict/sitemap.xml

	#-----------------------------------
	verbose "Finally clean used temp files"
	rm ict-linkfile.txt
	rm ict-sortedlinks.txt
	rm -rf ict.peppink.nl
	rm ict-sitemap.xml

#-----------------------------------
verbose "Ready is Case #########################################"

######################################################################
# Finishing script 
#-----------------------------------
# When needed (re)start services
#-----------------------------------
#verbose "Start the stopped services again."
# sudo service cron start

######################################################################
verbose "Ending ${MYNAME}"

######## THATs All ###################################################

Toelichting bij de regels

  • 1-58: Het eerste gedeelte van het script komt overeen met het eerder beschreven voorbeeld script.
  • 59-60: Als het script is gestart met ‘-v’, dan geeft het deze meldingen in de scherm uitvoer.
  • Volgende stappen t.a.v. .htaccess bestand alleen als het van toepassing is. Andere keer een artikeltje over het .htaccess bestand.
    61: We maken een kopie van het .htaccess bestand in de root directory van de website en bewaren dat als .htaccess.org
  • In .htaccess wordt in mijn geval allerhande ongewenste toegang tegengehouden. Daaronder benadering van de website met wget.
  • 64: We verwijderen de regel waarin “Wget” voorkomt. Deze beschermt de website tegen de Wget spider actie, die we nu juist willen uitvoeren. Deze bescherming wordt tijdens de kortdurende actie uitgeschakeld en daarna meteen weer hersteld.
    De optie sed -i zorgt voor bewerking in het aangeroepen bestand. ‘Wget /d’ verwijderd uitsluitende de regel(s!) waarin ‘Wget ‘ gevonden wordt en laat de rest van de .htaccess functionaliteit intact.
  • 67: Wijzig het sitedomein en vul daar de website in waarvoor u de sitemap wilt maken.
  • 68: het wget –spider commando haalt de links van de website op en verzameld deze in de genoemde output file: ict-linkfile.txt
  • 71: Als eerste plaatsen we nu weer het originele .htaccess bestand terug met het mv (move) commando.
  • 74: Dan volgt een lange regel met commando’s, die hun uitvoer met het | teken telkens aan het volgende commando doorgeven. Hieronder uitgesplitst en toegelicht:
    grep -i URL ict-linkfile.txt | Pak alle regels die de string ‘URL’ bevatten uit het bestand ict-linkfile.txt en geef het resultaat door aan het volgende commando.
    awk -F ‘URL:’ ‘{print $2}’ | Zet ‘URL:’ als veldscheiding tussen hetgeen ervoor en erna komt, waarbij ‘{print $2}’ de string die erop volgt doorgeeft aan het volgende commando.
    awk ‘{$1=$1};1’ | Verwijderd voorloop spaties en geeft resultaat door.
    Als voorbeeld voor het huidige bericht levert dat een regel op met: https://ict.peppink.nl/maak-sitemap-xml-met-bash-script/ [33759] -> “ict.peppink.nl/index.html?p=329.tmp.tmp” [1]
    awk ‘{print $1}’ | pakt daarvan met $1 het eerste deel (= tot eerste spatie) en geeft in het voorbeeld voor dit bericht de volgende url als resultaat door:
    https://ict.peppink.nl/maak-sitemap-xml-met-bash-script/
    Maar voor andere URL’s kan het nog ongewenste inhoud bevatten en daarom gaan we nog even door met:
    grep -v feed | grep -v geeft de regels door die NIET de opgegeven string ‘feed’ bevatten.
    grep -v author | filtert op dezelfde wijze de regels met ‘author’ eruit.
    grep -v wp-json |filtert de regels met ‘wp-json’ eruit.
    grep -v tag | filtert hier de regels met ’tag’ eruit.
    sort -u | sorteert de resterende regels op alphabet en zet het resultaat door naar
    sed ‘/^$/d’ dat met /d de lege regels verwijderd. (^is begin van de regel en $ is eind van de regel) en het resultaat door stuurd naar het gesorteerde bestand.
    > ict-sortedlinks.txt
    Bij het filteren is het natuurlijk even oppassen dat daar geen regel wordt gefilterd met een string, die (later) in een url voor kan komen.
  • 76-82: Stop de tekst tussen de enkele quotes in de variabele header.
  • 83: Bewaar deze header in het bestand ict-sitemap.xml. en overschrijf dit bestand door enkele redirect ‘>’ als het al bestaat.
  • 85-94: In een while loop lezen we regel voor regel uit het bestand ict-sortedlinks.txt (94), waarbij regel voor regel in de variabele ‘$line’ wordt geplaatst.
  • 86: In een case constructie checken we de inhoud van de regel.
  • 87, als deze eindigt op /, of .html, of .htm, dan voeren we regel 88 en 89 uit op de inhoud.
  • 88: zet huidige tijd (inclusief tijdzone) in de variabele timestamp volgens het formaat dat in het sitemap.xml bestand is gewenst.
  • 89: Vervolgens wordt de link in de xml constructie met dubbele redirect ‘>>’ toegevoegd aan het bestand ict-sitemap.xml.
  • 91: Voor de overige regels (die niet aan de eerdere case voorwaarden voldeden) volgt GEEN actie. Deze worden hiermee dus overgeslagen. Een link naar b.v. https://uwwebsite.nl/bestand.pdf valt daarmee buitende verzameling.
  • 96: Als op bovenstaande wijze alle regels doorlopen zijn, wordt de set met URL’s in het ict-sitemap.xml bestand afgesloten met </urlset>
  • 99 We kopiëren het resultaat naar de root directory van we website. (Als deze elders taat moet deze actie vervangen worden door een upload van het bestand.)
  • 100: De rechten van het bestand worden ingesteld met chmod commando.
  • 101: De eigenaar en groep wordt ingesteld met chown commando.
  • 104: in de volgende regels worden de tijdelijk aangemaakte bestanden en directories (domeinnaam in regel 107) weer verwijderd.

Resultaat

Dit is de scherm uitvoer van het script.

# ./Setictwebsite.sh -v
2021-02-05 22:55 - Starting Setictwebsite.sh
2021-02-05 22:55 - Start working on website ict.peppink.nl
2021-02-05 22:55 - Save the original .htaccess file
2021-02-05 22:55 - Remove the deny of Wget in .htaccess during Wget spider action
2021-02-05 22:55 - Do the Wget spider action
2021-02-05 22:55 - Restore the original .htaccess file
2021-02-05 22:55 - Create the new sitemap.xml
2021-02-05 22:55 - Copy the new sitemap.xml to production
2021-02-05 22:55 - Finally clean used temp files
2021-02-05 22:55 - Ready is Case #########################################
2021-02-05 22:55 - Ending Setictwebsite.sh

En hieronder dan nog de sitemap.xml die in de root directory is geplaatst.

<?xml version="1.0" encoding="UTF-8"?>
<urlset
	xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
	http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<!-- Created by Jan Peppink - https://ict.peppink.nl with sitemap generator script -->
<url><loc>https://ict.peppink.nl/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/algemene-voorwaarden/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/basis-firewall-in-linux/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/berichten/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/berichten/page/2/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/bestelformulier/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/betaalformulier/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/beveiligde-website-op-synology-nas/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/category/linux-bash/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/category/opdrachten/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/category/synology-nas/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/category/windows-dos/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/category/wordpress-website/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/contact/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/contactformulier/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/copyright/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/disk-4tb-naar-8tb/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/grondig-wissen-harde-schijf/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/ict-ervaring/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/inlog-en-uitlog-in-menu/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/maak-sitemap-xml-met-bash-script/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/mijn-account/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/mijn-account/lost-password/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/mogelijkheden-voor-hulp-op-afstand/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/offerteformulier/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/pep-dwnld-plug-in-voor-downloadknop-met-teller/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/pep-frmqr-qr-code-plug-in-voor-betalingen/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/pep-wooqr-qr-code-plug-in-voor-betalingen/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/permissie-op-gedeelde-mappen/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/privacybeleid/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/privecloud-met-synology-drive/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/product-categorie/wordpress-plug-ins/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/product/pep-dwnld-plug-in-voor-downloadknop-met-teller/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/product/pep-frmqr-qr-code-plug-in-voor-betaal-formulier/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/product/pep-wooqr-qr-code-plug-in-voor-woocommerce-betalingen/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/quick-assist/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/raid1-naar-raid0/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/script-voor-mestrum-nl/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/shortcode-met-countdown-functie/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/sitemap/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/sjabloon-bash-script/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/sjabloon-batchfile/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/terugbetalen-retournering/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/toon-code-op-website/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/veilig-delen-van-bestanden/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/verzend-e-mail-vanuit-script/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/volledige-backup/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/website-vanroekel-peppink-nl/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
<url><loc>https://ict.peppink.nl/winkel/</loc><lastmod>2022-02-13T21:46:36+01:00</lastmod></url>
</urlset>

Tips

  • Zet sitemap.xml in robots.txt bestand, die in de root directory van de website staat. Bijvoorbeeld:
    Sitemap: https://ict.peppink.nl/sitemap.xml

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

Deze site gebruikt Akismet om spam te verminderen. Meer informatie over hoe uw reactiegegevens worden verwerkt.