¡Hola, chicos!
En uno de los últimos posts de 2018, me gustaría compartir con ustedes un panel de Power BI con información de todos los MVP de Brasil, que están disponibles en el portal. Encuentra un MVP.

¿Qué es MVP?

Para aquellos que no están familiarizados con el programa Microsoft MVP (Most Valuable Professional), reconoce a los líderes comunitarios que han demostrado un compromiso ejemplar para ayudar a otros a aprovechar al máximo su experiencia con las tecnologías de Microsoft. Comparten su pasión excepcional, su conocimiento del mundo real y su experiencia técnica con la comunidad y con Microsoft.

Estos aportes pueden ser a través de:
– Envío de códigos fuente para proyectos.
– Personalmente (conferencias y eventos)
– Ayudar a otros en foros (y por qué no en grupos de Telegram/Whatsapp)
– Creación de contenido (artículos, publicaciones de blogs, vídeos grabados, webcasts, directos)
– Proporcionar comentarios sobre los productos de Microsoft.

Ya había comentado sobre el programa en mi artículo. ¡Felicitaciones al MVP de Microsoft 2018-2019!, que escribí cuando recibí la confirmación de que me había unido al programa, que una de las misiones de estos profesionales es llevar tecnología, innovación y conocimiento a las comunidades donde se ubican (y por qué no, al mundo entero, a través de los contenidos que crean en Internet).

Si quieres ayudar a crear y organizar más eventos de TI en tu región y comenzar a participar y contribuir más a la comunidad técnica de tecnología, una buena manera es buscar uno de estos profesionales que te ayude a lograr este objetivo, para que ambos puedan ayudarse mutuamente en este esfuerzo.

Volviendo al foco: Power BI

Volviendo al foco de Power BI, después de ver el vídeo POWER BI – Conector web. Cómo capturar sitios web con más de una página, de Rafael Mendonça, Tuve la idea de utilizar el conector web de Power BI para Webscrape la información disponible en el Portal MVPs y crear un panel.

En esta etapa, tuve dificultades para capturar el enlace de la foto del perfil y la URL del perfil, ya que esta información permanece como atributos de la etiqueta. EL y imagen y la interfaz de Power BI no permitía hacer esto, solo editar el código M, que se veía así, muy modesto:

let
    Source = Web.BrowserContents("https://mvp.microsoft.com/en-us/MvpSearch?lo=Brazil&kw=&ps=200&pn=1"),
    #"Extracted Table From Html" = Html.Table(Source, {{"Nome", ".profileListItemFullName"}, {"Categoria", ".profileListItemCompetency > .subItemContent"}, {"Pais", ".profileListItemLocation > .subItemContent"}}, [RowSelector=".profileListItem"]),
    #"Changed Type" = Table.TransformColumnTypes(#"Extracted Table From Html",{{"Nome", type text}, {"Categoria", type text}, {"Pais", type text}})
in
    #"Changed Type"

Llamé a Rafael por Whatsapp para ver si había una manera más fácil de capturar esto, sin tener que editar el código M manualmente. Fue entonces cuando aceptó esta idea y creó un panel mucho más completo de lo que imaginaba, incluyendo las últimas 10 contribuciones de cada MVP, que se veía así:

Realmente, el tipo es DEMASIADO bueno en Power BI... Si tiene curiosidad por saber cómo era el código M que usó para crear este informe, siga lo siguiente:

let
    Fonte = Web.BrowserContents("https://mvp.microsoft.com/en-us/MvpSearch?lo=Brazil&sc=e&pn=1"),
    //Extração da informação da quantidade de Registros Encontrados na consulta da página específica de MVPs do Brazil
    #"Tabela extraída de HTML" = Html.Table(Fonte, {{"Coluna 1", ".resultcount"}}),
    #"Tipo Alterado" = Table.TransformColumnTypes(#"Tabela extraída de HTML",{{"Coluna 1", Currency.Type}}),
    /////////////////////////////////////////////////////////////////////
    //Visto que cada página possui no máximo 18 perfis, dividimos a quantidade de perfis por 18 e arredondamos para cima, para encontrar a quantidade de páginas possíveis
    #"Coluna dividida" = Table.TransformColumns(#"Tipo Alterado", {{"Coluna 1", each _ / -18, Currency.Type}}),
    #"Arredondado para Cima" = Table.TransformColumns(#"Coluna dividida",{{"Coluna 1", Number.RoundUp, Currency.Type}}),
    ////////////////////////////////////////////////////////////////////
    #"Personalização Adicionada" = Table.AddColumn(#"Arredondado para Cima", "Personalizar", each {1..[Coluna 1]}),
    #"Colunas Removidas" = Table.RemoveColumns(#"Personalização Adicionada",{"Coluna 1"}),
    #"Personalizar Expandido" = Table.ExpandListColumn(#"Colunas Removidas", "Personalizar"),
    #"Tipo Alterado1" = Table.TransformColumnTypes(#"Personalizar Expandido",{{"Personalizar", type text}}),
    //Adicionado Prefixo à lista criada para montar o Link de cada uma das páginas a serem capturadas.
    #"Prefixo Adicionado" = Table.TransformColumns(#"Tipo Alterado1", {{"Personalizar", each "https://mvp.microsoft.com/en-us/MvpSearch?lo=Brazil&sc=e&pn=" & _, type text}}),
    
    //Função criada Internamente dentro da própria Consulta. Existem 3 Funções internas nessa query par capturar, pagina inicial, ultimas contribuições e dados complementares.
    Funcao = (url as text) =>
    let
        Fonte = Web.BrowserContents(url),
        #"Tabela extraída de HTML" = Html.Table(Fonte, 
        {
            {"Nome", ".profileListItemFullName"}, 
            {"Categoria Premiação", ".profileListItemCompetency > .subItemContent"}, 
            {"País/Região", ".profileListItemLocation > .subItemContent"}, 
            {"Perfil", "#kwmain > div > div > div > div > div.rightRail > div > div:nth-child(2) > div > div.thumb > a", each [Attributes][href]}, 
            {"Imagem", "#kwmain > div > div > div > div > div.rightRail > div > div:nth-child(2) > div > div.thumb > a > img", each [Attributes][src]}
        }, [RowSelector=".profileListItem"]),
        #"Prefixo Adicionado" = Table.TransformColumns(#"Tabela extraída de HTML", {{"Imagem", each "https://mvp.microsoft.com" & _, type text}}),
        #"Prefixo Adicionado1" = Table.TransformColumns(#"Prefixo Adicionado", {{"Perfil", each "https://mvp.microsoft.com" & _, type text}})
    in
        #"Prefixo Adicionado1",
    //Fim da Função
    Convoca = Table.AddColumn(#"Prefixo Adicionado", "FuncaoChamada", each Funcao([Personalizar])),
    #"FuncaoChamada Expandido" = Table.ExpandTableColumn(Convoca, "FuncaoChamada", {"Nome", "Categoria Premiação", "País/Região", "Perfil", "Imagem"}, {"Nome", "Categoria Premiação", "País/Região", "Perfil", "Imagem"}),
    #"Colunas Removidas1" = Table.RemoveColumns(#"FuncaoChamada Expandido",{"Personalizar"}),
    #"Dividir Coluna por Delimitador" = Table.ExpandListColumn(Table.TransformColumns(#"Colunas Removidas1", {{"Categoria Premiação", Splitter.SplitTextByDelimiter(", ", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Categoria Premiação"),
    #"Tipo Alterado2" = Table.TransformColumnTypes(#"Dividir Coluna por Delimitador",{{"Categoria Premiação", type text}, {"Nome", type text}, {"País/Região", type text}, {"Perfil", type text}, {"Imagem", type text}}),
    Funcao2 = (urlbio as text) =>
    let
        Fonte = Web.BrowserContents(urlbio),
        #"Tabela extraída de HTML" = Html.Table(Fonte, 
        {
            {"Data", "TABLE[id='recentActivities'] > TBODY > TR > :nth-child(2)"}, 
            {"Atividade", "TABLE[id='recentActivities'] > TBODY > TR > :nth-child(3)"}, 
            {"Tipo", "TABLE[id='recentActivities'] > TBODY > TR > :nth-child(4)"}, 
            {"Área Principal de Contribuição", "TABLE[id='recentActivities'] > TBODY > TR > :nth-child(5)"}, 
            {"Link Contribuição", "#recentActivities > tbody > tr > td > a", each [Attributes][href]}
        }, [RowSelector="TABLE[id='recentActivities'] > TBODY > TR"]),
        #"Tipo Alterado" = Table.TransformColumnTypes(#"Tabela extraída de HTML",{{"Data", type text}, {"Atividade", type text}, {"Tipo", type text}, {"Área Principal de Contribuição", type text}})
    
    in
        #"Tipo Alterado",
    ConsultaCotribuicoes = Table.AddColumn(#"Tipo Alterado2", "Contribuições", each Funcao2([Perfil])),
    Funcao3 = (urlbio as text) =>
    let
        Fonte = Web.BrowserContents(urlbio),
        #"Tabela extraída de HTML" = Html.Table(Fonte, 
        {
            {"Localidade", ".state"}, 
            {"Primeiro Ano de Prêmio", ".infoRow:nth-child(2) > .infoContent"}, 
            {"Numeros de Prêmios", ".infoRow:nth-child(3) > .infoContent"}
        }, [RowSelector=".infoRow:nth-child(2) > .infoContent"]),
        #"Tipo Alterado" = Table.TransformColumnTypes(#"Tabela extraída de HTML",{{"Localidade", type text}, {"Primeiro Ano de Prêmio", Int64.Type}, {"Numeros de Prêmios", Int64.Type}})
    in
        #"Tipo Alterado",
    ConsultaDemaisInfos = Table.AddColumn(ConsultaCotribuicoes, "Infos", each Funcao3([Perfil])),
    #"Contribuições Expandido" = Table.ExpandTableColumn(ConsultaDemaisInfos, "Contribuições", {"Data", "Atividade", "Tipo", "Área Principal de Contribuição", "Link Contribuição"}, {"Data", "Atividade", "Tipo", "Área Principal de Contribuição", "Link Contribuição"}),
    #"Infos Expandido" = Table.ExpandTableColumn(#"Contribuições Expandido", "Infos", {"Localidade", "Primeiro Ano de Prêmio", "Numeros de Prêmios"}, {"Localidade", "Primeiro Ano de Prêmio", "Numeros de Prêmios"}),
    #"Tipo Alterado com Localidade" = Table.TransformColumnTypes(#"Infos Expandido", {{"Data", type date}}, "en-US"),
    #"Tipo Alterado3" = Table.TransformColumnTypes(#"Tipo Alterado com Localidade",{{"Área Principal de Contribuição", type text}, {"Link Contribuição", type text}, {"Localidade", type text}, {"Primeiro Ano de Prêmio", Int64.Type}, {"Numeros de Prêmios", Int64.Type}}),
    #"Dividir Coluna por Delimitador1" = Table.SplitColumn(#"Tipo Alterado3", "Localidade", Splitter.SplitTextByDelimiter(", ", QuoteStyle.Csv), {"Localidade.1", "Localidade.2"}),
    #"Tipo Alterado4" = Table.TransformColumnTypes(#"Dividir Coluna por Delimitador1",{{"Localidade.1", type text}, {"Localidade.2", type text}}),
    #"Personalização Adicionada1" = Table.AddColumn(#"Tipo Alterado4", "Personalizar", each if [Localidade.2] = null then [Localidade.1] else [Localidade.2]),
    #"Colunas Renomeadas" = Table.RenameColumns(#"Personalização Adicionada1",{{"Personalizar", "Estado"}}),
    #"Colunas Removidas2" = Table.RemoveColumns(#"Colunas Renomeadas",{"Localidade.2"}),
    #"Colunas Renomeadas1" = Table.RenameColumns(#"Colunas Removidas2",{{"Localidade.1", "Município"}}),
    #"Colunas Reordenadas" = Table.ReorderColumns(#"Colunas Renomeadas1",{"Nome", "Categoria Premiação", "País/Região", "Perfil", "Imagem", "Data", "Atividade", "Tipo", "Área Principal de Contribuição", "Link Contribuição", "Primeiro Ano de Prêmio", "Numeros de Prêmios", "Município", "Estado"}),
    #"Tipo Alterado5" = Table.TransformColumnTypes(#"Colunas Reordenadas",{{"Estado", type text}}),
    #"Valor Substituído" = Table.ReplaceValue(#"Tipo Alterado5","Santa Catarina","SC",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído1" = Table.ReplaceValue(#"Valor Substituído","Ceara","CE",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído2" = Table.ReplaceValue(#"Valor Substituído1","Sao Paulo","SP",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído3" = Table.ReplaceValue(#"Valor Substituído2","Espírito Santo","ES",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído4" = Table.ReplaceValue(#"Valor Substituído3","Rio de Janeiro","RJ",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído5" = Table.ReplaceValue(#"Valor Substituído4","Parana","PR",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído6" = Table.ReplaceValue(#"Valor Substituído5","Pernambuco","PE",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído7" = Table.ReplaceValue(#"Valor Substituído6","São Paulo","SP",Replacer.ReplaceText,{"Estado"}),
    #"Valor Substituído8" = Table.ReplaceValue(#"Valor Substituído7","Minas Gerais","MG",Replacer.ReplaceText,{"Estado"}),
    #"Linhas Filtradas" = Table.SelectRows(#"Valor Substituído8", each true)
in
    #"Linhas Filtradas"

En enero haré una aparición especial en el canal. Youtube de Rafael Mendonça, demostrando junto a él cómo se construyó este informe paso a paso.

ACTUALIZAR: Como prometimos aquí, a continuación se muestra el video en vivo que realizamos explicando el programa Microsoft MVP y cómo se desarrolló el informe paso a paso.

¡Un abrazo y nos vemos en el próximo artículo!