「ホッテントリを解析すればホッテントリ入りの記事を量産できる。」
なんて噂を聞きました。
それじゃ試してみるか、ってことで、まずは一歩目。ホットエントリーのスクレイピングから初めてみます。
環境
- Python3
- コーディング・動作テスト:Windows / 本番:Raspberry pi
- 僕のスキル:コーディング初心者 (ノギスとドライバを愛するメカ屋なのです)
最終的には、定期的にスクレイピングして解析後に出てくるホットなワードを勝手に通知し続けるところまでやりたい。
となるとマシンは動かしっぱなしになるので、ラズパイで動かすことを前提としてやりました。
パッケージインストール
pip install requests pip install beautifulsoup4 sudo apt-get install python-lxml
ラズパイでは、pip install lxml
が通りませんでした、謎。
コード
requestsでスクレイピングしてbeautifulsoup4で解析します。
Pythonでのスクレイピングはやってる人が多くて、先人の知見に大いに助けられました。最後の方にお世話になったページをまとめているので、スクレイピングに挑戦しよう!って人は見てみてください。
import requests import bs4 import csv # ホットエントリページの取得、解析 headers = {"User-Agent": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.84 Safari/537.36"} #User-Agentは自身のブラウザとOSを設定する res = requests.get("http://b.hatena.ne.jp/hotentry", timeout=10, headers=headers) bs_res = bs4.BeautifulSoup(res.text, "lxml") # はてブ数とタイトルの取得 hotentry = [] for x in bs_res.findAll("div", attrs={"class":"entrylist-contents"}): a_tag = x.find("a", attrs={"class":"js-keyboard-openable"}) hatebu_num = x.find("a", attrs={"class":"js-keyboard-entry-page-openable"}) if a_tag is not None: hotentry.append((hatebu_num.find("span").text, a_tag.attrs["title"], a_tag.attrs["href"])) # はてブ数でソート hotentry = sorted(hotentry, key=lambda x:int(x[0]), reverse=True) # 確認用に表示 for x in hotentry: print('{} || {} \n {}'.format(x[0], x[1], x[2])) # csvに出力 f = open('hatebu.csv', 'w') #f = open('hatebu.csv', 'w', encoding='CP932', errors='ignore') windows環境用、エンコードエラー回避 writer = csv.writer(f, lineterminator='\n') for x in hotentry: writer.writerow(x) f.close()
<上記コードで出来なかった時用>タグとclassの確認
時間が経つとclassが変わったりして動かなくなるかもしれません。そんな時は開発者ツールを使って取得したい情報のclassを確認しに行きましょう。
ブラウザで目的のページにアクセスし、F12を押す
右側に宇宙語の羅列が出てきます。
抽出する要素を探す
①開発者ツール左上のアイコンをクリック(Ctrl+Shift+c)
②目的ページ内の欲しい要素をクリック
③ページコード内の欲しい要素が見つかる
コードの修正
コードの中で、findAllやfindで要素を検索しているところを、上記で抽出したものに置き換えます。
"div"
や"a"
といったタグや、{"class":"entrylist-contents"}
といった検索条件のところを弄る感じですね。
# はてブ数とタイトルの取得 hotentry = [] for x in bs_res.findAll("div", attrs={"class":"entrylist-contents"}): a_tag = x.find("a", attrs={"class":"js-keyboard-openable"}) hatebu_num = x.find("a", attrs={"class":"js-keyboard-entry-page-openable"}) if a_tag is not None: hotentry.append((hatebu_num.find("span").text, a_tag.attrs["title"], a_tag.attrs["href"]))
取得できた
CSVの方もバッチリです。やったー!
まとめ
Pythonを使ったスクレイピングで、はてブのホットエントリー情報を抽出することができました。
今後は、ホットエントリーの情報をワード毎に抽出して、はてブ数とかを目安に重みづけしたりして、僕の得意分野と照らし合わせて、得意分野の記事を作っていければ面白いなー、とか考えています。
以上のような、ざっくりした構想はあるものの具体的な手段は全然思い至ってません。WordCloudで可視化して人力でキーワードを見つけるとか?そもそも、エントリーのタイトルからキーワード抽出するのどうやるんだっけ?
まだまだ、そんなレベルです。僕の求めるホットエントリー・スナイプ記事はまだ遠い!
参考リンク
PythonでWebスクレイピングする時の知見をまとめておく - Stimulator
●コードコピーする時に、一通り目を通しておくと理解が深まります
PythonでHatenaブックマークのホットエントリを取得して表示する - Stimulator
●見るとわかりますが、こちらのコードを参考に書いてます
HTTPメソッド(CRUD)についてまとめた
●勉強用。そもそもgetとか良く分かんなかったので
HTMLスクレイピング — The Hitchhiker's Guide to Python
ラズパイでスクレイピングする時の詰みポイント
●ラズパイでlxmlがpip出来ない時、ほんと助かりました
Pythonでcsvファイルに出力
●CSVで出力する時に参考にしました
Python エラー'cp932' codec can't encode character - スタック・オーバーフロー
●Windows環境でCSV出力時、文字コードエラーでハマった時の助けになりました
こんな記事も書いています
temcee.hatenablog.com
csvではなく、スプレッドシートに記載してもいいですね。
temcee.hatenablog.com
ラズパイの3Dデータ作ってます。