PythonでWebスクレイピングしてみた
私はジャズが好きで、ちょくちょくライブに行きます。
前々から複数のライブハウスの予定を一気に表示してくれるサービスなんて無いかなあと思っておりました。
ふと調べてみたら、あるじゃないですか簡単そうな方法が・・・!
ということでPythonでWebスクレイピングに挑戦してみました。
最も有名と言われているスクレイピングのPythonライブラリ、PyQueryを使います。
例のごとく、インストールはpipで一発です。
pip install pyquery
PyQueryではその名の通りjQuery風のセレクタを使えるということだったのですが、jQueryなにそれ美味しいの?状態だったので、ドットインストールでひと通り勉強。
凄くシンプルな記述で、対象のhtmlから扱いたい要素を指定できるということですね。
今回は、ブルーノート、コットンクラブ、ピットイン、晴れたら空に豆まいての4つのライブハウスから、指定した月の日にちごとにライブの予定(ライブのタイトル)を取得し、データフレームにおさめて、最後にhtmlの表にして吐き出すスクリプトを書いてみました。
なにしろ独学素人なので美しくないところもあるかと思いますが、とりあえず欲しい結果は得られた模様です。
それぞれのサイトのhtmlをじっくり見ながら、どうやって欲しい情報(ライブのタイトル)が記述されてる要素を指定するか検討します。
# -*- coding:utf-8 -*- from urllib import request from pyquery import PyQuery as pq import pandas as pd from pandas import Series, DataFrame # 取得したい年と月 year = 2015 month = 7 # 1ケタの月が01でなく1になってしまうので調整 if month < 10: monthstr = '0' + str(month) else: monthstr = str(month) # 指定した月の日にちのリストを作成 import calendar days = [day for day in range(1, calendar.monthrange(year, month)[1] + 1)] # ----------------------------------------------------------------------------- # ブルーノートから取得 resp = request.urlopen("https://reserve.bluenote.co.jp/reserve/schedule/move/%d%s" % (year, monthstr)) html = resp.read().decode("utf-8") query = pq(html) bluenoteResults = [] for bluenote_days in query.find("span.day").closest(".oldBox"): if pq(bluenote_days)('tr')('td:last').text() == str('PRIVATE'): bluenoteResults.append('PRIVATE') else: bluenoteResults.append(pq(bluenote_days).next().next().find("span.text:eq(0)").text()) for bluenote_days in query.find("span.day").closest(".todayBox"): if pq(bluenote_days)('tr')('td:last').text() == str('PRIVATE'): bluenoteResults.append('PRIVATE') else: bluenoteResults.append(pq(bluenote_days).next().next().next().find("span.text:eq(0)").text()) for bluenote_days in query.find("span.day").closest(".later"): if pq(bluenote_days)('tr')('td:last').text() == str('PRIVATE'): bluenoteResults.append('PRIVATE') else: bluenoteResults.append(pq(bluenote_days).next().next().find("span.text:eq(0)").text()) bluenoteResults = DataFrame(bluenoteResults, index=[days], columns=["bluenote"]) # ----------------------------------------------------------------------------- # コットンクラブから取得 resp = request.urlopen("http://www.cottonclubjapan.co.jp/jp/schedule/%d%s.php" % (year, monthstr)) html = resp.read().decode("utf-8") query = pq(html) cottonResults = DataFrame(days, index=[days], columns=["cotton"]) for i in days: for cotton_lives in query.find("#sched_box"): if '%d.%d.' % (month, i) in pq(cotton_lives).find('p.day').text(): cottonResults.ix[i] = pq(cotton_lives).find('p.title').text() else: pass # ----------------------------------------------------------------------------- # ピットインから取得 if month == 1: pitinnMonthStr = '12' pitinnYear = year - 1 elif month < 10: pitinnMonthStr = '0' + str(month - 1) pitinnYear = year else: pitinnMonthStr = str(month - 1) pitinnYear = year resp = request.urlopen("http://www.m-works.info/pitinn/calend_j_p.php?YM=%d%s&MOVE=Next" % (pitinnYear, pitinnMonthStr)) html = resp.read().decode("utf-8") query = pq(html) pitinnResults = [] for pitinn_days in query.find("B"): pitinnResults.append(pq(pitinn_days).text()) pitinnResults = DataFrame(pitinnResults[1:], index=[days], columns=["pitinn"]) # ----------------------------------------------------------------------------- # 晴れ豆から取得 resp = request.urlopen("http://mameromantic.com/?m=%d%s&cat=1" % (year, monthstr)) html = resp.read().decode("utf-8") query = pq(html) hareResults = DataFrame(days, index=[days], columns=["haremame"]) for i in days: for hare_lives in query.find("div.entry"): if '%d.%d.' % (month, i) in pq(hare_lives).find('a:eq(0)').text(): hareResults.ix[i] = pq(hare_lives).find('a:eq(0)').text()[12:-2] else: pass allResults = pd.concat([bluenoteResults, cottonResults, pitinnResults, hareResults], axis=1) htmlout = allResults.to_html() f = open('jazzlive%d%s.html' % (year, monthstr), 'w') f.write(htmlout) f.close()
こんな感じで、以下のような表が得られました。
This Post Has 0 Comments