こんにちは, Shinoryoです.
論文を読むような方は, 学術論文のアーカイブサービスであるarXivを利用される方は多いと思います.
そこで, PythonとIFTTTを使用して, arXivへの新規投稿論文の情報をGoogle翻訳で日本語訳にしてメールさせてみました.
IFTTTの設定
まずは, IFTTTの設定を行います. IFTTTとは, さまざまなサービスを連携して, 「トリガーとなるあるイベントが発生した」場合(IF This), 「あるイベントを発生させる」(Then That)ことができる(合わせてIF This Then That = IFTTT)ものになります.
IFTTT
Get started with IFTTT, the easiest way to do more with your favorite apps and devices for free. Make your home more relaxing. Make your work more productive. Keep your data private and secure. We believe every thing works better together.
概要
以下の図のように, WebhookとGmailをつなげます.
Webhook
Webhookとは, さまざまなウェブリクエストを作成または受信できる機能のことです. 私もあまり詳細は分かりませんが, 以下のようになるでしょうか.
- 何かしらのトリガーとなるイベントが発生する(データが追加される, 特定の時刻になる等?)
- そのイベントにより指定したURLへのHTTP通信が発生し, データが送信される
もし具体的に興味があれば, 例えば以下のWebページは参考になるかもしれません.
Webhookって何?を子どもでもわかるように描いてみた
はじめに こんにちは. 最近娘に絵本を読むのがめんどくさいダン吉です. 今日は, 巷で話題のWebhookとは何かをわかりやすく伝えるために, 画力に圧倒的に自信のない私が恥を覚悟で, 子どもによく描いてあげる...
Webhookでは, 「Receive a web request」のトリガーを設定し, 下の図のようにEvent Nameを設定します. Event Nameは任意で構いません.
Gmail
Gmailでは, 「Send yourself an email」のイベントを設定し, 例えば下の図のように設定します. この後のPythonプログラムに合わせてこのようにしていますが, 「Value1, Value2, Value3に3つの値が保存され, その値をGmailのイベントの設定に使うことができる」ということが分かっていれば, 柔軟に設定を変更することができると思います.
WebhookのURLを取得しておく
この後のPythonプログラムで用いる, WebhookのURLを取得します. まず, IFTTTのMy ServiceからWebhookを選択し, 右上の「Documentation」を選択します.
そして「To Trigger an Event」の下のURLを確認します.
このURLの真ん中の四角に, 上記のIFTTTのWebhookの設定のEvent Nameで設定した名前を入れたURLを確認してください. これを後に用います.
Python
Pythonのコード例
私は以下のようなPythonプログラムを用いています.
import arxiv | |
import datetime | |
from googletrans import Translator | |
import requests | |
import time | |
translator = Translator() | |
# パラメータの設定 | |
# WebhookのURL | |
API_URL = "Webhook_URL" | |
# クエリの設定(カテゴリ) | |
QUERY_cat = "(cat:astro-ph.CO OR astro-ph.GA)" | |
# 情報を確認する時刻の設定 | |
# デフォルトは一週間前 | |
todaytime = datetime.datetime.utcnow() | |
endtime = todaytime - datetime.timedelta(days=7) | |
starttime = todaytime - datetime.timedelta(days=8) | |
todaytime = todaytime.strftime("%Y%m%d%H%M%S") | |
endtime = endtime.strftime("%Y%m%d%H%M%S") | |
starttime = starttime.strftime("%Y%m%d%H%M%S") | |
print("-------from_arXiv_to_Gmail.py-------") | |
print("ただいまの日時:" + todaytime) | |
print("出力日時:" + starttime + " TO " + endtime) | |
# arXivから情報を取得する(result_list) | |
result_list = arxiv.Search( | |
query = QUERY_cat + " AND submittedDate:[" + starttime + " TO " + endtime + "]", | |
# max_results = 1, | |
sort_by = arxiv.SortCriterion.SubmittedDate | |
) | |
# 情報を出力したカウント(count) | |
count = 1 | |
# 「出力開始」のログを出力 | |
print("-------出力開始-------") | |
size = len([result for result in result_list.get()]) | |
# result_listでループ | |
for result in result_list.get(): | |
# 細かな情報を取得 | |
title = result.title | |
authors = result.authors | |
date = result.published | |
category = result.categories | |
journalref = result.journal_ref | |
abst = result.summary | |
comment = result.comment | |
absurl = result.entry_id | |
pdfurl = result.pdf_url | |
doiurl = result.doi | |
# タイトルの日本語訳を取得 | |
title_jpn = translator.translate(title, src='en' ,dest='ja').text | |
time.sleep(1) | |
# 著者を整形 | |
new_authors = [] | |
for author in authors: | |
new_authors.append(author.name) | |
new_authors = "; ".join(new_authors) | |
# ジャーナル情報を整形 | |
if journalref == None: | |
journalref = "No Journal Reference." | |
# カテゴリーを整形 | |
new_category = ", ".join(category) | |
# 概要の日本語訳を取得 | |
abst = abst.replace("\n"," ") | |
abst_jpn = translator.translate(abst, src='en' ,dest='ja').text | |
time.sleep(1) | |
# コメントの日本語訳を取得 | |
if comment == None: | |
comment = "No comment." | |
comment_jpn = translator.translate(comment, src='en' ,dest='ja').text | |
time.sleep(1) | |
# doiurlを整形 | |
if doiurl == None: | |
doiurl = "No doi link." | |
else: | |
doiurl = "https://doi.org/" + doiurl | |
# ログを出力 | |
print() | |
print("-------" + str(count) + "/" + str(size) +"ページ目-------") | |
print("Title: {}".format(title)) | |
print("タイトル: {}".format(title_jpn)) | |
try: | |
print("Authors: {}".format(new_authors)) | |
except Exception as e: | |
print("Authors: " + str(e)) | |
print("Published(UTC): " + str(date)) | |
print("Journal Reference: " + journalref) | |
print("Categories: " + new_category) | |
print("") | |
print("Abstract: ") | |
try: | |
print("{}".format(abst)) | |
except Exception as e: | |
print("{}".format(e)) | |
print("") | |
print("概要: ") | |
try: | |
print("{}".format(abst_jpn)) | |
except Exception as e: | |
print("{}".format(e)) | |
print("") | |
print("Comment: ") | |
try: | |
print("{}".format(comment)) | |
except Exception as e: | |
print("{}".format(e)) | |
print("") | |
print("コメント: ") | |
try: | |
print("{}".format(comment_jpn)) | |
except Exception as e: | |
print("{}".format(e)) | |
print("") | |
print("URL: {}".format(absurl)) | |
print("PDFのURL: {}".format(pdfurl)) | |
print("doiのURL: {}".format(doiurl)) | |
# WebhookへPost | |
if doiurl == "No doi link.": | |
message = "\n".join(["Title: " + title + "<br>タイトル: " + title_jpn + "<br>Authors: " + new_authors + "<br>Published(UTC): " + str(date) + "<br>Journal Reference: " + journalref + "<br>Categories: " + new_category + "<br><br>Abstract: <br>" + abst + "<br><br>概要: <br>" + abst_jpn + "<br><br>Comment: <br>" + comment + "<br><br>コメント: <br>" + comment_jpn + "<br><br>URL: <a href=\"" + absurl + "\">" + absurl + "</a>" + "<br>PDFのURL: <a href=\"" + pdfurl + "\">" + pdfurl + "</a>" + "<br>doiのURL: " + doiurl]) | |
else: | |
message = "\n".join(["Title: " + title + "<br>タイトル: " + title_jpn + "<br>Authors: " + new_authors + "<br>Published(UTC): " + str(date) + "<br>Journal Reference: " + journalref + "<br>Categories: " + new_category + "<br><br>Abstract: <br>" + abst + "<br><br>概要: <br>" + abst_jpn + "<br><br>Comment: <br>" + comment + "<br><br>コメント: <br>" + comment_jpn + "<br><br>URL: <a href=\"" + absurl + "\">" + absurl + "</a>" + "<br>PDFのURL: <a href=\"" + pdfurl + "\">" + pdfurl + "</a>" + "<br>doiのURL: <a href=\"" + doiurl + "\">" + doiurl + "</a>"]) | |
title = "arXiv投稿通知(" + str(count) + "/" + str(size) + "): " + title | |
response = requests.post(API_URL, data={"value1": message, "value2": title, "value3": pdfurl}) | |
# countを+1 | |
count += 1 | |
# 5秒間休止 | |
time.sleep(5) | |
# 「出力完了」のログを出力 | |
print() | |
print("-------出力完了-------") |
- arxivモジュールが更新されたようなので, それに対応させました.
- arxiv.Searchで, arXivから情報を検索してくるようになりました.
- result.authorsで著者名を取得すると, 「arxiv.Result.Author("AAA")」のようなもののリストが取得されます. そのため, 「著者を整形」のコメントより下のような処理を施すことで, 著者名が「; 」でつながった文字列を得ています.
- googletransモジュールは, 最新ver.を入手した方がバグが少なくなるようです. 一応「time.sleep(1)」も入れていますが, ご参考までに.
$ pip install googletrans==4.0.0-rc1
まとめ
あとはこれを毎朝実行する等の状況があれば強いです. 現状, 私はそれを実行する設定ができていないので, batファイルを作成してせめて1ダブルクリックで実行できるようにはしています. 毎朝実行するように設定出来たら, また新記事で紹介するかもしれません!
参考にしたサイト等
- 「arxiv · PyPI」
arxiv
Python wrapper for the arXiv API: http://arxiv.org/help/api/
- _yushuu様による「【python】googletransの『AttributeError: 'NoneType' object has no attribute 'group'』対策【2021/01/12追記】」
【python】googletransの『AttributeError: 'NoneType' object has no attribute 'group'』対策【2021/01/12追記】 - Qiita
2021/01/12 追記しました はじめに pythonでgoogletransライブラリを使って翻訳していると, ある日 AttributeError: 'NoneType' object has no attribut...
- 「【python】arXivから論文を取得してLINEで手軽に見たい」(プログラミング日記)
【python】arXivから論文を取得してLINEで手軽に見たい
今回はarXivのAPIを使って, 興味ある論文を引っ張ってきたいと思います. さらにぼくは英語が苦手なので, 概要を和訳して見れるようにしていきたいと思います. 経緯以前, Googlescholarをスクレイピングして論文を見ようとしたのですが,
- sugup様による「自動でArxivから論文を取得して, 日本語に直してLineに投稿すれば, 受動的に最新情報が収集できるかも!?」
自動でArxivから論文を取得して, 日本語に直してLineに投稿すれば, 受動的に最新情報が収集できるかも!? - Qiita
はじめに 最先端の論文は知りたいけど, 時間が無くて論文を読む気にならない. . . arXiv見ても英語でよくわからないから, 日本語がよい. . . Slackとかよくわかんないし, Lineに通知して欲しい. . . ということで, これら...
- ダン吉様による「Webhookって何?を子どもでもわかるように描いてみた」
Webhookって何?を子どもでもわかるように描いてみた
はじめに こんにちは. 最近娘に絵本を読むのがめんどくさいダン吉です. 今日は, 巷で話題のWebhookとは何かをわかりやすく伝えるために, 画力に圧倒的に自信のない私が恥を覚悟で, 子どもによく描いてあげる...
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)