ハシカケ-実現したいことから学べるプログラミングサイトプログラミングを実現したいことから逆算して学べるサイトです。コピー2019.09.12このページでは、Pythonのスクレイピングを駆使して、はてなブックマークの特定のキーワードで検索した時の過去のエントリーをブックマーク数順にCSVにまとめるスクリプトのチュートリアルを公開します。このプログラムを使えば、下のようにずらーっとブックマーク数順にはてなブックマークのキーワード検索したエントリーをCSVにまとめることができるので、便利です。それでは、まずは完成したソースコードをお見せします。main()今回はちょっと複雑に見えますが、基本的には過去に解説したスクレイピングの記事と同じでBeautifulSoupとrequestsをメインで使います。未インストールの追加ライブラリのインストールを行うもし追加ライブラリのインストールがまだの場合は下記のコマンドを実行してインストールを行って下さい。beautifulsoup4また当プログラムではBeautifulSoup4の内部で使うhtmlパーサーにlxmlライブラリを指定しますので、これもインストールがまだの方はインストールを行って下さい。lxml検索したいキーワードを羅列したテキストファイルを用意するプログラムファイルと同じフォルダ内に「hatena_keyword.txt」というファイル名でテキストファイルを用意し、その中に検索したいキーワードを記入しておいて下さい。キーワードはいくつでも結構です。ソースコードの解説ここからはソースコードについて具体的に解説していきます。プログラムで使うライブラリをインポートする1~6行目では、今回のプログラムに必要なライブラリをインポートしています。Webページ取得に使用するためrequestsはPythonでhttp通信を行うための外部ライブラリです。詳しくはPythonでスクレイピングしてタイトルと見出しを取得するプログラムの記事をご覧下さい。スクレイピングするため(備考欄の取得のみ)BeautifulSoupはHTMLの構造を解析するためのスクレイピングに特化した外部ライブラリです。詳しくはPythonでスクレイピングしてタイトルと見出しを取得するプログラムの記事をご覧下さい。絶対URL取得のためurllib.parseはURLの解析に使われるモジュールです。今回は完全なURL(=絶対URL)を獲得するのに使用するurljoinをインポートしています。待ち時間を指定するため待ち時間を指定するsleep関数を使用するためtimeモジュールをインポートしています。CSVファイルを書き込みするためCSVファイルを扱うために使用するcsvモジュールをインポートしています。文字列抽出のため正規表現を使った文字列の抽出処理に使用するreモジュールをインポートしています。'はてなブックマーク'main関数実行中にてページ遷移の状態を確認するために使用する変数TITLEに値「はてなブックマーク」を設定しています。main関数を定義する12~151行はこのプログラムのメイン処理となるmain関数の定義部分となります。それでは各処理部分について詳細に解説していきます。f.readlines()]検索したいキーワードが記載されている「hatena_keyword.txt」を1行ずつ読み込んで変数keyword_listに格納しています。f:ファイルを開くopen()メソッドと共にwith構文が使われています。openだけで開くとファイルを閉じる処理も記述しなければいけないのですが、with構文を使うとファイルを自動で閉じてくれるので、閉じる操作を記述する手間が省けて便利です。f.readlines()]ここではファイルを1行ずつ取り出す処理を記述するのにリスト内包表記という表記方法が使用されています。リスト内包表記を使うと処理をすっきりと記述することができます。リスト内包表記は以下のような構造になっています。リスト]リスト(ここではf.readlines())の要素が一つずつ取り出されては変数(ここではs)に格納されていき、その変数sを使って式の部分(ここではs.rstrip())にて必要な処理や評価が行われた結果が最終的に新たなリストとなって返されます。readlines()はファイル全体をリストとして読み込むメソッドです。rstrip()は指定した文字列の末尾にある空白文字(改行コードやタブなど)を取り除くのに使うメソッドです。プログラム内で処理する文字列に余計な空白文字がついたままですと予期せぬエラーの原因になることがありますのでファイルなどから取り出した文字列は処理の前にstripメソッド(strip、lstrip、rstrip)を使って整形しておくと安全です。keyword_list:for構文でリスト変数keyword_listから要素を一つずつ取り出し変数keywordに格納していきます。keyword)print関数で処理対象のキーワードをコマンドプロンプトに表示しています。[]リスト変数item_listは初期化しておきます。'&sort=recent&users=50&safe=on'スクレイピングするサイトのURLを変数urlに格納しています。現在検索対象となっているキーワードが「Python」ならば値はhttps://b.hatena.ne.jp/search/text?q=Python&sort=recent&users=50&safe=onとなります。'lxml')変数urlに格納されているURLにアクセスしてサイトから情報を取得する処理部分になります。requests.get()メソッドでレスポンスを取得します。verify=False)と記述してあります。これは普通にリクエストを送る記述(requests.get(url))にてアクセスするとサイトによってはSSL関係のエラーが出てうまくいかないケースがありますのでそのような場合のエラー回避対策となっています。SSL関係のエラーが出るサイトにはキーワード引数verifyにFalseを指定することでエラーが出ずにレスポンスを取得することができます。次にtime.sleep()関数を使って1秒間待機した後取得したレスポンスをBeautifulSoup()メソッドでパースします。BeautifulSoupで使われるhtmlパーサーについてBeautifulSoup内部で使われるhtmlパーサーは、特に何も指定しないとデフォルトで「html.parser」が使用されるようになっています。このままでもよいのですがhtml.parserは性能があまり良くないので第2引数に性能のいい「lxml」を明示的に指定しておくことで処理の高速化が見込めます。lxml以外には「html5lib」というhtmlパーサーもあります。titleここでは目的のページに正しくアクセスできているかチェックしています。チェックにはWEBページに含まれているタイトルを利用します。タイトルはHTMLソース内では<title>タグで挟まれて記述されています。BeautifulSoupでパースしたWEBページデータが格納されている変数soupに「title.text」をつけることによって<title>タグの文字列を取り出して変数titleに格納しています。はてなブックマーク(〇〇には検索対象のキーワード名が入ります)という構造になっています。そのため・タイトルに「はてなブックマーク」という文字列が含まれているか・タイトルに検索キーワードが含まれているかをチェックすることで正しいページであるかどうかを判断できます。チェックにはassert文を使います。どちらか一つでもタイトル内に含まれていなかったらエラーとなりプログラムがストップするようになっています。'ページ目')42~147行目は実際にはてなブックマークのページから目的のデータを取り出す処理となります。42行目でページ数をカウントするのに使用する変数page_countを用意しています。次に43行目のwhile文で条件式に真偽値のTrueを指定してここの処理部分を永久ループとしてあります。指定したキーワードでの検索結果が全部で何ページあるかは不明なため、後述するbreak文によってループを抜けるまでは処理を何回も繰り返すことを意味します。45行目のprint関数で現在処理中のはてなブックマークのページ数を表示しています。breakWEBページに対して繰り返し処理を行っていると、時にはWEBページが使用しているサーバーの不調が原因でサーバーエラーが発生することがあります。サーバーエラーが発生するとタイトル内に「サーバーエラーが発生しました」という文言が表示されるようになっています。ここではタイトル内に「サーバーエラーが発生しました」という文字列が含まれていないかをチェックし、もし含まれていたらそこでループ処理を中断して次の処理に移るようにしてあります。{}53行目はCSSセレクタを使用してページ内から検索結果の各項目が記載されている部分を取り出しています。js-keyboard-selectable-itemが指定されているものが今回対象となる要素になります。soup.select()メソッドの引数に.bookmark-item.js-user-bookmark-item.js-keyboard-selectable-itemと指定してそのページに存在する該当要素を全て取得し、変数itemsに格納しています。それを次の行のfor文で1つずつ取り出して変数itemに格納し、次行以降でitemを使って処理が行われます。55行目では取り出した情報を辞書形式で格納するために使用する変数item_dictを用意しています。0item内に格納されているデータの中からブックマーク数を示している要素部分をCSSセレクタで取り出しています。して取り出したブックマーク数を表す要素を変数bookmarksに格納しています。取り出した要素に含まれるブックマーク数をitem_dictに格納する前に、以下の3点についてチェックします。bookmarks[0].text.strip():の各if文で判断しています。このうち3つ目につきましては17~19行目のところで解説したstripメソッドを使ってテキスト情報(bookmarks[0].text)の両端にある空白文字を全て除去してから判定しています。テキスト情報に空白文字以外の文字が含まれていなかったらなにも残らないということですので判定結果は偽となります。3つのチェック項目についてif文の判定結果が全て真の場合のみitem_dictにブックマーク数が格納され、それ以外は数値の0が格納されます。bookmarks[0].text.strip())search()メソッドの第1引数に検索パターンとしてr'(\d+)’を指定しています。正規表現で「\d」は「0~9の半角数字1つ」を表し「+」は「直前の文字の1回以上の繰り返し」を表します。「\d+」は「1桁以上の半角数字」を表す正規表現となり、これで○○の数字の部分だけを取り出すことができます。search()メソッドで取り出して変数mに格納された数字(=ブックマーク数)は通常は正常なブックマーク数を表しているのですが、まれに元データの異常などにより数値と認識できない値の場合もありますので取り出した数字データについても・データ自体があるか・取り出したデータが全て十進数の数字のみで表されているかの2点を格納前にチェックします。それぞれ下記のif文で判断しています。m.group(1).isdecimal():2つの判定結果について両方とも真の場合のみitem_dictにブックマーク数が格納され、それ以外は数値の0が格納されます。変数mに格納された数字は一見普通の数値のように見えますが実はプログラム内では「文字列」として認識されるデータ型になっていますので、item_dictに格納する前に整数型に変換しておく必要があります。文字列型から整数型への変換には下記のようにint関数を使用します。''先のブックマーク数と同様にitem内に格納されているデータの中から投稿日時を示している要素部分をCSSセレクタで取り出し変数datesに格納しています。CSSセレクタの引数は「.entry-contents-date」となります。投稿日時についても・要素自体があるか・テキスト情報自体はちゃんとあるか・テキスト情報が空文字(スペースなど)でないかのチェック項目3点をif文で判定し、全て真の場合のみitem_dictに投稿日時を格納し、それ以外は空白を格納します。''ブックマーク数・投稿日時と同じようにタイトル・URL情報を取り出します。こちらもそれぞれチェック項目3点をif文で判定し、全て真の場合のみitem_dictに格納し、それ以外は空白を格納します。リストに追加item_list.append(item_dict)item_dictに格納しておいたブックマーク数・投稿日時・タイトル・URL情報のデータをitem_listに追加していきます。breakキーワードでの検索結果が複数ページある場合は次のページを読みに行く必要がありますのでここでは次ページに遷移するための処理を行っています。次のページのようなリンクが表示されています。a」を指定してタグ情報を取得し変数nextsに格納します。格納したタグ情報をブックマーク数などの処理時と同様にif文でチェック項目を判断し、全て真の場合のみ次ページ遷移処理を行い、それ以外は次ページが存在しないと見なしてbreak文を使ってwhile文を抜けます。全て真の場合に行う次ページ遷移処理に使用するURLを134行目のところで用意しています。nexts[0].get('href').strip())次ページへのリンクを表す<a>タグ内でのhref属性を見ると、下記のようにURLは絶対URLではなく相対URLで指定されています。href=”/search/text?q=python&amp;users=50&amp;page=2′′そのためurljoin()関数を使って相対URLを絶対URLに変換してから変数next_urlに格納しています。第1引数の基底URLには27行目で用意したurlを指定します。その次のrequests.get()メソッドでは29~35行目での処理と同じくtry~except文を使ってSSL関係のエラー対策を行っています。レスポンスを取得した後は1秒間待機してからBeautifulSoup()メソッドでパースを行います。次ページ遷移処理の最後にpage_countの値を1増やしています。keyword)main関数の最後にCSVファイルへの出力処理を行っています。メッセージを表示してから後述するwrite_csv関数を実行しています。write_csv関数を定義する154~177行はmain関数で取得したスクレイピングデータをCSVファイルに書き出す処理を行うwrite_csv関数の定義部分となります。それでは各処理部分について詳細に解説していきます。'URL']後述するDictWriter()メソッドでオブジェクト作成時に必要となるヘッダー情報を用意しています。reverse=True)item_list内のデータを、「ブックマーク数」をソートキーにして降順でソートしています。キーワード引数keyで使用されているのはラムダ式と呼ばれる無名関数の記述方法です。x[‘ブックマーク数’]とすることでitem_listの要素が引数xに入り、x[‘ブックマーク数’]をキーとして返しています。今回は降順でソートするのでキーワード引数reverseにはTrueを設定します。上書きモードで開くスクレイピング結果を出力するCSVファイルのファイル名を「○○.csv(○○はキーワード名)」として上書きモードで開きます。keys)辞書型のデータを書き込むのに使われるDictWriter()を利用してwriterオブジェクトを作成しています。第2引数には159~165行目で用意したkeysを指定しています。172行目:writer.writeheader()writeheader()メソッドを使用してヘッダーを出力しています。writer.writerow(item)item_list内のデータを1行ずつ取り出して出力しています。出力前にブックマーク数をチェックし0の場合は空白に変換しています。最後にwriterow()メソッドを使用してデータ行を出力しています。main()main関数を実行する処理です。‘__main__’:とすることでプログラムが単体で実行された時のみ動作するようにしています。変数というものを使うことで、Pythonが何倍も使いやすくなります。変数を使えば、数...PythonPythonでMicrosoftの画像認識APIを利用して、適切な説明を自動でつけるプログラム今回ご紹介するPythonのプログラムは、Pythonで画像認識APIを利用して、インターネット上の画像データに適切な説明を自動でつけるプログラムです。本記事は、こんな悩みを解決する内容です。「制御構文」は、記述することでプログラムの動きをコントロールする構文です...PythonPythonでWordPressに複数の記事を自動投稿してくれるプログラム今回のPythonスクリプトは指定したフォルダに入れたテキストファイルのWordPressへの複数の記事の投稿を自動で一括で行ってくれるプログラムです。「Pythonをインストールしたいが、どうするのが一番良いのかわからない。インストール方法は色々あるようだし、公式サイトも英語だから単語を読むのも一苦労...初心者でも簡単にわかる言葉で、Pythonをインストールするまでの手順を説明してほしい...PythonPythonの辞書(dict)について詳しく解説Pythonには辞書というデータ型があります。この辞書はdict型オブジェクトと言われることもあります。定義としてはkey(キー)とvalue(値)がセットになっているリストのようなイメージです。コメントをキャンセルメールアドレスが公開されることはありません。*サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。ハシカケとは?Hashikakeハシカケは、改善したい、効率化したいなどの実現したいことからプログラミングを学ぶことができるサイトです。ハシカケ-実現したいことから学べるプログラミングサイト.ホーム検索トップサイドバーハシカケとは?Hashikakeハシカケは、改善したい、効率化したいなどの実現したいことからプログラミングを学ぶことができるサイトです。未インストールの追加ライブラリのインストールを行う検索したいキーワードを羅列したテキストファイルを用意するソースコードの解説プログラムで使うライブラリをインポートするページ遷移チェック用変数を用意するmain関数を定義するBeautifulSoupで使われるhtmlパーサーについてwrite_csv関数を定義するmain関数を実行するタイトルとURLをコピーしました。