Delphi - URL mentése képekkel együtt

forráskód letöltése
A TWebBrowser komponens vagy egy API függvény segítségével saját gépünkre lementhetünk egy tetszőleges Web oldalt. Mentéskor azonban csak maga a HTML oldal kerül lemezre, a hozzá tartozó képek nem. Ebben a példában erre a problémára keresünk megoldást. Megnézzük, hogy miként lehet a HTML kóddal együtt a hozzá tartozó képeket is lementeni.
A megadott Web oldalt egy TWebBrowser komponens segítségével jelenítjük meg, ehhez a komponens Navigate metódusát kell használnunk.
WebBrowser1.Navigate(Edit1.Text);
A megjelenített oldal lemezre mentését több lépésben tudjuk megvalósítani. Először elmentjük magát a HTML kódot.
A kódhoz a WebBrowser1 objektum Document property-jén keresztül férhetünk hozzá. A mentést egy TFileStream segítségével végezzük el.
ps:=WebBrowser1.Document as IPersistStreamInit;
fs:=TFileStream.Create(Edit2.Text,fmCreate);
...
sa:=TStreamAdapter.Create(fs,soReference) as IStream;
ps.Save(sa,True);
A kód mentése után jöhetnek a képek. A Windows által használt mentési mechanizmust próbáljuk utánozni. A megadott nevű állományba kerül a HTML kód. A képek számára létrehozunk egy új könyvtárt, melynek az X_elemei elnevezést adjuk.
A könyvtár nevének meghatározásához szükségünk van a kódot tartalmazó állomány nevére, kiterjesztés nélkül. Ennek meghatározásra elkészítettük a GetHTMLFileName függvényt.
function GetHTMLFileName: String;
A függvény az állománynevet az Edit2.Text értékéből olvassa ki, ezért nincs szükség bemenő paraméterre.
A WebBrowser1 objektumban megjelenített képeket az alábbi módon érhetjük el:
Images:=WebBrowser1.OleObject.Document.Images;
Az Images egy OleVariant típusú változó. A fenti értékadás hatására, értéke egy kollekció lesz, amely tartalmazza a Web oldalon található képek adatait.
A kollekció egy elemét az Item(i) metóduson keresztül érhetjük el.
for i:=0 to Images.length-1 do
  DownloadFile(Images.Item(i).Src,ElemekDir+'\'+GetFileNameFromURL(Images.Item(i).Src));
Ami számunkra fontos, az a kép URL címe. Ezt az Src tagból olvashatjuk ki.
Készítettünk egy eljárást, amely egy megadott URL címet lement a megadott nevű állományba, ez a függvény a DownloadFile.
procedure DownloadFile(URL, FileName: String);
A mentéshez a már korábbi példákban sokszor használt InternetOpen, InternetOpenURL, valamint InternetReadFile API függvényeket használjuk.
Mivel a képeket a létrehozott könyvtárba mentjük el, csak a képeket tartalmazó állományok neveire van szükségünk.
A GetFileNameFromURL függvény egy megadott URL címből meghatározza az állomány nevét és kiterjesztését.
function GetFileNameFromURL(URL: String): String;
Most már letöltöttük a Web oldalt és a hozzá tartozó képeket is. A probléma az, hogy a HTML kód még mindig a képek régi helyére hivatkozik. Módosítanunk kell ezeket a hivatkozásokat is. A módosításokat a ModifySRC eljárás végzi el.
procedure ModifySRC;
A feldolgozáshoz mindössze a HTML állományunk adott, amelyet egy TStringList segítségével betöltünk a memóriába.
sl.LoadFromFile(Edit2.Text);
A TStringList Text property-jét használva, a szöveget karakterenként végignézzük és keressük benne az „src=” HTML tagot. Az egyenlőségjel után mindig egy hivatkozásnak kell szerepelnie, amely egy képre mutat. Ez lehet idézőjelek között, vagy azok nélkül.
Ha a Text-ben megtaláltuk a bejegyzést, akkor az egyenlőség jel utáni karaktertől kezdődően fel kell jegyeznünk minden karaktert, egészen addig, amíg idézőjelet, vagy szóközt nem találunk.
A megtalált képhivatkozásokat feljegyezzük a ChangeList, TStringList típusú változóba.
A hivatkozások megtalálása után kicseréljük azokat az új könyvtárnak megfelelően.
for i:=0 to ChangeList.Count-1 do
  if ChangeList[i][1]='"' then
  sl.Text:=StringReplace(sl.Text,ChangeList[i],'"'+GetHTMLFileName+'_elemei/'+GetFileNameFromURL(ChangeList[i])+'"',[rfReplaceAll])
  else
    sl.Text:=StringReplace(sl.Text,ChangeList[i],GetHTMLFileName+'_elemei/'+GetFileNameFromURL(ChangeList[i]),[rfReplaceAll]);
A cseréhez a StringReplace függvényt használjuk fel.
Végül a módosított TStringList tartalmát újra elmentjük, és ezzel készen vagyunk.