Como descobri que meu visto não está pronto, uma mensagem no Slack

Jejum para as férias de maio. Há 6 semanas, solicitei um visto para a Irlanda. A partida está prevista para 30 de abril. Existe um site da embaixada no qual são publicadas listas de decisões sobre vistos. Eles fazem isso às segundas e quintas-feiras. E aqui estou eu sentado no domingo, 28 de abril, ainda não há solução para o meu visto. E minhas ações adicionais na segunda-feira dependem se minha declaração estará no novo relatório ou não. Caso contrário, você precisará ir à embaixada e resolver o problema. Se houver, puxe o centro de vistos. Sentar e atualizar a página o dia inteiro na segunda-feira parecia um passatempo chato, então escrevi um script Python.



Isenção de responsabilidade. Não sou programador, mas posso programar. Isso significa que não posso escrever um código elegante e eficiente, mas posso fazer com que esse órgão público faça o que eu preciso.


1. Verificando a página para um novo relatório


Então, o que precisa ser feito:


  1. Você precisa analisar esta página.
  2. Encontre nos relatórios um novo por uma nova data (no meu caso, você pode pesquisar pela palavra 24 April ).
  3. Obtenha um link para este relatório.

O código da função é o seguinte:


 def check_report(url, div_class, date): embassy_page = requests.get(url) page_text = BeautifulSoup(embassy.text, 'lxml') tags = page_text.findAll('div', {"class": div_class}) text = '' report_url = '' for tag in tags: tag_soup = BeautifulSoup(tag.text, 'lxml') report = s(text=re.compile(date)) if len(report) > 0: text = 'New report published' report_url = 'https://www.dfa.ie' + tag.find('a').attrs['href'] return text, report_url 

Agora, mais sobre o que está acontecendo neste código.


Primeiro, usamos a biblioteca de requests , que nos ajuda a baixar a página necessária. Em seguida, usamos outra biblioteca BeautifulSoup , que ajuda a transformar esse layout de página curinga em uma aparência mais bonita e conveniente.


Antes de usar o BeautifulSoup :


 '<!DOCTYPE html>\r\n\r\n<html lang="en">\r\n <head>\r\n <META http-equiv="X-UA-Compatible" content="IE=edge">\r\n <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\t\r\n\t<meta name="viewport" content="initial-scale=1">\r\n \r\n \r\n \r\n \r\n \r\n <!-- Static Meta data -->\r\n \r\n\t<!-- <meta name="DC.Creator" content="Department of Foreign Affairs" />\r\n\t<meta name="DC.Publisher" content="Department of Foreign Affairs" /> \r\n\t<meta name="DC.Format" content="text/xhtml" /> \r\n\t<meta name="DC.Copyright" content="All material (c) copyright 2012 Department of Foreign Affairs" /> \r\n\t<meta name="DC.Source" content="Department of Foreign Affairs" /> \r\n\t<meta name="DC.Language" content="en" />\r\n\t<meta name="DC.Author" content="Department of Foreign Affairs" /> -->\r\n\r\n\r\n<meta name="author" content="Department of Foreign Affairs">\r\n<meta name="google-site-verification" content="HHtulupgM8GXpd9YYDjoXUb6MiU7_mGTkHixUrVPFYQ" />\r\n \r\n\t<title>Weekly Decision Report - Department of Foreign Affairs and Trade</title>\r\n <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> \r\n <link rel="stylesheet" type="text/css" media="screen" href="/media/dfa-2017/style-assets/css/font-defs.css" />\t<!-- 2017 font-defs.css --> \r\n\t<link rel="stylesheet" type="text/css" media="screen" href="/media/dfa-2017/style-assets/css/style.css" />\t<!-- 2017 style.css -->\r\n <link rel="stylesheet" type="text/css" media="print" href="/media/dfa-2017/style-assets/css/print.css" />\t<!-- 2017 print.css -->\r\n 

Depois:


 <!DOCTYPE html> <html lang="en"> <head> <meta content="IE=edge" http-equiv="X-UA-Compatible"/> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> <meta content="initial-scale=1" name="viewport"/> <!-- Static Meta data --> <!-- <meta name="DC.Creator" content="Department of Foreign Affairs" /> <meta name="DC.Publisher" content="Department of Foreign Affairs" /> <meta name="DC.Format" content="text/xhtml" /> <meta name="DC.Copyright" content="All material (c) copyright 2012 Department of Foreign Affairs" /> <meta name="DC.Source" content="Department of Foreign Affairs" /> <meta name="DC.Language" content="en" /> <meta name="DC.Author" content="Department of Foreign Affairs" /> --> <meta content="Department of Foreign Affairs" name="author"/> <meta content="HHtulupgM8GXpd9YYDjoXUb6MiU7_mGTkHixUrVPFYQ" name="google-site-verification"/> <title>Weekly Decision Report - Department of Foreign Affairs and Trade</title> <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/> <link href="/media/dfa-2017/style-assets/css/font-defs.css" media="screen" rel="stylesheet" type="text/css"/> <!-- 2017 font-defs.css --> <link href="/media/dfa-2017/style-assets/css/style.css" media="screen" rel="stylesheet" type="text/css"/> <!-- 2017 style.css --> 

Agora você pode, de alguma forma, viver e trabalhar com isso. Em particular, no meu caso, procuraremos uma div class especial usada para links para relatórios. Vemos isso no código fonte da página: <div class="gen-content-landing__block"> . No meu código, procuramos todas essas tags.


Em seguida, consulte as tags coletadas e procure a que contém a data do novo relatório: 24 April . Se esse resultado for encontrado, extraímos o link e formamos o texto que um novo relatório foi publicado.


2. Procure um ID de visto em um novo relatório


Então, o que precisa ser feito agora aqui:


  1. Faça o download deste novo relatório.
  2. Analisa o arquivo pdf.
  3. Encontre minha identificação nele.
  4. Encontre o status correspondente a ele.

O código da função é o seguinte:


 def check_visa(report_url, filename, visa_id, text): pdf = requests.get(report_url) file_path = Path(filename) file_path.write_bytes(pdf.content) pdfFileObj = open(filename, 'rb') pdfReader = PyPDF2.PdfFileReader(pdfFileObj, strict=False) for pageNum in range(0, pdfReader.numPages): page = str(pdfReader.getPage(pageNum).extractText().encode('utf-8')).split('\\n') if visa_id in page: visa_index = page.index(visa_id) status = page[visa_index + 1] text = text + '\t' + visa_id + '\t' + status return text 

Usando a biblioteca de requests novamente, fazemos uma solicitação para este relatório. Em seguida, salve-o localmente. Usando a biblioteca PyPDF2 , lemos o arquivo. Depois disso, classificamos suas páginas e procuramos visa_id na matriz de tokens. A marcação deste arquivo pdf é tal que o próximo token após visa_id é o status de visa_id diretamente: Approved ou Refused . Em seguida, concatenamos o texto existente com id e status.


3. Enviando mensagem de status no Slack


Bom O script encontrou, digamos, meu ID, mas você precisa me notificar sobre isso. Nós da nossa empresa usamos o Slack como um mensageiro, então achei que seria conveniente receber uma notificação lá.


Este link permite que você configure seu webhook. Lá, você pode selecionar o canal ou o destinatário para quem postar a mensagem (pode ser necessário ser um administrador do WorkSpace para esta etapa). Lá, você receberá um URL exclusivo para o webhook, que pode ser usado no código.


 def send_to_slack(webhook_url, text): post = {"text": "{0}".format(text)} json_data = json.dumps(post) req = requests.post(webhook_url, data=json_data.encode('ascii'), headers={'Content-Type': 'application/json'}) return req.status_code 

Utilizando a mesma biblioteca de requests , fazemos uma solicitação POST com o conteúdo do text no webhook.


4. Uso de funções


O restante do código fica assim:


 url = 'https://www.dfa.ie/irish-embassy/russia/visas/weekly-decision-report/' div_class = 'gen-content-landing__block' date = '24 April' filename = 'weekly_report.pdf' visa_id = '38644112' webhook_url = 'https://hooks.slack.com/services/...' text, report_url = check_report(url, div_class, date) if text != '': text = check_visa(report_url, filename, visa_id, text) print(send_to_slack(webhook_url, text)) 

Atribuímos valores a todas as variáveis ​​necessárias e, em seguida, executamos as funções prescritas.


5. Lançamento de acordo com o plano


Ok Eu escrevi um script, mas se eu tiver que fazer isso sempre, não estou longe do estado inicial, onde teria que sentar e atualizar a página.


 $ crontab -e 

Adicionada uma linha a ela:


 */10 * * * * python3 /home/ubuntu/embassy.py >/dev/null 2>&1 

Eu pensei que seria o suficiente para mim se esse script fosse executado a cada 10 minutos pelo cron em um servidor com o ubuntu.


6. Conclusão


Às 11h50, recebi a mensagem de que um novo relatório havia aparecido, mas meu visto não estava nele ... Depois disso, fui à embaixada. Ele o pegou pela tempestade (eles não responderam cartas e telefonemas por várias semanas) e, como resultado, recebeu seu passaporte com um visto.


Em geral, a habilidade de programação é importante no mundo moderno, mesmo que você não seja um programador. Permite automatizar algumas de suas operações de rotina, o que torna seu mundo um pouco mais conveniente. De fato, pode-se até organizar isso em um serviço separado, onde uma pessoa simplesmente digita seu ID e e-mail e recebe uma mensagem sobre a disponibilidade de um visto para enviar.

Source: https://habr.com/ru/post/pt450060/


All Articles