#はじめに
pythonでweb scrapingをやってみたく色々調べているのですが、内容をメモとしてまとめておこうと思います。
##利用するライブラリ
BeautifulSoupとRequestsを利用する
##pythonの実行結果をatom上で確認する方法
「script」というパッケージを使用
コード実行のショートカットはCtrl+Shift+B
(windowsの場合)
BeautifulSoupに関するメモ
-
parserには色々と種類があるらしい
- 参考記事:beautifulsoup4入門 htmlをパース、スクレイピングする
- 違いは正直あまり良く分からない(一応速度に違いがあるらしい)
- 大体のサンプルコードで
html.parser
を利用しているからそれでいいんじゃないかな笑
-
文字列の取得はget_text()
- 参考記事:10分で理解する Beautiful Soup
- 改行/空白をトリミングしたり、要素名を指定した取得なども出来る
- 要素を指定することで、特定の文字列を取得することも出来る
- 例えば、
.i.get_text()
と指定すれば、<i>
要素で囲まれた部分のみ取得する - 参考:公式レファレンス
- 例えば、
-
get('href')
でhref属性を取得することが出来る
##requestsに関するメモ
参考記事:Requests の使い方 (Python Library)
- httpリクエストのメソッドに対応した関数がある
- レスポンス内容をテキスト形式で取得する(
.text
)とバイナリー形式で取得する(.content
)のパターンがある
##UnicodeEncodeErrorについて
以下のサンプルコードをwindows環境で実行しようとするとエラーが出た
from bs4 import BeautifulSoup
import requests as req
url = 'https://www.y-shinno.com/vgg16-finetuning-uecfood100/'
html = req.get(url).content
soup = BeautifulSoup(html, 'html.parser')
text = soup.find(class_='entry-content').get_text()
print(text)
返ってきたエラー
UnicodeEncodeError: 'cp932' codec can't encode character '\xa0' in position 1710: illegal multibyte sequence
調べてみると、python内部の文字列のエンコード方式とwindowsの標準エンコード方式のバッティングによって発生するらしい。
解決策としては以下の記事に記載のコードをimport時に記載することで解決
(解決までにかなり時間がかかった...)
import io,sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
windowsにおいてpythonで日本語を扱う際はこれを入れておく方がいいかな?(間違ってたら指摘ください笑)
##要素を取得してスクレイピングする方法
find()
or select()
を使えばよい
注意:class属性をディベロッパーツールで調べる時に、ソースコードをそのままコピペするだけでは上手くいかないケースがある
例
<div class="l-mt10 text-ellipsis__body--2lines contents-list__item-name">あいうえお</div>
このclass属性を指定してselectしようとした時に
soup.select(".l-mt10 text-ellipsis__body--2lines contents-list__item-name")
では動かなくて
soup.select(".l-mt10.text-ellipsis__body--2lines.contents-list__item-name")
でないといけない(分かりずらい...)
##selectで取得した配列から文字列だけトリミングする方法
get_text()
とfor~in~
を組み合わせる(for文ってこうやって使うのか!)
例
print([t.get_text() for t in text])
こういう感じで配列の各要素に対してfor文で順次get_text()
していった結果を出力すればよい。
##pythonでJSONを扱う場合
取得した要素をjson配列にしたアウトプットしたい場合、json
モジュールとoperator
モジュールのitemgetter
を利用し、for文を回して順次配列化していけばよい
###jsonモジュールについて
参考記事:
関数の区別がややこしい...
- json.load(): 処理の結果としてファイルのJSONを辞書型に変換して返却する
- json.loads(): プログラム上に文字列として取得済みのjsonを辞書型に変換して読み込む
- json.dump(): 辞書型の値をJSONに変換してファイルに出力する
- json.dumps(): 辞書型の値を文字列型に変換して出力する
###operatorモジュールのitemgetterについて
軽く見ただけなので、参考資料のみ記載
###pythonにおける配列の扱い方
軽く見ただけなので、参考資料のみ記載