google analyticsがあるcgiがinternal server errorになっていることを報告してきて、
それを直している過程で、
perl (LWP)でやっているスクレイピングが時代遅れ
pythonの2系は時代遅れ
ということを悟ったので、3系(3.6)をインストールした。
2.6とか2.7とかいろいろ入ってしまったのできれいにしようと思ったのだが、
うまく消えないのでとりあえず3系がデフォルトで動くようにした。
# pip install beautifulsoup4
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python2.7/site-packages (4.7.1)
Requirement already satisfied: soupsieve>=1.2 in /usr/local/lib/python2.7/site-packages (from beautifulsoup4) (1.8)
Requirement already satisfied: backports.functools-lru-cache; python_version < "3" in /usr/local/lib/python2.7/site-packages (from soupsieve>=1.2->beautifulsoup4) (1.5)
#
beautifulsoupなる便利なものがあると聞いて使ってみようとしたら「まだ2.7なんか使ってんのかよ」と怒られた。
# python --version
Python 2.6.6
python
とだけやると、2.6.6が起動する。
python3.6
とやれば3系が動くようにはなっているが、面倒。
# python3.6
Python 3.6.7 (default, Dec 5 2018, 15:02:16)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
"python" はシンボリックリンクなので、
それを3系にリンクしなおせばよい。
# which python
/usr/bin/python
# which python3.6
/usr/bin/python3.6
pipも
# which pip3.6
/usr/bin/pip3.6
# which pip
/usr/local/bin/pip
# ln -s /usr/bin/python3.6 /usr/bin/python
ln: creating symbolic link `/usr/bin/python': ファイルが存在します
現在のリンクを消してから3系へのリンクを作る。
# unlink /usr/bin/python
# ln -s /usr/bin/python3.6 /usr/bin/python
# ln -s /usr/bin/pip3.6 /usr/local/bin/pip
ln: creating symbolic link `/usr/local/bin/pip': ファイルが存在します
pipも同様
# unlink /usr/local/bin/pip
# ln -s /usr/bin/pip3.6 /usr/local/bin/pip
# python
Python 3.6.7 (default, Dec 5 2018, 15:02:16)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
# pip -V
pip 9.0.1 from /usr/lib/python3.6/site-packages (python 3.6)
pythonもpipも3系になった。
このブログを検索
2019/03/02
2012/12/20
2ちゃんねるでスクレイピングが失敗する
さくらのVPSサーバから、あるサイトにアクセスし、そのWEBサイトの情報の一部を取り出すという事をしている。いわゆる「スクレイピング」である。
最初はperlで、LWP::Useragentなどを使って、あるサイトの情報を取り、あとは正規表現などを使って試行錯誤しつつ欲しい情報のみを取り出した。 特に難しいことはない。
ところが、同じ事を2ちゃんねるでやってみたら、うまくいかない。やろうとしたのは、ニュース速報の上位のスレッドタイトルを取得することだった。 2ちゃんねるは掲示板のメニューがあってそこに各掲示板のURLが記載されている。そしてその掲示板のURLはかなり頻繁に変更されるので、そのときアクセスできているURLに固定でアクセスせずに、メニューからURLを取得しなければならない。 その、メニューからURLを取得することはできたのだが、そこから取得したURLへアクセスすると、どうしてもHTMLの内容が取得できないのだ。
まずは、「302 Found」というエラーになる。これはリダイレクトされたときに出るもののようで、あるところで
同じperlスクリプトをローカルPCで動かしても同じ状況になる。 もちろん、ブラウザやギコナビなどでは問題なくアクセスできている。 昨日はここまでやって、あきらめて寝た。
そして今日、perlのスクリプトでアクセスしたときと、ブラウザでアクセスしたときのパケットをwiresharkでキャプチャして比較してみた。
すると、GETしているときに、・・・・ と、ここまで書いてuseragentが違うことに気づいた。 perlで書いたものは何も設定しておらず、lwpの初期値が入っている。 これを'Mozilla'に変えたら・・・いけた。
昨日、変えてダメだったような記憶があったんだけどな・・・ ま、いいや。 これだけでいけるようになるということは、2ちゃんねるの「スクリプトキディ」除けかな。
今日はWEBでphpをつかったスクレイピング例を見つけてそれがうまく動いたのでそれをいじっていた。
しかし今度はphpの動作で不可解なところがでてきた。 まず、phpをcgiとして動かすために必要な設定がなんなのか。 いろいろと情報があるのだが、皆条件付でスパっと「ここをこうする!」という情報がない。
これも試行錯誤で試して、なんとかうごいた。 前回はこんなに苦労した記憶はないのに・・・。 さらに、いちおう動いたのだが、出力する内容が全部そのまま出てしまう。 htmlのリンクとかを書いても、そのまま表示されてリンクにならないのだ? なんでだ?
話は変わるが、正規表現であるパターンにマッチする文字列が複数あり、それをすべて取り出したいときにはどうすればいいのだろう? たとえば、今まさにやりたかったのは、httpでgetしたデータの中にあるリンク(a href) を全部取り出して配列に格納する、というようなケースだ。 パッと思いつかず、サラっと探しても見つからなかったので、a hrefの前で改行してファイルに吐き出し、そのファイルを読んで一行ずつ処理するというメンドクサイことをしている。 こんなことしなくてもできるよね・・・。
最初はperlで、LWP::Useragentなどを使って、あるサイトの情報を取り、あとは正規表現などを使って試行錯誤しつつ欲しい情報のみを取り出した。 特に難しいことはない。
ところが、同じ事を2ちゃんねるでやってみたら、うまくいかない。やろうとしたのは、ニュース速報の上位のスレッドタイトルを取得することだった。 2ちゃんねるは掲示板のメニューがあってそこに各掲示板のURLが記載されている。そしてその掲示板のURLはかなり頻繁に変更されるので、そのときアクセスできているURLに固定でアクセスせずに、メニューからURLを取得しなければならない。 その、メニューからURLを取得することはできたのだが、そこから取得したURLへアクセスすると、どうしてもHTMLの内容が取得できないのだ。
まずは、「302 Found」というエラーになる。これはリダイレクトされたときに出るもののようで、あるところで
push @{ $ua->requests_redirectable }, 'POST';
をやればいいという情報を見つけたのでやってみたら、今度は「ボボンハウス」のページが表示されてしまう。同じperlスクリプトをローカルPCで動かしても同じ状況になる。 もちろん、ブラウザやギコナビなどでは問題なくアクセスできている。 昨日はここまでやって、あきらめて寝た。
そして今日、perlのスクリプトでアクセスしたときと、ブラウザでアクセスしたときのパケットをwiresharkでキャプチャして比較してみた。
すると、GETしているときに、・・・・ と、ここまで書いてuseragentが違うことに気づいた。 perlで書いたものは何も設定しておらず、lwpの初期値が入っている。 これを'Mozilla'に変えたら・・・いけた。
昨日、変えてダメだったような記憶があったんだけどな・・・ ま、いいや。 これだけでいけるようになるということは、2ちゃんねるの「スクリプトキディ」除けかな。
今日はWEBでphpをつかったスクレイピング例を見つけてそれがうまく動いたのでそれをいじっていた。
しかし今度はphpの動作で不可解なところがでてきた。 まず、phpをcgiとして動かすために必要な設定がなんなのか。 いろいろと情報があるのだが、皆条件付でスパっと「ここをこうする!」という情報がない。
これも試行錯誤で試して、なんとかうごいた。 前回はこんなに苦労した記憶はないのに・・・。 さらに、いちおう動いたのだが、出力する内容が全部そのまま出てしまう。 htmlのリンクとかを書いても、そのまま表示されてリンクにならないのだ? なんでだ?
話は変わるが、正規表現であるパターンにマッチする文字列が複数あり、それをすべて取り出したいときにはどうすればいいのだろう? たとえば、今まさにやりたかったのは、httpでgetしたデータの中にあるリンク(a href) を全部取り出して配列に格納する、というようなケースだ。 パッと思いつかず、サラっと探しても見つからなかったので、a hrefの前で改行してファイルに吐き出し、そのファイルを読んで一行ずつ処理するというメンドクサイことをしている。 こんなことしなくてもできるよね・・・。