スクレイピング
元々はVBA+IEでスクレイピングをしてデータを収集してデータベースを作った。でもそれを毎回やるのはめんどいので自動化できると良い。サーバー上でスクレイピングするやり方って何があるんだろうと探してみたらPythonのライブラリでBeautifulSoupというものを見つけた。これで定期的に更新されてるか見に行きつつスクレイピングして必要なデータを抽出して、なおかつデータベースを更新できればいいな。とりあえずスクレイピングしよー。
Beautiful Soupでスクレイピング
公式ドキュメント。今は4.9.0が最新?
こっちは日本語訳。これは4.2.0が基みたい。まぁやってこー。
インストール
CentOSなので
$ pip install beautifulsoup4
Collecting beautifulsoup4
Downloading beautifulsoup4-4.9.1-py3-none-any.whl (115 kB)
|????????????????????????????????| 115 kB 17.9 MB/s
Collecting soupsieve>1.2
Downloading soupsieve-2.0.1-py3-none-any.whl (32 kB)
Installing collected packages: soupsieve, beautifulsoup4
Successfully installed beautifulsoup4-4.9.1 soupsieve-2.0.1
された。
HTMLパーサーのインストール
HTMLを解析してくれるやつ。Pythonで標準に入ってるらしいやつとなんか色々。そのうちlxmlのHTMLパーサーを使おうと思う。速いらしいよ。
$ pip install lxml
Collecting lxml
Downloading lxml-4.5.2-cp38-cp38-manylinux1_x86_64.whl (5.4 MB)
|????????????????????????????????| 5.4 MB 10.6 MB/s
Installing collected packages: lxml
Successfully installed lxml-4.5.2
Requestsのインストール
HTMLをそのまま取得する時に使うやつみたい。Pythonの標準にもUrllibというライブラリが入ってるらしいけど、こっちのほうが使いやすいらしい。らしいばっかだ。ただ自分の目的だと外部公開されてる固定ページに行って取得するだけだし別にそこまでするようなものでもないかもしんない。まぁ一応入れとく!
$ pip install requests
Collecting requests
Downloading requests-2.24.0-py2.py3-none-any.whl (61 kB)
|????????????????????????????????| 61 kB 727 kB/s
Collecting chardet<4,>=3.0.2
Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
|????????????????????????????????| 133 kB 22.3 MB/s
Collecting certifi>=2017.4.17
Downloading certifi-2020.6.20-py2.py3-none-any.whl (156 kB)
|????????????????????????????????| 156 kB 30.5 MB/s
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
Downloading urllib3-1.25.10-py2.py3-none-any.whl (127 kB)
|????????????????????????????????| 127 kB 17.0 MB/s
Collecting idna<3,>=2.5
Downloading idna-2.10-py2.py3-none-any.whl (58 kB)
|????????????????????????????????| 58 kB 6.0 MB/s
Installing collected packages: chardet, certifi, urllib3, idna, requests
Successfully installed certifi-2020.6.20 chardet-3.0.4 idna-2.10 requests-2.24.0 urllib3-1.25.10
できた。
使ってみる
まずちゃんと取得できるか試す。コード書いた。
import requests
from bs4 import BeautifulSoup
url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(url)
soup = BeautifulSoup(res.text, 'lxml')
print(soup.title)
結果
python3 scrape.py
<title>a??a??a?≪a?!ec°a°?a£?i??ec°a°?a£?a?≫a¬!a?Ra,a??i??a?\a?¬a°?a£?e£c??</title>
おっとー、また文字化けかい…。んーと
print('こんにちわ')
で
$ python3 hello.py
こんにちわ
表示される。
import requests
url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(url)
print(res.text)
こうして、結果
<title>a??a??a?≪a?!ec°a°?a£?i??ec°a°?a£?a?≫a¬!a?Ra,a??i??a?\a?¬a°?a£?e£c??</title>
あーこの時点でもう化けてる。”Requests 文字化け”とかで検索
https://qiita.com/nittyan/items/d3f49a7699296a58605b
とか。自分でも試してみる。
print(res.encoding)
に変えて
$ python3 scrape.py
ISO-8859-1
おー。qiitaだとapparent_encodingを使ってるけどすでにサイト側の文字コードがutf-8だと分かってるので
import requests
from bs4 import BeautifulSoup
url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(url)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text, 'lxml')
print(soup.title)
簡易に文字コードを強制的に指定してあげる。結果
$ python3 scrape.py
<title>まいにち詰将棋|詰将棋・次の一手|日本将棋連盟</title>
取得できた!そしたら最新出題日のデータを取得してみる。
最新を取得
CSSセレクタで指定するのはいまいちよく分かってないのでfindとfind_all使ってやってく。ソース見ると、id=”contents“の中のli要素1個目で、aとpの要素を取得できれば良さげ。その後p要素のテキストを加工すればデータ作れそう。で、こんな感じになった。
import requests
from bs4 import BeautifulSoup
target_url = 'https://www.shogi.or.jp/tsume_shogi/everyday/'
res = requests.get(target_url)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text, 'lxml')
contents = soup.find(id="contents")
url = contents.find('a').get('href')
print(url)
title = contents.find('p').text
print(title)
q_date = title[0:title.find('日')].replace('年','-').replace('月','-')
print(q_date)
maker = ''
steps = 0
if '、' in title:
maker = title[title.find('(')+1:title.find('、')-1]
steps = title[title.find('、')+1:title.find('手詰')]
else:
steps = title[title.find('(')+1:title.find('手詰')]
print(maker)
print(steps)
結果
$ python3 scrape.py
![]()
2020年9月5日の詰将棋(服部慎一郎作、9手詰)|詰将棋・次の一手|日本将棋連盟日本将棋連盟の2020年9月5日の詰将棋(服部慎一郎作、9手詰)のページです。日本将棋連盟は伝統文化としての将棋の普及発展と技術向上や将棋を通じた交流親善などを目的とした公益社団法人です。
2020年9月5日の詰将棋(服部慎一郎作、9手詰)
2020-9-5
服部慎一郎
9
とりあえず9/5分しかチェックしてないけど大丈夫かな~。BFのfindの引数の書き方がよく分かんなかったので何回もfindした。liはいらんかったね。データの切り出しも正規表現とか使えるともっといい感じに書けるんだろうなぁ…。まだまだですね。まぁ目的のデータはゲットできそうなので、次はこれをDBに更新していく処理を書こう!
コメント