<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Silveira Neto &#187; CRON</title>
	<atom:link href="http://silveiraneto.net/tag/cron/feed/" rel="self" type="application/rss+xml" />
	<link>http://silveiraneto.net</link>
	<description>the world is a pixel</description>
	<lastBuildDate>Sun, 08 Jan 2012 05:17:57 +0000</lastBuildDate>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Extração de Dados e Fundos de Investimento do Banco do Brasil</title>
		<link>http://silveiraneto.net/2010/01/11/extracao-de-dados-e-fundos-de-investimento-do-banco-do-brasil/</link>
		<comments>http://silveiraneto.net/2010/01/11/extracao-de-dados-e-fundos-de-investimento-do-banco-do-brasil/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 00:02:42 +0000</pubDate>
		<dc:creator>Silveira</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[ações]]></category>
		<category><![CDATA[aplicações]]></category>
		<category><![CDATA[Banco do Brasil]]></category>
		<category><![CDATA[bolsa de valores]]></category>
		<category><![CDATA[CRON]]></category>
		<category><![CDATA[Data Mining]]></category>
		<category><![CDATA[fundo de investimento]]></category>
		<category><![CDATA[fundos]]></category>
		<category><![CDATA[fundos de investimento]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Mineração de Dados]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[screen scraping]]></category>
		<category><![CDATA[Web Harvest]]></category>
		<category><![CDATA[web scraping]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[yaml]]></category>

		<guid isPermaLink="false">http://silveiraneto.net/?p=3112</guid>
		<description><![CDATA[Eu não achei onde coletar os dados diários de rentabilidade dos fundos de investimento do Banco do Brasil em formato bem estruturado. Num mundo ideal as coisas seriam assim, você faria uma requisição numa url como esta: http://bb.com.br/apps/rentabilidade?fundo=Siderurgia&#38;saida=xml E ele cuspiria um XML com as informações da rentabilidade diária desse fundo, isso se eu não [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-full wp-image-3118 aligncenter" title="unicornio" src="http://silveiraneto.net/wp-content/uploads/2010/01/unicornio1.jpg" alt="" width="400" height="440" /></p>
<p>Eu não achei onde coletar os dados diários de rentabilidade dos <a title="Fundos de Investimento do Banco do Brasil" href="http://www21.bb.com.br/portalbb/rentabilidade/index.jsp?tipo=01">fundos de investimento do Banco do Brasil</a> em formato bem estruturado.</p>
<p>Num mundo ideal as coisas seriam assim, você faria uma requisição numa url como esta:</p>
<blockquote><p>http://bb.com.br/apps/rentabilidade?fundo=Siderurgia&amp;saida=xml</p></blockquote>
<p>E ele cuspiria um XML com as informações da rentabilidade diária desse fundo, isso se eu não especificasse através de outro parâmetro qual a data ou intervalo de datas desejado ou outro tipo de dados para saída como YAML ou JSON. Mas por enquanto não temos isso, nem unicórnios, então temos de fazer as coisas do jeito mais difícil, que é puxando os <a title="tabela dos fundos de investimento" href="http://www21.bb.com.br/portalbb/rentabilidade/index.jsp?tipo=01">dados feitos para humanos</a> e escrevendo um programa pra extrair à força os dados que desejamos e quem sabe usar eles para algum uso relacionado a <a href="http://pt.wikipedia.org/wiki/Minera%C3%A7%C3%A3o_de_dados">mineração de dados</a>.</p>
<p style="text-align: center;"><img class="size-full wp-image-3113 aligncenter" title="bb fundos de investimento" src="http://silveiraneto.net/wp-content/uploads/2010/01/bb_fundos_de_investimento.png" alt="" width="494" height="318" /></p>
<p>A primeira abordagem que eu tentei foi a de criar <a href="http://silveiraneto.net/2009/12/25/python-fast-xml-parsing/">um desses pequenos parsers XML que eu já mostrei como fazer antes</a>, mas o código fonte desse documento se mostrou muito incompatível com o XML que o parser estava disposto a trabalhar. A solução alternativa foi tratar o documento linha a linha.</p>
<div class="wp_syntax">
<div class="code">
<pre class="python python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># abrimos o documento referenciado pela url</span>
url = <span style="color: #483d8b;">'http://www21.bb.com.br/portalbb/rentabilidade/index.jsp?tipo=01'</span>
documento = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># fundo de investimento que me interessa</span>
fundo = <span style="color: #483d8b;">'small caps'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># estados</span>
INICIO = 0
ACHOU_FUNDO = <span style="color: #ff4500;">1</span>
FIM = <span style="color: #ff4500;">2</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># estado inicial</span>
estado = INICIO
&nbsp;
<span style="color: #808080; font-style: italic;"># vamos analisar linha a linha do fluxo do documento</span>
<span style="color: #ff7700;font-weight:bold;">for</span> linha <span style="color: #ff7700;font-weight:bold;">in</span> documento:
	<span style="color: #808080; font-style: italic;"># simplificamos, tudo pra minusculas</span>
	linha = linha.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># no inicio, procura uma linha que tenha o fundo</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> estado == INICIO <span style="color: #ff7700;font-weight:bold;">and</span> linha.<span style="color: black;">find</span><span style="color: black;">&#40;</span>fundo<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
		estado = ACHOU_FUNDO
&nbsp;
	<span style="color: #808080; font-style: italic;"># depois, procuramos o proximo inicio de tabela html.</span>
	<span style="color: #808080; font-style: italic;"># dessa linha, pegamos o que vem depois do primeiro &amp;gt;</span>
	<span style="color: #808080; font-style: italic;"># e entao o que vem antes do primeiro &amp;lt;</span>
	<span style="color: #808080; font-style: italic;"># e trocamos a virgula por ponto.</span>
	<span style="color: #ff7700;font-weight:bold;">elif</span> estado == ACHOU_FUNDO <span style="color: #ff7700;font-weight:bold;">and</span> linha.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&gt;'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>.<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span>,<span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span>
		estado = FIM</pre>
</div>
</div>
<p>E para usar:</p>
<blockquote><p>$ python rendimento_small_caps.py<br />
0.881</p></blockquote>
<p>Geralmente estamos mais interessados em saber o valor da cota daquele fundo, daí podemos calcular o rendimento total sabendo a cota que compramos a ação inicialmente. Nesse caso o dado está na 11º coluna.</p>
<div class="wp_syntax">
<div class="code">
<pre class="python python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># abrimos o documento referenciado pela url</span>
url = <span style="color: #483d8b;">'http://www21.bb.com.br/portalbb/rentabilidade/index.jsp?tipo=01'</span>
documento = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># fundo de investimento que me interessa</span>
fundo = <span style="color: #483d8b;">'small caps'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># estados</span>
INICIO = 0
ACHOU_FUNDO = <span style="color: #ff4500;">1</span>
FIM = <span style="color: #ff4500;">2</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># estado inicial</span>
estado = INICIO
coluna = 0
&nbsp;
<span style="color: #808080; font-style: italic;"># vamos analisar linha a linha do fluxo do documento</span>
<span style="color: #ff7700;font-weight:bold;">for</span> linha <span style="color: #ff7700;font-weight:bold;">in</span> documento:
	<span style="color: #808080; font-style: italic;"># simplificamos, tudo pra minusculas</span>
	linha = linha.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># no inicio, procura uma linha que tenha o fundo</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> estado == INICIO <span style="color: #ff7700;font-weight:bold;">and</span> linha.<span style="color: black;">find</span><span style="color: black;">&#40;</span>fundo<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
		estado = ACHOU_FUNDO
&nbsp;
	<span style="color: #808080; font-style: italic;"># para cada coluna, conta a coluna, mas nao faz nada</span>
	<span style="color: #ff7700;font-weight:bold;">elif</span> estado == ACHOU_FUNDO <span style="color: #ff7700;font-weight:bold;">and</span> linha.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;'</span><span style="color: black;">&#41;</span>:
		coluna += <span style="color: #ff4500;">1</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># quando chegar na coluna onze, retira o conteudo entre os sinais &amp;gt; e &amp;lt;</span>
	<span style="color: #808080; font-style: italic;"># e troca virgula por ponto, transforma em float e joga na tela</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> estado==ACHOU_FUNDO <span style="color: #ff7700;font-weight:bold;">and</span> coluna == <span style="color: #ff4500;">11</span>:
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>linha.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&gt;'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>.<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span>,<span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
		estado = FIM</pre>
</div>
</div>
<blockquote><p>$ python cota_small_caps.py<br />
6.156906634</p></blockquote>
<p>Essa é uma abordagem que eu não gosto nem recomendo porque ela é muito frágil e está extremamente acoplada a formatação de dados para humanos. Esta formatação está interessada no saída gráfica que o usuário vai obter e não em facilitar a extração (não humana) desses dados. Isso torna a solução muito frágil:</p>
<ul>
<li>Se mudarem os nomes internos dos elementos, a solução pode falhar.</li>
<li>Se mudarem a formatação da tabela, a solução pode falhar.</li>
<li>Se mudarem a disposição interna dos elementos html, a solução pode falhar.</li>
<li>Se mudarem a url do documento, a solução vai falhar.</li>
<li>Se o documento não puder mais ser tratado linha a linha, a solução vai falhar feio.</li>
</ul>
<p>É provável que quando você estiver lendo isso ela nem funcione mais do jeito que está descrita aqui.</p>
<p>Por outro lado, a solução funciona e nesse caso é o que me interessa. Quando ela quebrar, se ainda for do meu interesse eu posso rapidamente conserta-la e os dados já coletados no passado continuam válidos.</p>
<p>Isso somado  a uma programa como o Cron pode se tornar uma ferramenta realmente poderosa.</p>
]]></content:encoded>
			<wfw:commentRss>http://silveiraneto.net/2010/01/11/extracao-de-dados-e-fundos-de-investimento-do-banco-do-brasil/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Twitter Bot @rudaufc versão 1</title>
		<link>http://silveiraneto.net/2009/11/09/twitter-bot-rudaufc-versao-1/</link>
		<comments>http://silveiraneto.net/2009/11/09/twitter-bot-rudaufc-versao-1/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 19:54:18 +0000</pubDate>
		<dc:creator>Silveira</dc:creator>
				<category><![CDATA[português]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[bot]]></category>
		<category><![CDATA[Comida]]></category>
		<category><![CDATA[CRON]]></category>
		<category><![CDATA[crontab]]></category>
		<category><![CDATA[culinária]]></category>
		<category><![CDATA[CURL]]></category>
		<category><![CDATA[ia]]></category>
		<category><![CDATA[inteligência artificial]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Restaurante Universitário]]></category>
		<category><![CDATA[robô]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[SH]]></category>
		<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[ufc]]></category>
		<category><![CDATA[Universidade Federal do Ceará]]></category>

		<guid isPermaLink="false">http://silveiraneto.net/?p=2927</guid>
		<description><![CDATA[Este aqui é um bot bem simples para Twitter. Diariamente, as nove da manhã ele posta qual vai ser o cardápio do RU (Restaurante Universitário) da UFC naquele dia. Assim, quando vai batendo a hora da fome, os alunos podem entrar no perfil @rudaufc e olhar qual vai ser o prato do dia, ou quem [...]]]></description>
			<content:encoded><![CDATA[<p><center><img src="http://silveiraneto.net/wp-content/uploads/2009/11/robo.jpg" alt="robô" title="robô" width="117" height="227" class="alignnone size-full wp-image-2933" /></center></p>
<p>Este aqui é um bot bem simples para Twitter.</p>
<p>Diariamente, as nove da manhã ele posta qual vai ser o cardápio do RU (<a href="http://www.ufc.br/portal/index.php?option=com_content&#038;task=view&#038;id=6842&#038;Itemid=87">Restaurante Universitário</a>) da <a href="http://www.ufc.br">UFC</a> naquele dia.</p>
<p>Assim, quando vai batendo a hora da fome, os alunos podem entrar no perfil <a href="http://www.twitter.com/rudaufc">@rudaufc</a> e olhar qual vai ser o prato do dia, ou quem está seguindo ele no Twitter pode ter a agradável surpresa de ver todo dia o que vai ser servido hoje.</p>
<p>Aqui está o código fonte do arquivo rudaufc.sh:</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;"># Twitter bot @rudaufc</span>
<span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">login</span></span>=<span style="color: #ff0000;">&quot;rudaufc&quot;</span>
<span style="color: #007800;">senha</span>=<span style="color: #ff0000;">&quot;suasenhaaqui&quot;</span>
&nbsp;
<span style="color: #007800;">segunda</span>=<span style="color: #ff0000;">&quot;Picadinho com legumes ou bife na chapa. Salada de macarrão com cenoura. Arroz. Feijão com abóbora e batata doce.&quot;</span>
<span style="color: #007800;">terca</span>=<span style="color: #ff0000;">&quot;Franco guisado ou coxas de frango ao forno . Salada de acelga, cenoura e passas. Arroz. Feijão com abóbora e batata doce.&quot;</span>
<span style="color: #007800;">quarta</span>=<span style="color: #ff0000;">&quot;# Feijoada à moda RU ou bisteca . Salada de repolho branco, cenoura e abacaxi. Arroz. Feijão com abóbora e batata doce&quot;</span>
<span style="color: #007800;">quinta</span>=<span style="color: #ff0000;">&quot;Frango à passarinho ou frango chinês. Salada de Alface, Tomate e Cebola. Arroz. Feijão com abóbora e batata doce.&quot;</span>
<span style="color: #007800;">sexta</span>=<span style="color: #ff0000;">&quot;# Isca ao molho ou maravilha de carne. Salada de acelga com cenoura. Arroz. Feijão com abóbora e batata doce.&quot;</span>
&nbsp;
<span style="color: #007800;">dia</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span><span style="color: #c20cb9; font-weight: bold;">w</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">log</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>Y-<span style="color: #000000; font-weight: bold;">%</span>m-<span style="color: #000000; font-weight: bold;">%</span>d-<span style="color: #000000; font-weight: bold;">%</span>s<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">`</span><span style="color: #ff0000;">&quot;-$$.log&quot;</span>
<span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">dir</span></span>=<span style="color: #ff0000;">&quot;/home/silveiraneto/rudaufc&quot;</span>
<span style="color: #007800;">msg</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$dia&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
<span style="color: #666666; font-style: italic;">#	&quot;0&quot;) msg=$domingo ;;</span>
	<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #007800;">msg</span>=<span style="color: #007800;">$segunda</span> ;;
	<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #007800;">msg</span>=<span style="color: #007800;">$terca</span> ;;
	<span style="color: #ff0000;">&quot;3&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #007800;">msg</span>=<span style="color: #007800;">$quarta</span> ;;
	<span style="color: #ff0000;">&quot;4&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #007800;">msg</span>=<span style="color: #007800;">$quinta</span> ;;
	<span style="color: #ff0000;">&quot;5&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #007800;">msg</span>=<span style="color: #007800;">$sexta</span> ;;
<span style="color: #666666; font-style: italic;">#	&quot;6&quot;) msg=$sabado ;;</span>
<span style="color: #000000; font-weight: bold;">esac</span>
&nbsp;
curl <span style="color: #660033;">-u</span> <span style="color: #007800;">$login</span>:<span style="color: #007800;">$senha</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">status</span>=<span style="color: #ff0000;">&quot;$msg&quot;</span> http:<span style="color: #000000; font-weight: bold;">//</span>twitter.com<span style="color: #000000; font-weight: bold;">/</span>statuses<span style="color: #000000; font-weight: bold;">/</span>update.xml <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$dir</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$log</span></pre>
</div>
</div>
<p>A mágica toda está na capacidade do <a href="http://en.wikipedia.org/wiki/CURL">Curl</a> de acessar facilmente a <a href="http://apiwiki.twitter.com/">API do Twitter</a> para enviar mensagens.</p>
<p>Para que o script execute diariamente as nove da manhã ele está alocado em um servidor com a <a href="http://pt.wikipedia.org/wiki/Crontab">crontab</a> configurada da seguinte maneira:</p>
<pre>
0 5 * * *  . /caminho_para_onde_ele_esta/rudaufc.sh
</pre>
<p><small>ps: leve em conta que o servidor está em um fuso horário diferente do Brasil.</small></p>
<p>Nessa versão o prato de cada dia está hardcoded no script, o que não é o ideal e faz com que semanalmente eu tenha que atualizar o script inserindo os pratos da semana manualmente. Eu espero que a próxima versão seja capaz de descobrir esses pratos e se atualizar sem nenhuma interferência.</p>
]]></content:encoded>
			<wfw:commentRss>http://silveiraneto.net/2009/11/09/twitter-bot-rudaufc-versao-1/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

