<pedrocorreia.net ⁄>
corner
<mySearch ⁄> <mySearch ⁄>

corner
 
corner
<mySnippets order="rand" ⁄> <mySnippets order="rand" ⁄>

corner
 
corner
<myContacts ⁄> <myContacts ⁄>

<email ⁄>


pc@pedrocorreia.net

<windows live messenger ⁄>


pedrojacorreia@hotmail.com

<myCurriculum type="pdf" ⁄>


Download
corner
 
corner
<myBlog show="last" ⁄> <myBlog show="last" ⁄>

corner
 
corner
<myNews show="rand" ⁄> <myNews show="rand" ⁄>

corner
 
corner
<myNews type="cat" ⁄> <myNews type="cat" ⁄>

corner
 
corner
<myQuote order="random" ⁄> <myQuote order="random" ⁄>

No one ever died for my sins in hell, as far as I can tell, at least the ones I got away with
corner
 
corner
<myPhoto order="random" ⁄> <myPhoto order="random" ⁄>

<pedrocorreia.net ⁄>
corner
 
corner
<myAdSense ⁄> <myAdSense ⁄>

corner
 
corner
<myVisitorsMap ⁄> <myVisitorsMap ⁄>

corner
 
 

<Diz que é uma espécie de IMDB API ⁄ >




clicks: 10183 10183 2008-05-12 2008-05-12 goto mySnippets mySnippets asp.net  Download  Bookmark This Bookmark This



Chamar a este snippet uma API do IMDB, é no minimo dos minimos, um pouco discutivel, quiçá uma heresia ^_^'' Que eu saiba o IMDB não fornece nenhuma API ou alguma forma de aceder aos seus preciosos conteúdos, pelo menos de uma forma gratuíta, porque há uma versão do IMDB que é a pagar, mas desconheço se fornecem esse serviço ou não.


Porém ver a informação de um filme no IMDB (Internet Movie Database), é tão simples como digitar o endereço correcto do filme num browser e visualizar aí toda a informação respectiva a esse mesmo filme.


Este snippet vai recorrer a isso, exactamente, vai tão simplesmente "agarrar" todo o conteúdo html da página do filme e vai fazendo o parsing dessa informação.




Se analisarmos o código da página vemos que é dividida em secções, por ex. para sabermos qual é o filme que estamos a ver temos a tag <title>


<title>Wo hu cang long (2000)</title>




Por ex. na parte da duração do filme temos este código


<div class="info">
<h5>Runtime:</h5>
120 min
</div>




Já podem ver onde é que quero chegar, vamos buscar o código html completo da página e vamos "andando" ao longo do código indo a partes especificas e retirando a informação, por ex. no caso da duração do filme "<h5>Runtime:</h5>", vamos percorrer a string directamente para este ponto, "posicionamos o ponteiro" no fim da tag <h5> e vamos lendo até encontrar o 1º </div>, quando chegarmos a esse ponto significa que já não existirá mais dados relativos à duração; and so on, and so on ... Isto é o caso mais genérico, depois consoante a informação que pretendemos obter, tanto se poderá enquadrar neste padrão como não, caso caso é um caso; por ex. se quisermos obter a lista de actores é algo semelhante porém teremos de iterar para obter toda a listagem de actores (tanto o nome real como o nome da personagem), mas claro que isto vai depender da informação que pretendemos obter.




- Como sempre cá está o style.css:

  1. *{padding: 0; margin: 0;}
  2.  
  3. body{
  4. font-family: Verdana, Tahoma, Arial, sans-serif;font-size: 62.5%;
  5. color: #000;background: #fff;text-align: left;margin-top: .5em;
  6. }
  7. div#container,div#search{
  8. margin: 0 auto;
  9. width: 80em;
  10. padding: .8em;
  11. border: solid 0.6em #3F4C6B;
  12. overflow:hidden;
  13. }
  14. div#search{text-align: center;}
  15.  
  16. label, span, strong{font-size: 1.2em;color: #D01F3C;}
  17. strong{color: #356AA0 !important; font-weight: 900;}
  18.  
  19. input{border: solid .1em #FF7400;color: #B02B2C;background-color: #FFFF88;}
  20.  
  21. input#txtFilmID{font-size: 2.8em;border-color: #FF7400;text-align: center;}
  22.  
  23. input#btnFilmViewStats{
  24. background-color: #356AA0;
  25. font-size: 1.8em;color: #F9F7ED;
  26. }
  27.  
  28. div#FilmInfo{
  29. float: left;
  30. padding: .6em;line-height: 1.6em;width: 65em;
  31. border: solid 0.4em #6BBA70;
  32. text-align: justify;
  33.  
  34. }
  35. div#FilmPoster{
  36. float: right;
  37. padding: .6em;right: .8em;top: .8em;
  38. border: solid 0.4em #6BBA70;
  39. }
  40.  
  41. a{text-decoration: none;color: #FF7400;}
  42. a:hover{text-decoration: underline;}




- SoCalledImdbApi.vb, este será a nossa Class principal, será aqui que vamos ler o conteúdo da página e fazer o parsing da informação; neste snippet não recorri ao uso de expressões regulares (muito pelo facto de que é uma área que não me sinto muito à vontade), muito provavelmente seria o mais indicado, se houver alguma alma caridosa que queira fornecer as expressões regulares esteja à vontade :D; para este snippet usei VB.NET; a conversão para C# não será complicado, existem muito conversores online e gratuitos;

  1. Imports Microsoft.VisualBasic
  2. Imports System.Net
  3. Imports System.IO
  4. Imports System.Text
  5.  
  6. ''' <summary>
  7. ''' Class que permite obter algumas informações
  8. ''' sobre um filme em www.imdb.com
  9. ''' </summary>
  10. ''' <author>pedrocorreia.net</author>
  11. Public Class SoCalledImdbApi
  12. Private Const _imdb_url As String = "http://www.imdb.com"
  13. Private _movie_url As String = ""
  14. Private _movie_id As String = ""
  15. Private _html As String = ""
  16.  
  17. ''' <summary>
  18. ''' Método construtor
  19. ''' </summary>
  20. ''' <param name="movie_id">ID do filme, formato "tt0000000"</param>
  21. Public Sub New(ByVal movie_id As String)
  22. If Me._IsValid(movie_id) Then
  23. MovieID = movie_id
  24. Me._SetMovieURL()
  25. Me.FetchInfo()
  26. Else
  27. Throw New Exception("IMDB_API_INVALID_MOVIE_ID")
  28. End If
  29. End Sub
  30. ''' <summary>
  31. ''' Obter HTML
  32. ''' </summary>
  33. Private Sub FetchInfo()
  34. If Me._IsValid(Me._movie_id) Then
  35. Dim pedido As WebRequest = WebRequest.Create(Me._movie_url)
  36. Dim resposta As HttpWebResponse = CType(pedido.GetResponse(), HttpWebResponse)
  37. Dim dataStream As Stream = resposta.GetResponseStream()
  38. Dim reader As New StreamReader(dataStream)
  39. Me._html = reader.ReadToEnd()
  40. Else
  41. Throw New Exception("IMDB_API_INVALID_MOVIE_ID")
  42. End If
  43. End Sub
  44.  
  45. ''' <summary>
  46. ''' Getter/ Setter ID do filme
  47. ''' Formato: tt0000000
  48. ''' </summary>
  49. ''' <value>ID do filme, formato "tt0000000"</value>
  50. ''' <returns>ID do filme, formato "tt0000000"</returns>
  51. Public Property MovieID() As String
  52. Get
  53. Return Me._movie_id
  54. End Get
  55. Set(ByVal value As String)
  56. Me._movie_id = value
  57. End Set
  58. End Property
  59.  
  60. ''' <summary>
  61. ''' Obter titulo
  62. ''' </summary>
  63. ''' <returns>String</returns>
  64. Public Function GetMovieTitle() As String
  65. GetMovieTitle = Me._GetGenericInfo("<title>", "</title>")
  66. End Function
  67.  
  68. ''' <summary>
  69. ''' Obter poster
  70. ''' </summary>
  71. ''' <returns>String</returns>
  72. ''' <remarks>Devolve tag imagem completa</remarks>
  73. Public Function GetMoviePoster() As String
  74. GetMoviePoster = Me._GetGenericInfo("<div class=""photo"">", "</div>")
  75. End Function
  76.  
  77. ''' <summary>
  78. ''' Obter idioma
  79. ''' </summary>
  80. ''' <returns>String</returns>
  81. Public Function GetMovieLanguage() As String
  82. GetMovieLanguage = Me._GetGenericInfo("<h5>Language:</h5>", "</div>")
  83. End Function
  84.  
  85. ''' <summary>
  86. ''' Obter género
  87. ''' </summary>
  88. ''' <returns>String</returns>
  89. Public Function GetMovieGenre() As String
  90. GetMovieGenre = Me._GetGenericInfo("<h5>Genre:</h5>", "</div>")
  91. End Function
  92.  
  93. ''' <summary>
  94. ''' Obter tagline
  95. ''' </summary>
  96. ''' <returns>String</returns>
  97. Public Function GetMovieTagline() As String
  98. GetMovieTagline = Me._GetGenericInfo("<h5>Tagline:</h5>", "</div>")
  99. End Function
  100.  
  101. ''' <summary>
  102. ''' Obter nome do Realizador
  103. ''' </summary>
  104. ''' <returns>String</returns>
  105. Public Function GetMovieDirector() As String
  106. GetMovieDirector = Me._GetGenericInfo("<h5>Director:</h5>", "</div")
  107. End Function
  108.  
  109. ''' <summary>
  110. ''' Obter realizador
  111. ''' </summary>
  112. ''' <returns>String</returns>
  113. Public Function GetMovieWriters() As String
  114. Dim writers As String = Me._GetGenericInfo("<h5>Writers:</h5>", "</div>")
  115. If String.IsNullOrEmpty(writers) Then
  116. writers = Me._GetGenericInfo("<h5>Writers <a href=""/wga"">(WGA)</a>:</h5>", "</div>")
  117. End If
  118. If String.IsNullOrEmpty(writers) Then
  119. writers = Me._GetGenericInfo("<h5>Writer:</h5>", "</div>")
  120. End If
  121. If String.IsNullOrEmpty(writers) Then
  122. writers = Me._GetGenericInfo("<h5>Writer: <a href=""/wga"">(WGA)</a>:</h5>", "</div>")
  123. End If
  124.  
  125. GetMovieWriters = writers
  126. End Function
  127.  
  128. ''' <summary>
  129. ''' Obter plot
  130. ''' </summary>
  131. ''' <returns>String</returns>
  132. Public Function GetMoviePlot() As String
  133. GetMoviePlot = Me._GetGenericInfo("<h5>Plot:</h5>", "</div")
  134. End Function
  135.  
  136. ''' <summary>
  137. ''' Obter duração
  138. ''' </summary>
  139. ''' <returns>String</returns>
  140. Public Function GetMovieRuntime() As String
  141. GetMovieRuntime = Me._GetGenericInfo("<h5>Runtime:</h5>", "</div")
  142. End Function
  143.  
  144. ''' <summary>
  145. ''' Obter introdução do comentário do utilizador
  146. ''' </summary>
  147. ''' <returns>String</returns>
  148. Public Function GetMovieShortUserComment() As String
  149. GetMovieShortUserComment = Me._GetGenericInfo("<h5>User Comments:</h5>", "<a")
  150. End Function
  151.  
  152. ''' <summary>
  153. ''' Obter comentário completo do utilizador
  154. ''' </summary>
  155. ''' <returns>String</returns>
  156. Public Function GetMovieFullUserComment() As String
  157. GetMovieFullUserComment = Me._GetGenericInfo("Author:", "<div class=""yn""", True)
  158. End Function
  159.  
  160. ''' <summary>
  161. ''' Obter link do filme
  162. ''' </summary>
  163. ''' <returns>String</returns>
  164. Public Function GetMovieLink() As String
  165. GetMovieLink = String.Format("<a href='{0}' target='_blank'>{0}</a>", Me._movie_url)
  166. End Function
  167.  
  168. ''' <summary>
  169. ''' Obter data de estreia do filme
  170. ''' </summary>
  171. ''' <returns>String</returns>
  172. Public Function GetMovieYear() As String
  173. GetMovieYear = Me._GetGenericInfo("<h5>Release Date:</h5>", "<a")
  174. End Function
  175.  
  176. ''' <summary>
  177. ''' Obter nota do filme
  178. ''' </summary>
  179. ''' <returns>String</returns>
  180. Public Function GetUserRating() As String
  181. GetUserRating = Me._GetGenericInfo("<b>User Rating:</b>", "</small>")
  182. End Function
  183.  
  184. ''' <summary>
  185. ''' Obter lista de actores com os nomes reais e os nomes da respectiva personagem
  186. ''' </summary>
  187. ''' <returns>String</returns>
  188. Public Function GetCast() As String
  189. Dim init_tag_actor As String = "<td class=""nm"">", init_tag_char As String = "<td class=""char"">"
  190. Dim end_tag As String = "</td>"
  191. Dim aux_str_actor As String = "", aux_str_char As String = ""
  192. Dim str As New StringBuilder()
  193. Dim cur_pos As Integer = 0, start_at As Integer = 0, end_at As Integer = 0
  194. Dim size_init_tag_actor As Integer = init_tag_actor.Length
  195. Dim size_init_tag_char As Integer = init_tag_char.Length
  196.  
  197. While cur_pos <> -1
  198. 'obter nome do actor
  199. cur_pos = Me._html.IndexOf(init_tag_actor, end_at)
  200. aux_str_actor = "" : aux_str_char = ""
  201.  
  202. If cur_pos > -1 Then
  203. start_at = cur_pos + size_init_tag_actor
  204. end_at = Me._html.IndexOf(end_tag, start_at)
  205. aux_str_actor = _StripTags(Me._html.Substring(start_at, (end_at - start_at)))
  206. End If
  207.  
  208. 'obter nome da personagem
  209. cur_pos = Me._html.IndexOf(init_tag_char, end_at)
  210. If cur_pos > -1 Then
  211. start_at = cur_pos + size_init_tag_char
  212. end_at = Me._html.IndexOf(end_tag, start_at)
  213. aux_str_char = _StripTags(Me._html.Substring(start_at, (end_at - start_at)))
  214. End If
  215.  
  216. If Not String.IsNullOrEmpty(aux_str_actor) Or Not String.IsNullOrEmpty(aux_str_char) Then
  217. str.Append(String.Format("{0} ({1}); ", aux_str_actor, aux_str_char))
  218. End If
  219. End While
  220.  
  221. GetCast = str.ToString()
  222. End Function
  223.  
  224. ''' <summary>
  225. ''' Obter informação genérica
  226. ''' </summary>
  227. ''' <param name="init_tag">Tag onde começa</param>
  228. ''' <param name="end_tag">Tag onde acaba</param>
  229. ''' <param name="include_br">Incluir br?</param>
  230. ''' <returns>String</returns>
  231. Private Function _GetGenericInfo(ByVal init_tag As String, ByVal end_tag As String, Optional ByVal include_br As Boolean = False) As String
  232. Dim size_init_tag As Integer = init_tag.Length
  233.  
  234. Dim start_at As Integer = Me._html.IndexOf(init_tag)
  235. If start_at = -1 Then Return ""
  236.  
  237. start_at = start_at + size_init_tag
  238. Dim end_at As Integer = Me._html.IndexOf(end_tag, start_at)
  239.  
  240. _GetGenericInfo = _StripTags(Me._html.Substring(start_at, (end_at - start_at)), include_br)
  241. End Function
  242.  
  243. ''' <summary>
  244. ''' Remover e substituir tags html;
  245. ''' </summary>
  246. ''' <param name="txt">String</param>
  247. ''' <returns>String</returns>
  248. Private Function _StripTags(ByVal txt As String, Optional ByVal include_br As Boolean = False) As String
  249. 'limpar tags, à excepção de <img /> e <a />
  250.  
  251. 'uniformizar <br/> e converter <p> para <br>
  252. Dim str As String = txt.Trim().Replace("<p>", "<br/>").Replace("<br>", "<br/>")
  253.  
  254. Dim strip_tags As String = "b,i,u,title,link,small,p,title,div"
  255. Dim splitted_str As String() = strip_tags.Split(New [Char]() {","})
  256. For Each s As String In splitted_str
  257. str = str.Replace(String.Format("<{0}>", s), String.Empty)
  258. str = str.Replace(String.Format("</{0}>", s), String.Empty)
  259. Next
  260.  
  261. 'se o texto terminar com <br/>, remover
  262. If str.EndsWith("<br/>") Then str = str.Remove(str.LastIndexOf("<br/>"))
  263.  
  264. 'remover todos os <br/>, caso necessário
  265. If include_br = False Then str = str.Replace("<br/>", ". ")
  266.  
  267. 'os links no imdb são relativos, vamos modificá-los para absolutos
  268. If str.Contains("<a") Then
  269. str = str.Replace("href=""", "href=""" & SoCalledImdbApi._imdb_url)
  270. str = str.Replace("<a", "<a target=""_blank"" ")
  271. End If
  272.  
  273. 'caso especial da synopsis e ratings
  274. Dim aux_str As String = String.Format("{0}synopsis", SoCalledImdbApi._imdb_url)
  275. If str.Contains(aux_str) Then str = str.Replace(aux_str, String.Format("{0}synopsis", Me._movie_url))
  276. aux_str = String.Format("{0}ratings", SoCalledImdbApi._imdb_url)
  277. If str.Contains(aux_str) Then str = str.Replace(aux_str, String.Format("{0}ratings", Me._movie_url))
  278. '
  279.  
  280. _StripTags = str
  281. End Function
  282.  
  283. ''' <summary>
  284. ''' Verificar se o ID do filme é válido
  285. ''' </summary>
  286. ''' <param name="movie_id"></param>
  287. ''' <returns>Boolean</returns>
  288. Private Function _IsValid(ByVal movie_id As String) As Boolean
  289. _IsValid = Regex.IsMatch(movie_id, "tt[\d]")
  290. End Function
  291.  
  292. ''' <summary>
  293. ''' Atribuir ID do filme
  294. ''' </summary>
  295. ''' <remarks></remarks>
  296. Private Sub _SetMovieURL()
  297. Me._movie_url = String.Format("{0}/title/{1}/", SoCalledImdbApi._imdb_url, MovieID)
  298. End Sub
  299.  
  300. End Class
  301.  








- Default.aspx.vb, a code-behind file:
  1. Partial Class _Default
  2. Inherits System.Web.UI.Page
  3. Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  4.  
  5. End Sub
  6. Protected Sub btnFilmViewStats_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFilmViewStats.Click
  7.  
  8. 'criar objecto imdb api
  9. Dim imdb As New SoCalledImdbApi(Me.txtFilmID.Text)
  10.  
  11. FilmPoster.InnerHtml = imdb.GetMoviePoster()
  12. lblTitle.Text = imdb.GetMovieTitle()
  13. lblRating.Text = imdb.GetUserRating()
  14. lblDirector.Text = imdb.GetMovieDirector()
  15. lblWriters.Text = imdb.GetMovieWriters()
  16. lblCast.Text = imdb.GetCast()
  17. lblLanguage.Text = imdb.GetMovieLanguage()
  18. lblGenre.Text = imdb.GetMovieGenre()
  19. lblYear.Text = imdb.GetMovieYear()
  20. lblTagLine.Text = imdb.GetMovieTagline()
  21. lblPlot.Text = imdb.GetMoviePlot()
  22. lblRuntime.Text = imdb.GetMovieRuntime()
  23. lblShortComment.Text = imdb.GetMovieShortUserComment()
  24. lblFullComment.Text = imdb.GetMovieFullUserComment()
  25. lblLink.Text = imdb.GetMovieLink()
  26.  
  27. End Sub
  28.  
  29. End Class




- Default.aspx, aqui realçava só que faço uso dos Validators, para não submetermos o campo em branco;
  1. <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" EnableViewState="false" %>
  2.  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml">
  5. <head runat="server">
  6. <title>Diz que é uma espécie de IMDB tiny API?!</title>
  7. <link href="StyleSheet.css" rel="stylesheet" type="text/css" />
  8. </head>
  9. <body>
  10. <form id="form1" runat="server">
  11. <div id="container">
  12. <div id="FilmInfo">
  13. <strong>Titulo: </strong>
  14. <asp:Label ID="lblTitle" runat="server"></asp:Label><br />
  15. <strong>Nota: </strong>
  16. <asp:Label ID="lblRating" runat="server"></asp:Label><br />
  17. <strong>Realizador: </strong>
  18. <asp:Label ID="lblDirector" runat="server"></asp:Label><br />
  19. <strong>Argumentista: </strong>
  20. <asp:Label ID="lblWriters" runat="server"></asp:Label><br />
  21. <strong>Actores: </strong>
  22. <asp:Label ID="lblCast" runat="server"></asp:Label><br />
  23. <strong>Idioma: </strong>
  24. <asp:Label ID="lblLanguage" runat="server"></asp:Label><br />
  25. <strong>Género: </strong>
  26. <asp:Label ID="lblGenre" runat="server"></asp:Label><br />
  27. <strong>Data: </strong>
  28. <asp:Label ID="lblYear" runat="server"></asp:Label><br />
  29. <strong>Tagline: </strong>
  30. <asp:Label ID="lblTagLine" runat="server"></asp:Label><br />
  31. <strong>Enredo: </strong>
  32. <asp:Label ID="lblPlot" runat="server"></asp:Label><br />
  33. <strong>Duração: </strong>
  34. <asp:Label ID="lblRuntime" runat="server"></asp:Label><br />
  35. <strong>Comentário: </strong>
  36. <asp:Label ID="lblShortComment" runat="server"></asp:Label><br />
  37. <strong>Comentário Completo: </strong>
  38. <asp:Label ID="lblFullComment" runat="server"></asp:Label><br />
  39. <strong>Link: </strong>
  40. <asp:Label ID="lblLink" runat="server"></asp:Label><br />
  41. </div>
  42. <div runat="server" id="FilmPoster"></div>
  43. </div>
  44. <br />
  45. <div id="search">
  46. <asp:TextBox ID="txtFilmID" runat="server"></asp:TextBox>
  47. <asp:RequiredFieldValidator ID="RequiredFilmID" runat="server"
  48. ControlToValidate="txtFilmID" Display="Static"
  49. ErrorMessage="ID do Filme" SetFocusOnError="True">*</asp:RequiredFieldValidator>
  50. <asp:Button ID="btnFilmViewStats" runat="server" Text="Obter Dados" />
  51.  
  52. </div>
  53. </form>
  54. </body>
  55. </html>
  56.  





Aqui ficam alguns screenshots ("mouse-click" para aumentar a imagem):

ScreenShot #1:



ScreenShot #2:



ScreenShot #3:



ScreenShot #4:




Qualquer erro/ dúvida, be my guest!









clicks: 10183 10183 2008-05-12 2008-05-12 goto mySnippets mySnippets asp.net  Download  Bookmark This Bookmark This