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

PythonによるWebスクレイピング入門

antenna_three
September 27, 2019

 PythonによるWebスクレイピング入門

UTMC ( http://www.komaba.utmc.or.jp/ ) にて行ったプレゼンテーションです。
スクレイピング、HTML、Pythonの基礎を話したあと、東京大学教養学部前期教養のお知らせページをスクレイピングするコードを解説し、ちょっとした発展課題に取り組んでもらいました。

antenna_three

September 27, 2019
Tweet

More Decks by antenna_three

Other Decks in Programming

Transcript

  1. HTMLとは HyperText Markup Languageの略 HyperText 文字だけでなくリンクや画像も入れられるすごいテキスト Markup Language 文章構造を記述するための言語 cf.

    プログラミング言語 リンクや画像を入れたり、文章構造を記述するためにタグが用いられる タグは<タグ名>のように記述される
  2. HTML主要タグ <div> ページの部品を区別するなど <span> 文章の一部を区別するなど <h▪> 見出し (▪ = 1,

    2, 3, 4, 5, 6) <p> パラグラフ <a> リンク <img> 画像 <ol>, <ul> 箇条書き <li> 箇条書きの項目 <table> 表
  3. 変数・算術演算子 数 >>> x = 1 >>> x + 2.34

    3.34 文字列 >>> s = “It’s ” >>> t = ‘showtime!’ >>> s + t It’s showtime!
  4. リスト >>> l = [1, 3.14, ‘abc’] >>> l[1] 3.14

    >>> l.append([7, 8]) >>> l [1, 3.14, ‘abc’, [7, 8]] >>> len(l) 4
  5. 辞書 >>> d = {‘name’: ‘hiroshi’, ‘age’: 35} >>> d[‘name’]

    ‘hiroshi’ >>> d.update(job=’office worker’) >>> d {‘name’: ‘hiroshi’, ‘age’: 35, ‘job’: ‘office worker’}
  6. if文 >>> if 1 > 2: ... print(‘1 is greater

    than 2.’) ... else: ... print(‘1 is not greater than 2.’) ... 1 is not greater than 2.
  7. in演算子 bool演算子 >>> if 2 in [1, 2, 3]: ...

    print(‘2 in [1, 2, 3] == True’) 2 in [1, 2, 3] == True >>> ‘工業’ in ‘東京工業大学’ and ’工業’ not in ‘東京大学’ True
  8. for文 >>> members = [‘scott’, ‘Virgil’, ‘Alan’, ‘Gordon’, ‘John’] >>>

    for member in members: ... print(member) ... Scott Virgil Alan Gordon John
  9. こんなforはやめよう >>> for i in range(len(members)): >>> print(members[i]) for文の中でインデックスを使いたいときは? >>>

    for i, member in enumerate(members): ... print(str(i+1) + ‘: ‘ + member) ... 1: Scott 2: Virgil 3: Alan 4: Gordon 5: John
  10. クラス >>> class Dog(): ... def __init__(self, name): ... self.name

    = name ... def bark(self): ... print(‘I am ‘ + self.name) ... >>> dog = Dog(‘sushi’) >>> print(dog.name) sushi >>> dog.bark() I am sushi
  11. ライブラリのインポート import tkinter import tkinter as tk import tkinter.filedialog from

    tkinter import ttk, filedialog from tkinter.filedialog import (FileDialog as FD, askdirectory as ad, N, NS, NSEW)
  12. プログラムのソースコード from urllib.request import urlopen from bs4 import BeautifulSoup url

    = 'http://www.c.u-tokyo.ac.jp/zenki/news/index.html' html = urlopen(url) soup = BeautifulSoup(html, 'html.parser') div = soup.find('div', id='newslist2') dds = div.find_all('dd') for dd in dds: print(dd.a.text)
  13. その気になればimport以外は1行で書ける from urllib.request import urlopen from bs4 import BeautifulSoup print(‘\n’.join(dd.a.text

    for dd in BeautifulSoup(urlopen('http://www.c.u-tokyo.ac.jp/zenki/news/index.html'), 'html.parser').find('div', id='newslist2').find_all('dd')))
  14. 阿部寛のホームページのソース <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=x-sjis"> <title>阿部寛のホームページ </title> </head>

    <frameset cols=18,82> <frame src=menu.htm marginheight=0 marginwidth=0 scrolling=auto name=left> <frame src=top.htm marginheight=0 marginwidth=0 scrolling=auto name=right> </frameset><noframes></noframes> http://abehiroshi.la.coocan.jp/
  15. そのsoupのイメージ soup .head .meta [‘http-equiv’] = ‘Content-Type’ [‘content’] = ‘text/html;

    charset=x-sjis’ .title .string = ‘阿部寛のホームページ ’ .frameset [‘cols’] = [18, 82] .frame [‘src’] = ‘menu.htm’ [‘marginheight’] = 0 [‘marginwidth’] = 0 [‘scrolling’] = ‘auto’ [‘name’] = ‘left’
  16. ddsの内容 dds[0] .a [‘href’] = ‘http://www.c.u-tokyo.ac.jp/zenki/news/kyoumu/2019SS2_tuishi_nittei.pdf’ [‘target’] = ‘_blank’ .string

    = ‘2019年度Sセメスター(S2ターム)追試験時間割(再掲)’ .img [‘src’] = ‘http://www.c.u-tokyo.ac.jp/zenki/news/kyoumu/images/common/icon_pdf.gif’ dds[1] .a [‘href’] = ‘http://www.c.u-tokyo.ac.jp/zenki/news/kyoumu/20190924engineering.pdf’ [‘target’] = ‘_blank’ .string = ‘【工学部より】2020年度工学部システム創成学科 進学内定の学生各位’ .img [‘src’] = ‘http://www.c.u-tokyo.ac.jp/zenki/news/kyoumu/images/common/icon_pdf.gif’ dds[2] .a [‘href’] = ‘http://www.c.u-tokyo.ac.jp/zenki/news/kyoumu/firstyear/2019/0920170054.htm .string = 留年・降年による英語二列の履修について
  17. 日付とお知らせをセットで出力 for dt, dd in zip(div(‘dt’), div(‘dd’)): print(dt.text + ‘,

    ‘ + dd.a.text) zip 複数のリストをまとめてforで参照できる関数
  18. 結果をファイルに保存 from pathlib import Path ︙ ︙ dds = div.find_all(‘dd’)

    with Path(‘result.txt’).open(‘w’) as f: for dd in dds: f.write(dd.a.text + ‘\n’) pathlib ファイルパスをスマートに扱える標準モジュール