LoginSignup
4
1

More than 3 years have passed since last update.

CVPR2020の論文を毎日自動で送ってくれるslack botを作ってみた!

Last updated at Posted at 2020-07-19

経緯

最近はCVPR2020の論文の要約を読んで、面白そうな論文はmendeleyにストックするという作業をやっています。その作業が結構大変です。理由は以下の通りです。

  • 採択されている論文が多い(1500ぐらいだったような)
  • あんまり興味がない論文が結構ある。Adversarial attacksの防御論文多すぎ(笑)。
  • わからない英単語が結構あるので、google翻訳でその都度調べる

このような理由でどうにか作業をもっと簡単にしたいと思い、以下のようなシステムを作ることにしました。

プログラムの手順

  1. スクレイピングでCVPR2020の公式サイトから論文のタイトル要約pdfのリンクを取ってくる。
  2. 要約を和訳する。
  3. 要約の中で、あまり興味がない内容の単語が入っている場合は別にする。今回はAdversarial attacks系の論文。
  4. 論文のタイトル、要約、要約を和訳したもの、pdfのリンクを1時間おきにslackのチャンネルに自動で配信する

手順ごとに自分の実装を説明していきます。

1. スクレイピング

def main():
    # CVPR2020のサイト情報を取得
    headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"
        }
    url_name = "https://openaccess.thecvf.com/CVPR2020"
    url = requests.get(url_name, headers)
    soup = BeautifulSoup(url.content, "html.parser")
    # 論文情報がdtダグの中にあるのでその情報を取得する
    elems = soup.find_all("dt")
    for elem in tqdm(elems):
        url = elem.next.next.attrs['href']
        ori_link = "https://openaccess.thecvf.com/"
        contents_url = ori_link + url
        paper_link = requests.get(contents_url, headers)
        paper_soup = BeautifulSoup(paper_link.content, "html.parser")
        title = paper_soup.find('div', id="papertitle").text
        abstract = paper_soup.find('div', id="abstract").text

beautfulsoupを使っています。CVPRの論文はサイト上で以下のような感じで並んでいます。
Screenshot from 2020-07-19 20-46-04.png
それぞれのタイトルをクリックするとその論文の詳細ページに飛びます。
Screenshot from 2020-07-19 20-48-10.png
このページから論文のタイトル、要約、pdfのリンク(下のリンク)をスクレイピングします。

2. 要約の和訳

abstract_ja = translator.translate(abstract, src='en', dest='ja')
abstract_ja = str(abstract_ja.text)

googletransを使いました。こちらを参考にしました。

3. Adversarial attacksの排除

def sort_class(abstract):
    sentence = abstract
    adversarial_1 = re.search("adversarial attacks", sentence)
    adversarial_2 = re.search("Adversarial Attacks", sentence)
    adversarial_3 = re.search("adversarial examples", sentence)
    adversarial_4 = re.search("Adversarial Examples", sentence)
    adversarial_5 = re.search("adversarial robustness", sentence)
    adversarial_6 = re.search("Adversarial Robustness", sentence)
    adversarial_7 = re.search("adversarial noise", sentence)
    adversarial_8 = re.search("Adversarial Noise", sentence)
    if adversarial_1 != None or adversarial_2 != None or adversarial_3 != None or adversarial_4 != None or adversarial_5 != None or adversarial_6 != None or adversarial_7 != None or adversarial_8 != None:
        class_name = "adver"
        return class_name
    else:
        class_name = "other"
        return class_name

ちゃんと正規表現をやればもっと簡単にできると思います。今回は馬鹿正直に候補を全て書きました。adversarial attacksの論文は別のチャンネルに上げるようにします。

4. slackに自動配信

slackwebを使いました。使い方をこちらを参考にしました。コード全体を下にまとめます。

post_to_slack.py
import re
import time
import slackweb
import requests
from tqdm import tqdm
from bs4 import BeautifulSoup
from googletrans import Translator
translator = Translator()


def sort_class(abstract):
    sentence = abstract
    adversarial_1 = re.search("adversarial attacks", sentence)
    adversarial_2 = re.search("Adversarial Attacks", sentence)
    adversarial_3 = re.search("adversarial examples", sentence)
    adversarial_4 = re.search("Adversarial Examples", sentence)
    adversarial_5 = re.search("adversarial robustness", sentence)
    adversarial_6 = re.search("Adversarial Robustness", sentence)
    adversarial_7 = re.search("adversarial noise", sentence)
    adversarial_8 = re.search("Adversarial Noise", sentence)

    # 対象の単語がある場合は別にしておく
    if adversarial_1 != None or adversarial_2 != None or adversarial_3 != None or adversarial_4 != None or adversarial_5 != None or adversarial_6 != None or adversarial_7 != None or adversarial_8 != None:
        class_name = "adver"
        return class_name
    else:
        class_name = "other"
        return class_name


def main():
    headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"
        }
    url_name = "https://openaccess.thecvf.com/CVPR2020"
    url = requests.get(url_name, headers)
    soup = BeautifulSoup(url.content, "html.parser")
    elems = soup.find_all("dt")
    for elem in tqdm(elems):
        url = elem.next.next.attrs['href']
        ori_link = "https://openaccess.thecvf.com/"
        contents_url = ori_link + url
        paper_link = requests.get(contents_url, headers)
        paper_soup = BeautifulSoup(paper_link.content, "html.parser")
        title = paper_soup.find('div', id="papertitle").text
        abstract = paper_soup.find('div', id="abstract").text
        abstract_ja = translator.translate(abstract, src='en', dest='ja')
        abstract_ja = str(abstract_ja.text)
        pdf = paper_soup.find("dd").find("a").attrs['href'][6:]
        pdf_link = ori_link + pdf
        class_name = sort_class(abstract)

        attachments_title = []
        attachments_contents = []
        paper_title = {"title": title,
                "text": pdf_link}
        paper_contents = {"title": abstract,
                "text": abstract_ja}
        attachments_title.append(paper_title)
        attachments_contents.append(paper_contents)

        # adversarial attacksとその他の論文で分けてslackに通知する
        if class_name == "adver":
            slack = slackweb.Slack(url="YOUR_TOKEN")
            slack.notify(attachments=attachments_title)
            slack.notify(attachments=attachments_contents)
        else:
            slack = slackweb.Slack(url="YOUR_TOKEN")
            slack.notify(attachments=attachments_title)
            slack.notify(attachments=attachments_contents)

        time.sleep(3600)


if __name__ == "__main__":
    main()

完成したslack bot

Screenshot from 2020-07-19 21-09-06.png
論文のタイトル、pdfのリンク先、要約、要約を和訳したものの順で並んでいます。これが1時間ごとに自動で配信されます。herokuにデプロイしました。

感想

スクレイピングめっちゃ楽しかったです。ちょっとハマりそうです(笑)。ちなみにこちらに今回のCVPRの論文も含めた様々な論文のチャンネルがあるslackのworkspaceを作ったので、お気軽に参加してください。コードの中でおかしいところとかありましたらコメントください。

間違いや質問、ご意見等ありましたらお気軽にコメントください。頑張って答えますので(笑)。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1