Accessing the DOM in a Windows 8 WebView
I was recently working on a Windows 8 app that required accessing the DOM to retrieve certain elements from a website, such as images and links, since there wasn’t a feed to pull those information from.
To access the DOM, you obviously need a webview in a C#/XAML application. However, that webview doesn’t have to be visible. If you define the webview as Visibility=”Collapsed”, it will still work without actually displaying anything.
For example (in XAML):
<WebView x:Name="webView" Visibility="Collapsed" Height="1" Width="1" />
After adding the webView, you need to navigate to a page and subscribe to a LoadCompleted handler when its finished loading (in .cs code).
<br></br>
webView.LoadCompleted += webView_LoadCompleted;<br></br>
webView.Navigate(new Uri("http://sertacozercan.com"));```
In the webView_LoadCompleted function, if you need to fire [ScriptNotify](http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.webview.allowedscriptnotifyuris) events, you need to add the page to the list of allowedUris.
List<Uri> allowedUris = new List<Uri>();<br></br>
allowedUris.Add(new Uri("http://sertacozercan.com""));<br></br>
webView.AllowedScriptNotifyUris = allowedUris;```
To get access to the DOM and retrieve values, you need to eval the arguments passed to webView.InvokeScript like below to get the title of the page.
string[] args = { "document.title;" };<br></br>
string foo = webView.InvokeScript("eval", args);```
Arguments can be used to get any element, such as children count, and you can iterate on that.
One important thing to note is the .toString() function when getting the count. You need to convert this back to a numeric value if you want to use it as such.
string[] args = { "document.getElementsByClassName('className')[0].childElementCount.toString();" };<br></br>
string foo = webView.InvokeScript("eval", args);<br></br>
Int32.TryParse(foo, out childCount);```
To retrieve and save images locally, you can use the following code: (you can iterate on the childCount and get all images with certain class names, for example)
<br></br>
Uri source = new Uri(imgSrc);<br></br>
StorageFile destinationFile;<br></br>
try<br></br>
{<br></br>
destinationFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("pic.jpg", CreationCollisionOption.ReplaceExisting);<br></br>
}<br></br>
catch (FileNotFoundException ex)<br></br>
{<br></br>
return;<br></br>
}<br></br>
BackgroundDownloader downloader = new BackgroundDownloader();<br></br>
DownloadOperation download = downloader.CreateDownload(source, destinationFile);<br></br>
await download.StartAsync();<br></br>
ResponseInformation response = download.GetResponseInformation();<br></br>```
After that, if you have a listView, flipView etc, you can add those images or texts you retrieved from the web page to populate your list. Something like this for example:
flipViewData.Items.Add(new FlipViewDataItem("item-"+i,
urlHref,
destinationFile.Path
));
```