VB .NET - Obtendo informações de uma web page
Você já precisou obter informações de uma site da web ? |
Se você é um programador Visual Basic (ou C#) provavelmente se deparou ou vai deparar com essa tarefa, afinal hoje praticamente quase todas as informações são acessadas através de uma página web.
Neste artigo eu procuro apresentar alternativas viáveis de como você pode realizar esta tarefa usando a linguagem VB .NET (em outro artigo mostrarei a mesma coisa usando a linguagem C#).
Para acompanhar os exemplos deste artigo você vai precisar usar o Visual Basic 2010 Express Edition.
Um pouco de teoria
A plataforma .NET fornece duas classes presentes no namespace System.NET que podemos usar para podermos interagir diretamente com servidores usando HTTP. São elas:
Para podermos usar os recursos da classe WebRequest podemos usar as classes HttpWebRequest e HttpWebResponse que fornecem implementações específicas destas classes.
Dessa forma a classe HttpWebRequest fornece suporte para as propriedades e métodos definidos na classe WebRequest e para propriedades e métodos adicionais que permitem interagir usando o protocolo HTTP.
- O método Create()
de uma instância da classe WebRequest para iniciar os objetos HttpWebRequest;
- O método GetResponse() realiza uma
requisição síncrona através da propriedade RequestUri,
retornando um objeto HttpWebResponse contendo a
resposta de uma requisição;
- O método GetRequestStream() obtém um objeto
stream usado para escrever os dados da requisição;
Usando estas duas classes, temos tudo que precisamos para fazer o download de uma página Web completa em um stream ou postar dados para uma URL.
Criando o projeto
Abra o Visual Basic 2010 Express Edition e crie um novo projeto (File-> New Project) do tipo Windows Forms Application com o nome ExtraindoDadosWeb;
A seguir vamos incluir uma classe no projeto via menu Project -> Add Class com o nome Web.vb e definir o seguinte código nesta classe:
1- Namespaces
Imports System.Net
Imports System.Text.RegularExpressions
Imports System.IO
Imports System.Data
2- Método RequestDadosWeb que retorna uma string contendo o código de uma URL definida:
Public Function RequestDadosWeb(ByVal pstrURL As String) As String Dim oWebRequest As WebRequest Dim oWebResponse As WebResponse = Nothing Dim strBuffer As String = "" Dim objSR As StreamReader = Nothing 'conecta com o website Try oWebRequest = HttpWebRequest.Create(pstrURL) oWebResponse = oWebRequest.GetResponse() 'Le a resposta do web site e armazena em uma stream objSR = New StreamReader(oWebResponse.GetResponseStream) strBuffer = objSR.ReadToEnd Catch ex As Exception Throw ex Finally objSR.Close() oWebResponse.Close() End Try Return strBuffer End Function |
A seguir vamos mostrar como usar este método para obter informações de uma página Web.
Inclua no formulário form1.vb, a partir da ToolBox, os controles TextBox(txtDados Multiline=True), Button (btnObterPagina), TextBox(txtUrl) conforme o leiaute abaixo:
No evento Click do botão de comando - Obter Página - incluo código abaixo:
Private Sub btnObterPagina_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnObterPagina.Click Try Dim wc As New Web txtDados.Text = wc.RequestDadosWeb(txtUrl.Text.Trim) Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub |
Executando o projeto iremos obter:
Podemos a partir das informações obtidas extrair outras informações realizando um filtro no arquivo recebido. Para ilustrar isso vamos extrair os links de uma página web.
Para isso temos que incluir na nossa classe Web.vb os métodos ExtrairLinks e MapearUrl conforme o código a seguir:
Public Function ExtrairLinks(ByVal url As String) As DataTable Dim dt As New DataTable dt.Columns.Add("LinkTexto") dt.Columns.Add("LinkUrl") Dim wc As New WebClient Dim html As String = wc.DownloadString(url) Dim links As MatchCollection = Regex.Matches(html, "<a.*?href=""(.*?)"".*?>(.*?)</a>") For Each match As Match In links Dim dr As DataRow = dt.NewRow Dim matchUrl As String = match.Groups(1).Value 'Ignora todos os links âncoras If matchUrl.StartsWith("#") Then Continue For End If 'Ignora todas as chamadas javascript If matchUrl.ToLower.StartsWith("javascript:") Then Continue For End If 'Ignora todos os links de email If matchUrl.ToLower.StartsWith("mailto:") Then Continue For End If 'Para links internos, constroi a url mapeada para o endereço base If Not matchUrl.StartsWith("http://") And Not matchUrl.StartsWith("https://") Then matchUrl = MapearUrl(url, matchUrl) End If 'Inclui o link no datatable dr("LinkUrl") = matchUrl dr("LinkTexto") = match.Groups(2).Value dt.Rows.Add(dr) Next Return dt End Function Public Function MapearUrl(ByVal enderecoBase As String, ByVal caminhoRelativo As String) As String Dim u As New System.Uri(enderecoBase) If caminhoRelativo = "./" Then caminhoRelativo = "/" End If If caminhoRelativo.StartsWith("/") Then Return u.Scheme + Uri.SchemeDelimiter + u.Authority + caminhoRelativo Else Dim Caminho_Consulta As String = u.AbsolutePath ' Se o enderecoBase contem o nome do arquivo como ..../Something.aspx ' ajusta o nome do arquivo Caminho_Consulta = Caminho_Consulta.Split("?")(0).TrimEnd("/") If Caminho_Consulta.Split("/")(Caminho_Consulta.Split("/").Count - 1).Contains(".") Then Caminho_Consulta = Caminho_Consulta.Substring(0, Caminho_Consulta.LastIndexOf("/")) End If enderecoBase = u.Scheme + Uri.SchemeDelimiter + u.Authority + Caminho_Consulta 'se o caminhoRelativo contém ../ então ' ajusta o enderecoBase While caminhoRelativo.StartsWith("../") caminhoRelativo = caminhoRelativo.Substring(3) If enderecoBase.LastIndexOf("/") > enderecoBase.IndexOf("//" + 2) Then enderecoBase = enderecoBase.Substring(0, enderecoBase.LastIndexOf("/")).TrimEnd("/") End If End While Return enderecoBase + "/" + caminhoRelativo End If End Function |
O método ExtrairLInks obtêm os links da URL definida salvando as informações em um DataTable e utiliza o método MapearUrl que faz os ajustes nos nomes extraídos:
Para testar a nova funcionalidade vamos incluir mais controle Button (btnLinks), uma caixa de Texto (txtLinks0) e um controle DataGridView(dgvDados) conforme a figura abaixo:
No evento Click do botão Obter Links inclua o código a seguir:
Private Sub btnLinks_Click(sender As System.Object, e As System.EventArgs) Handles btnLinks.Click Dim wc As New Web dgvDados.DataSource = wc.ExtrairLinks(txtLinks.Text.Trim) End Sub |
Executando o projeto e fornecendo a URL, após clicar no botão Obter Links teremos o seguinte resultado:
Que tal obter imagens de páginas web ?
Vamos fazer isso primeiro alterando o leiaute do formulário form1.vb, incluindo dois controles Button(btnImage1 e btnImage2) e dois controles PictureBox conforme o leiaute abaixo:
Vamos agora incluir na classe Web.vb o método RequestImagemWeb que retorna uma imagem obtida do website conforme a seguir:
Public Function RequestImagemWeb(ByVal pstrURL As String, ByVal imagem As String) As String Dim oWebRequest As WebRequest Dim oWebResponse As WebResponse 'conecta com o website oWebRequest = HttpWebRequest.Create(pstrURL) oWebResponse = oWebRequest.GetResponse() 'Le a resposta do website e armazena em uma stream Dim objStream As Stream objStream = oWebResponse.GetResponseStream Dim inBuf(100000) As Byte Dim bytesToRead As Integer = CInt(inBuf.Length) Dim bytesRead As Integer = 0 While bytesToRead > 0 Dim n As Integer = objStream.Read(inBuf, bytesRead, bytesToRead) If n = 0 Then Exit While End If bytesRead += n bytesToRead -= n End While Dim fstr As New FileStream(imagem, FileMode.OpenOrCreate, FileAccess.Write) fstr.Write(inBuf, 0, bytesRead) objStream.Close() fstr.Close() oWebResponse.Close() 'retorna a imagem Return imagem End Function |
No evento Click de cada um dos botões - Obter Imagem - inclua o código abaixo:
Private Sub btnImagem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImagem1.Click Dim strArquivo As String Dim wc As New Web strArquivo = wc.RequestImagemWeb("http://www.macoratti.net/images/maco1b.gif", "maco1b.gif") PictureBox1.Image = Image.FromFile(strArquivo) End Sub Private Sub btnImagem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImagem2.Click Dim strArquivo As String Dim wc As New Web strArquivo = wc.RequestImagemWeb("http://www.macoratti.net/images/dvdnet2.gif", "dvdnet2.gif") PictureBox2.Image = Image.FromFile(strArquivo) End Sub |
O código acima recebe a imagem do website e a exibe em um controle PictureBox.
Executando o projeto e clicando em cada um dos botões de comando teremos:
Configurando o acesso via proxy
Tudo o que foi mostrado aqui vai falhar se você estiver sob um proxy que requeira uma autenticação para acessar as páginas usadas.
Mas podemos facilmente contornar o problema configurando as propriedades Proxy e usando a classe NetWorkCredential(username,password) para definir o nome do usuário e a senha do proxy.
A propriedade Proxy define ou obtém o proxy da rede e a classe NetWorkCredential permite fornecer as credenciais usadas para acessar o proxy.
No nosso caso, supondo que exista um proxy configurado como : proxy.com.br na porta 80, e que o usuário usado fosse macoratti com senha numsey, bastaria incluir as seguintes linhas de código para acessar as páginas:
Dim
wp As WebProxy = New WebProxy("proxy.com.br", 80)
wp.Credentials = New NetworkCredential("macoratti",
"numsey")
request.Proxy = wp
E assim vimos como extrair informações e imagens de páginas web usando as classe WebRequest e WebResponse.
pegue o projeto completo aqui: ExtraindoDadosWeb.zip
Filipenses 2:14
Fazei todas as coisas sem murmurações nem contendas;Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Visual Studio - Dica de produtividade - Quick Launch - Macoratti.net
Visual Studio - Dica de produtividade - Nuget - Macoratti.net
C# - Novidades da versão 7.0 - Macoratti
C# - O tipo Dynamic - Macoratti.net
NET HttpWebRequest x WebClient x HttpClient - Macoratti
C# - Fazendo requisições na web - Macoratti.net
VB .NET - Download de arquivos com WebClient - Macoratti
Download de arquivos na web - Macoratti.net