Upgrade to Pro — share decks privately, control downloads, hide ads and more …

あなたのOrganizationどうなの?Qiita API と スクレイピング

あなたのOrganizationどうなの?Qiita API と スクレイピング

「自分/あの組織が使っている技術がわからない🤔」「QiitaのOrganizationはみつけたけどいまいちよくわからない🧐」という悩みに答えそうなモノ(Pythonスクリプト)を作りました📝

この発表で次の3点ができる…ようになる気がします
1. PythonのrequestsでAPIにGETリクエストを送る
2. PythonのrequestsとBeautifulSoup4でスクレイピングができる
3. Qiita APIとGitHub APIを実践的に使う

ソースコードはこちら
https://github.com/ysd-marrrr/100days-of-code-sample/blob/20190828-pt27-parital/20190807-pt27-scraping-qiita-organization-users/scraping_organization_user.py

F5367e6dde42dda84768b5b145c12eef?s=128

Masataka Yoshida

August 29, 2019
Tweet

More Decks by Masataka Yoshida

Other Decks in Technology

Transcript

  1. あなたのOrganization どうなの? 2019/08/29 あえてジャンル不問の大LT大会 vol.2 Masataka Yoshida Qiita API と

    スクレイピング
  2. 吉田 匡孝(Masataka Yoshida) 株式会社オープンストリーム 戦略技術推進本部 目に見えるモノを作る+新しい技術に触れるおしごとがしたいなー !2 Web 
 CakePHP,

    Spring, Vue.js… その他いろいろ iOS/Android(Ionic, Objective-C, Java) … AWS, Python
  3. QiitaのOrganization !3

  4. この会社/団体は (Qiitaで) 何をやっているのか?

  5. 気にならなかったら
 そっ閉じでOKです

  6. 気になる点 • Organizationのページではユーザーが
 どんな投稿をしたのか俯瞰できない !6 0SHBOJ[BUJPOʹͭͳ͕͍ͬͯΔ ϢʔβʔΛௐ΂Δ 2JJUB (JU)VCͷ׆ಈঢ়گΛݟΔ •

    連携しているんだからGitHubの活動 状況も見たいよね
  7. 技術的には… • Organizationのページをスクレイピング してユーザーを列挙する • Qiita APIを使ってユーザーを調べる !7 0SHBOJ[BUJPOʹͭͳ͕͍ͬͯΔ ϢʔβʔΛௐ΂Δ

    2JJUB (JU)VCͷ׆ಈঢ়گΛݟΔ • Qiitaに紐付いたGitHubアカウントの
 リポジトリをGitHub APIで列挙する
  8. 必要なもの !8 Qiita/GitHubのアカウントは不要です 1ZUIPO #FBVUJGVM4PVQ スクレイピング pip install beautifulsoup4 3FRVFTUT

    HTTP通信 pip install requests
  9. Organizationに
 つながっている
 ユーザーを調べる

  10. Organizationに所属するユーザー • ユーザー全員のID(@以降の部分)が
 ほしい • 取得するAPIがない! !10 _人人人人人人人人人人人人人_ > よし、スクレイピングだ <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

  11. Organizationに所属するユーザー !11 • まず、取得したい部分をブラウザの開発者ツールで選択する • class, idで特定できるか考える

  12. スクレイピング(Beautiful Soup) 1. HTMLを取得する 2. HTMLをBeautiful Soupに読み込ませる 3. ほしい部分のclassを指定する 4.

    .contents で中身を取り出す !12
  13. スクレイピング(Beautiful Soup) !13 import requests response = requests.get(‘https://qiita.com/organizations/opst/ members’) 1.

    HTMLを取得する 2. HTMLをBeautiful Soupに読み込ませる from bs4 import BeautifulSoup html_soup = BeautifulSoup(response.text, features=‘html.parser’) requests.getで取得したHTMLは .text に入っているぞ!!
  14. スクレイピング(Beautiful Soup) !14 member_soup = html_soup.find('ul', attrs={'class', ‘p- organization_memberlist'}) member_list_soup

    = member_soup.find_all('div', attrs={'class', ‘od- MemberCardContent'}) 3. ほしい部分のclassを指定する .find
 一つ指定する .find_all
 すべて指定する
  15. スクレイピング(Beautiful Soup) !15 for m in member_list_soup: id = m.contents[0].find('span',

    attrs={'class', 'od- MemberCardHeaderIdentities_userid'}).contents[0] 4. .contents で中身を取り出す .find.contents -> @derui 必要に応じて更に .find してみたり、
 .contentsリストのインデックスを変えてみたり
 試す
  16. ページめくりも忘れずにね • 実際にページングを動かして、どのような状態になったら 最後のページに到達したか考える • rel=“next” が消えると最後のページに到達 !16

  17. Qiitaのユーザー情報 • ユーザーIDがわかればQiita APIを 叩いて詳細情報を取得する !17 GET https://qiita.com/api/v2/users/derui/ @derui ▼

    • ほしいのはQiitaに紐付いた GitHubのID • github_login_name
  18. Qiitaに紐付いているGitHub ID • requestsにはレスポンスのJSONをdictに変換
 してくれる .json() がある! • 変換に失敗すると None

    が返ってくる !18 user_req = requests.get(‘https://qiita.com/api/v2/users/derui/’) user = user_req.json() user[‘github_login_name’] ▼ derui(github_login_name)
  19. Qiitaユーザーの投稿 • 投稿順に記事が並ぶ • 記事1件だけを取得したいときは per_page=1&page_1 !19 GET https://qiita.com/api/v2/users/derui/items?page=1&per_page=1 •

    記事の本文(HTML&Markdown) • 記事のタイトル • 記事のタグ • 記事の最終更新日 • 記事のいいね・閲覧数 • 記事を書いたユーザー などなど 記事の本文はまるまる返ってきて
 長いので注意
  20. Qiita + GitHubの
 活動状況を見る

  21. GitHubのリポジトリ • 最新のリポジトリから順に見たいので sort=pushed !21 GET https://api.github.com/users/derui/repos?sort=pushed derui ▼ (github_login_id)

  22. GitHubのリポジトリ • リポジトリをフォークではなくイチから作っているか folk の値を見る • pushed_at はブランチを問わずpushされた時刻(UTC) !22 [

    { “full_name”: “derui/sxfiler”, “html_url”: “https://github.com/derui/sxfiler”, “folk”: false, “description”: “Simple and eXtensible Two-pane filer”, “language”: “TypeScript”, “pushed_at”: “2019-08-26T12:10:12Z”, … }, …
  23. リポジトリは30件/回のみ取得できる • 30件を超える場合は page パラメーターを設定する !23 Link: <https://api.github.com/user/97231/repos?sort=pushed&page=2>; rel="next", <https://api.github.com/user/97231/repos?

    sort=pushed&page=3>; rel="last" • レスポンスヘッダーの ”Links”に(必要に応じて)
 次・前・最初・最後のページのURLが載っている • rel=“next” が無くなるまでpagesをインクリメントすれ ばいいのでは GET https://api.github.com/users/derui/repos?sort=pushed&page=2
  24. 集めた情報を組み合わせれば完成! • Qiita・GitHubでどんな活動をしているか !24 • Qiita・GitHub合わせてどれくらい放置しているのか 技術を俯瞰して Organizationをアピール! サボってる子誰だ(?!)

  25. ToDo Qiitaはオワコン 別のBlogに載っている記事も加味したい • QiitaにつながっているBlogを見てmetaタグあたりから RSSを取り出せないかな… !25 Webサービス化したい(自分のアカウントで分析したい) • OAuthで認証情報をやり取りする

    ✴ Qiita/GitHubともにアカウントを使って認証するとAPI を呼び出せる回数が増える
  26. まとめ QiitaのOrganizationにいるユーザー全員を俯瞰できた • APIが用意されていない場面ではスクレイピングで
 対処することができた
 他のサイトで試すときは利用規約をみてね!! !26 結局スライド作るのに6時間かかった (もちろん)俯瞰するには企業/団体のメンバー全員が
 アウトプットしている場所が必要である

  27. 参考 • Qiita API v2ドキュメント - Qiita:Developer: 
 https://qiita.com/api/v2/docs •

    pythonでさくっとスクレイピング(Requests + Beautiful Soup 4) - Qiita: 
 https://qiita.com/Atupon0302/items/352811a2d92d6ebab8c2
 • Solved: Difference between "updated_at" and "pushed_at" in... - GitHub Community Forum: 
 https://github.community/t5/GitHub-API-Development-and/Difference-between- quot-updated-at-quot-and-quot-pushed-at-quot/td-p/22305
 !27