Parse HTML to retrieve image <img /> and display in/om vb.net form


I have received previous help to parse innerText from HTML and display in vb.net forms. Now I need code to parse HTML and retrieve an image and display it in/on a vb.net form. How do I do it and what is the code necessary to do this?

I am including vb.net code that I use to pase and display innerText values. I assume there is a similar way to retrieve and display images, or am I wrong?

Thanks!
Dim elementCollection As IHTMLElementCollection = Doc.getElementsByTagName("div")
        For Each element As IHTMLElement In elementCollection
            If element.id = "content_main_qn" Then
                TextBox1.Text = element.innerText
                Exit For
            End If
        Next

        Dim elementCollection2 As IHTMLElementCollection = Doc.getElementsByTagName("span")
        For Each element As IHTMLElement In elementCollection2

            Select Case element.id

                Case "lblHighprice"
                    TextBox4.Text = element.innerText

                Case "lblVolume"
                    TextBox5.Text = element.innerText

            End Select

        Next

Open in new window

investalertAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

MedievalWarriorCommented:
Quote: " I assume there is a similar way to retrieve and display images, or am I wrong? "

Yes. You can use the (images) property collection of the IHTMLDocument the elements type IHTMLImgElement

For Each img As IHTMLImgElement In Doc.images
  Debug.Print img.href
Next

Open in new window

0
investalertAuthor Commented:
OK, that gives me a list of the images in the Immediate window ... now how do I select the one I want and display it in/on my vb.net windows form? Thanks, we're making progress!
0
MedievalWarriorCommented:
You can use WebClient to get the bytes of the image from the url and display it in your picturebox
Imports System.Net
Imports System.IO

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PictureBox1.Image = GetImage("http://l1.yimg.com/a/i/ww/news/2011/03/30/033011mercury.jpg")
    End Sub

    Private Function GetImage(ByVal url As String) As Image
        Dim data() As Byte
        Dim img As Image = Nothing
        Using wc As New WebClient
            data = wc.DownloadData(url)
        End Using
        If data.Length > 0 Then
            Using ms As New MemoryStream(data)
                img = Image.FromStream(ms)
            End Using
        End If
        Return img
    End Function
 
End Class

Open in new window

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

investalertAuthor Commented:
When I run your code, it shows the image from your sample URL. But when I load my URL, no image is displayed. The html element I want is:

 <img width="425" height="380" src="/chartfx62/temp/CFT0330_09590038449.png" complete="complete"/>

What needs to be changed to display this image?

Thanks
0
MedievalWarriorCommented:
The URL is missing some parts like the webroot (http://www.site.com/chartfx62/temp/CFT0330_09590038449.png
0
investalertAuthor Commented:
Hmmmm . . .  here is the URL that brings up the image page:

http://www.schaeffersresearch.com/streetools/indicators/open_interest_configuration.aspx?ticker=bby&expirationmonth=May

Then in IE8 I used F12 to go to the developer tool and clicked the chart image I wanted and the element in my previous comment was highlighted. So how to I make the connection from the URL to the "png"?
0
MedievalWarriorCommented:
You have to add http://www.schaeffersresearch.com/ then append the url returned to that but because that website creates temp images for viewing the address to the image will be different each time you visit the page so you have to navigate to that site first and then get the image url.

As you can see yours was at the time you viewed the page:
/chartfx62/temp/CFT0330_09590038449.png

When I viewed the page it was different
/chartfx62/temp/CFT0330_103538141AA.png

If you want to view it then you can append it to the main address
http://www.schaeffersresearch.com/chartfx62/temp/CFT0330_09590038449.png
0
investalertAuthor Commented:
Makes sense and I tried adding Form2 with PictureBox1. When I run that attached code, I still do not get an image in the picture box (the form is blank). So I assume I am missing some additional code that ties the URL and image element together.

I have two forms with Form1 retrieving some innerText from one web site and then Form2 showing an image from our subject web site.

Does this make a difference?
Public Class Form1

     "My other code here"

End Class

==================

Public Class Form2

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PictureBox1.Image = GetImage("http://www.schaeffersresearch.com/")

        Dim Doc As mshtml.IHTMLDocument
        Doc = New mshtml.HTMLDocumentClass
        Dim elementCollection As IHTMLElementCollection = Doc.getElementsByTagName("img")

        For Each img As IHTMLImgElement In Doc.images
            Debug.Print(img.href)
        Next

    End Sub

    Private Function GetImage(ByVal url As String) As Image
        Dim data() As Byte
        Dim img As Image = Nothing
        Using wc As New WebClient
            data = wc.DownloadData(url)
        End Using
        If data.Length > 0 Then
            Using ms As New MemoryStream(data)
                img = Image.FromStream(ms)
            End Using
        End If
        Return img
    End Function

End Class

Open in new window

0
MedievalWarriorCommented:
You have to specify the full location to the image.
PictureBox1.Image = GetImage("http://www.schaeffersresearch.com/chartfx62/temp/CFT0330_09590038449.png")

Open in new window

0
investalertAuthor Commented:
OK, started a new VB 2010 project wtih one form and put the attached code in it. Then worked out all the errors but it still won't show any image in PictureBox1. The code line:

Doc = New mshtml.HTMLImg

doesn't look right to me. I added the MSHTML reference but still won't run. Can you get this code to run and display and image in Form1?

Or is it because the image "src" number changes each time the stock symbol is queried? Then we need to parse maybe ussing RegEx to find the new number?
Imports mshtml
Imports System.Net
Imports System.IO

Public Class Form2

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PictureBox1.Image = GetImage("http://www.schaeffersresearch.com/chartfx62/temp/CFT0330_09590038449.png")

        Dim Doc As mshtml.IHTMLDocument
        Doc = New mshtml.HTMLImg
        Dim elementCollection As IHTMLElementCollection = Doc.getElementsByTagName("img")

        For Each img As IHTMLImgElement In Doc.images
            Debug.Print(img.href)
        Next

    End Sub

    Private Function GetImage(ByVal url As String) As Image
        Dim data() As Byte
        Dim img As Image = Nothing
        Using wc As New WebClient
            data = wc.DownloadData(url)
        End Using
        If data.Length > 0 Then
            Using ms As New MemoryStream(data)
                img = Image.FromStream(ms)
            End Using
        End If
        Return img
    End Function

End Class

Open in new window

0
investalertAuthor Commented:
BTW, I get the following in the IMMEDIATE Window when the above code runs:

A first chance exception of type 'System.ArgumentException' occurred in System.Drawing.dll
0
MedievalWarriorCommented:
The link to that image changes every visit to the site.

1) Navigate to the page that has the image, wait for the page to load.

2) Enumerate the image urls and parse the one you need.
ex. /chartfx62/temp/CFT0331_0948223685A.png

3) Take the parsed url from above and append the websites root  
ex. http://www.schaeffersresearch.com/chartfx62/temp/CFT0331_0948223685A.png

4) When you have the full url then you can pass that into GetImage().
ex GetImage("http://www.schaeffersresearch.com/chartfx62/temp/CFT0331_0948223685A.png")


Since this image url is only temporary it changes each time you visit the site so you have to parse it out like above.
0
investalertAuthor Commented:
Sorry, but I started down path and now am really confused. My other code I have worked on to scrape text and numbers from my favorite web sites is working fine, but this code to scrape images/charts has me stumped.

I have Form1 as a Windows form with PictureBox1 on it. Are there any properties I am missing or other controls needed?

I tried your last suggestion and incorporated them into the code below, but no results. What is wrong with the coding in my routine?


Imports mshtml
Imports System.Net
Imports System.IO

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        PictureBox1.Image = GetImage("http://ww.schaeffersresearch.com/streetools/indicators/open_interest_configuration.aspx?chartfx62/temp/CFT0331_1019152A253.png")

        Dim doc As HTMLElementCollection
        doc = New mshtml.HTMLElementCollection
        Dim img As HTMLElementCollection = doc.getElementsByTagName("div")

        For Each img In doc.images
            Debug.Print(img.href)
        Next

    End Sub

    Private Function GetImage(ByVal url As String) As Image
        Dim data() As Byte
        Dim img As Image = Nothing
        Using wc As New WebClient
            data = wc.DownloadData(url)
        End Using
        If data.Length > 0 Then
            Using ms As New MemoryStream(data)
                img = Image.FromStream(ms)
            End Using
        End If
        Return img
    End Function

End Class

Open in new window

0
CodeCruiserCommented:
The page you are viewing is
http://ww.schaeffersresearch.com/streetools/indicators/open_interest_configuration.aspx

and the img's src is
/chartfx62/temp/CFT0330_09590038449.png

So the GetImage should be passed

"http://ww.schaeffersresearch.com/streetools/indicators" & Doc.Images(0).href
0
investalertAuthor Commented:
I have tried all suggestions and still cannot get the code to render a solution. I am using vb 2010 and when I set a breakpoint at the beginning of the sub to step through each line, I get a blank form (with PictureBox1) loaded and cannot step through the remainder of the code to see the values of the variables nor see the sequence of steps followed during the execution. I believe my routine logic is flawed, but I can seem to find the fault.

Please run the code to see if your suggestions work. Thanks!
0
Anurag AgarwalPython DeveloperCommented:
Hi investalert,

Your code still uses the image URL which will never get an image as the image name changes after every request to that page.

I have modified the code and now it is working. What I did is first get the whole site data as string and then from that string I fetched the URL of that image. Then again downloaded that image and shown in picture box. Have a look and let me know if you face any problem.

Don't copy blindly the code as the namespaces will be different in your code. Just copy the functions.

Regards,
Anurag
Imports mshtml
Imports System.Net
Imports System.IO


Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PictureBox1.Image = GetImage("http://www.schaeffersresearch.com/streetools/indicators/open_interest_configuration.aspx?ticker=bby&expirationmonth=May")

        Dim doc As HtmlElementCollection
        doc = New mshtml.HTMLElementCollection

        Dim img As HtmlElementCollection = doc.getElementsByTagName("div")

        For Each img In doc.images

            Debug.Print(img.href)
        Next

    End Sub

    Private Function GetImage(ByVal url As String) As Image
        Dim data() As Byte
        Dim dataString As String
        Dim index As Integer
        Dim endIndex As Integer
        Dim imageURL As String

        imageURL = ""

        Dim img As Image = Nothing
        Using wc As New WebClient
            dataString = wc.DownloadString(url)
        End Using
        If dataString.Length > 0 Then
            index = dataString.IndexOf("<IMG SRC=")
            If index > 0 Then
                index = dataString.IndexOf("/chartfx62/temp/", index)
                If index > 0 Then
                    endIndex = dataString.IndexOf(".png", index)
                    imageURL = dataString.Substring(index, endIndex - index + 4)
                End If
            End If
        End If

        url = "http://www.schaeffersresearch.com" + imageURL

        Using wc As New WebClient
            data = wc.DownloadData(url)
        End Using

        If data.Length > 0 Then
            Using ms As New MemoryStream(data)
                img = Image.FromStream(ms)
            End Using
        End If

        Return img
    End Function


End Class

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
investalertAuthor Commented:
I was focused on why the code between the call to the function and the function itself when it has nothing to do with getting the image. Taking that out of the equation let me fucus on the procedure to get the images from the URL and then parse the one I wanted. Can now add code to allow user to select image and add it to the URL to give the user options. I probably wasn't as clear in my objective as I should have been at the outset. I appreciate the experts patience and explanations.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.