Escrevendo scripts com a API do Reddit

AlpsCode Blocked Desbloquear Seguir Seguindo 26 de dezembro de 2018

Neste post, mostrarei como você pode usar o Python para reunir conteúdo e criar uma página da Web simples em torno dele. Veja a primeira parte para aprender como registrar um aplicativo no Reddit API e começar.

Configuração

Costumo usar PyCharm ou Jupyter para Python, mas qualquer ambiente Python fará o truque. Você precisa ter um ID de aplicativo do Reddit e um segredo de aplicativo já disponíveis para essa parte. Um conhecimento básico de HTML e CSS pode ser útil, mas não é necessário para o conteúdo de alto nível.

Escreverei um script que pesquisará subreddits relacionados a "filhotes" e mostrará seus principais posts como galeria. Este projeto pode ser o suficiente para desencadear sua agressão bonito se você estiver em cães.

visão global

Eu mostrei uma introdução básica à API do Reddit na parte anterior. Existem os passos que vou seguir:

  1. Encontre subreddits relacionados a filhotes
    GET /subreddits/search
  2. Obter lista de posts para cada subreddit
    GET /top
  3. Filtrar e coletar links de imagem como um código HTML
  4. Finalmente, exiba (e salve) o conteúdo HTML

GET solicitações GET são membros passivos das APIs RESTful. Portanto, o script não publicará nada, mas retornará o conteúdo que você pode analisar.

A primeira ordem de trabalhos é obter nomes de subreddit que você precisa analisar. Você pode usar a função de pesquisa do Reddit através da API:

 payload = {'q': 'puppies', 'limit': 5} 
response = requests.get(api_url + '/subreddits/search', headers=headers, params=payload)
js = response.json()

A variável js é um dicionário aninhado, que inclui a resposta que recebemos do Reddit. Nós podemos ver as chaves do dicionário

 print(js.keys()) 
 dict_keys(['kind', 'data']) 

Você pode se familiarizar com as respostas, mas visualizá-lo ajuda imensamente. Usando seu visualizador JSON favorito ( https://jsoneditoronline.org/ , https://codebeautify.org/jsonviewer , http://jsonviewer.stack.hu/ ) copie o conteúdo response.text para visualizar a resposta JSON.

A resposta do Reddit inclui dois objetos. O kind objeto mostra, bem, que tipo de dados esse objeto de data possui. Se for uma listagem, o objeto de data incluirá duas sequências, before e after quais será usado para navegar. Depois que terminarmos de analisar a primeira página, por exemplo, usaremos o parâmetro after para solicitar a segunda página.

 { 
"kind": "Listing",
"data": {
"modhash": null,
"dist": 5,
"children": [...],
"after": "t5_2tjl7",
"before": null
}
}

Aqui, os dados que você pode usar estão dentro da matriz de children . O Reddit torna nossa vida mais fácil aqui, nos dando quantos elementos o array de children tem "dist": 5 . Vamos ver o que o primeiro filho inclui:

 "children": [ 
{
"kind": "t5",
"data": {
"display_name": "puppies",
"display_name_prefixed": "r/puppies",
...
}
},
...
]

O objeto de data tem muitos campos. Eu só vou usar display_name nesta etapa. Um visualizador JSON mostra que o display_name pode ser acessado usando os seguintes breadcrumbs: data > children > i > data > display_name . Agora você pode reunir todos os nomes subreddit da seguinte forma:

 sr = [] 
for i in range(js['data']['dist']):
sr.append(js['data']['children'][i]['data']['display_name'])

print(sr)
 ['puppies', 'aww', 'dogpictures', 'corgi', 'lookatmydog'] 

Coletando Postagens

Agora que temos uma lista de subreddits, vamos continuar coletando as 5 principais imagens dos subreddits em nosso pool.

Para este propósito, nós conseguiremos postagens de todos os tempos deste subreddit. Lembre-se de que alguns subreddits e suas principais postagens podem não estar relacionados ao nosso termo de pesquisa, mas nosso objetivo aqui é simplesmente exibir uma lista das principais postagens de subreddits relacionados.

A requisição da API /r/(subreddit)/top – onde o subreddit será substituído pelo nome do subreddit – nos dará os posts principais. Simplesmente substitua subreddit pelos nomes de subreddit que você armazenou na variável sr .

Antes de prosseguir, imprima uma resposta simples para entender a estrutura:

 payload = {'t': 'all'} 
r = requests.get(api_url + '/r/puppies/top', headers=headers, params=payload)
print(r.text)
 { 
"kind": "Listing",
"data": {
"modhash": null,
"dist": 25,
"children": [
{
"kind": "t3",
"data": {
"title": "Recently at the airport",
"url": " http://imgur.com/qPjptrd.jpg ",
"thumbnail": " https://b.thumbs.redditmedia.com/bJxCSi2BHocxt0RlUvfk2ibVIKhpniqFL7_j-sCEs-Y.jpg ",
"approved_at_utc": null,
"subreddit": "puppies",
"selftext": "",
...
}
},
...
],
"after": "t3_7s49s5",
"before": null
}
}

Como você vê na resposta JSON, é necessário acessar os dados nesta ordem: data > children > i > data > title . Eu só usarei title , thumbnail e url aqui, mas é uma boa idéia verificar que tipo de dados o Reddit retorna para projetos futuros.

Você pode iterar todos os filhos e salvar as miniaturas dentro de um código HTML. Este código HTML pode ser impresso se você estiver usando o Jupyter. Também mostrarei como ele pode ser salvo como uma página HTML. Se você não estiver familiarizado com HTML, talvez seja uma boa idéia verificar o básico o quanto antes, pois é uma habilidade muito útil, especialmente nos dias de hoje. As tags HTML que uso a seguir são as seguintes:

  • h3 para imprimir títulos
  • div para agrupamento e estilo
  • span para agrupar elementos HTML juntos
  • a para criar links
  • img para exibir imagens

O código a seguir mostra o título do subreddit e, em seguida, coloca 5 imagens principais uma ao lado da outra. É uma boa ideia usar miniaturas em vez de imagens completas, pois você só precisa mostrar uma pequena foto na galeria. Quando o usuário passar, ele mostrará o título do pôster original e o clique levará o usuário à imagem completa (ou URL).

 payload = {'t': 'all', 'limit': 5} 
imghtml = ''
for s in sr:
imghtml += '<h3 style="clear:both">{}</h3><div>'.format(s)
r = requests.get(api_url + '/r/{}/top'.format(s), headers=headers, params=payload)
js = r.json()
for i in range(js['data']['dist']):
if js['data']['children'][i]['data']['thumbnail'] == '':
continue
imghtml += '<span style="float:left"><a href="{}"><img src="{}" title="{}" target="_blank" ></a></span>'.format(
js['data']['children'][i]['data']['url'],
js['data']['children'][i]['data']['thumbnail'],
js['data']['children'][i]['data']['title'],
)
imghtml += '</div>'

Aqui, a solicitação GET para /r/(subreddit)/top retorna os posts principais desse subreddit. Passei o período de tempo t=all e um limite no número de postagens de cada limit=5 subreddit limit=5 para a consulta. No final, o imghtml deve ter o código HTML que você precisa exibir.

Resultado

Chegamos à etapa final do nosso breve e esperançoso tutorial. As imagens podem ser exibidas no notebook Jupyter da seguinte forma:

 from IPython.core.display import display, HTML 
display(HTML(imghtml))

As funções que usamos display e HTML são específicas para Jupyter. Se você estiver usando uma ferramenta diferente para escrever seu código Python, faz sentido escrever o código HTML em uma página.

 with open("puppies.html", "w", encoding='utf-8') as html_page: 
html_page.write(imghtml)

Agora, você pode navegar pela pasta que seu código Python mora e abrir a página puppies.html apropriadamente chamada. Veja uma prévia aqui .

Fechamento

Há uma tonelada de informações que eu não pude abordar aqui para manter este post para o ponto. Eu estava esperando para escrever um jogo de trivia, onde você vê uma foto e tentar adivinhar o subreddit que foi compartilhado, mas eu tenho que ignorá-lo por agora. Eu poderia fazer isso em outra iteração, espero.

Se você gostou do tutorial, verifique meu notebook Jupyter para ver um exemplo completo, em que uma página da Web é gerada a partir de uma determinada consulta de pesquisa. Em um dos próximos posts do blog, mostrarei como escrever um bot do Reddit, que irá analisar informações de duas APIs separadas e postar comentários no Reddit.

Referências

Texto original em inglês.