Requests + BeautifulSoup で html から form データの雛形作成他
Requests と BeautifulSoup は忘れた頃に使って何度も調べるのでメモ。小ネタ。
Requests を使ってログイン処理をするときはだいたいこんな処理をかく。
s = requets.Session() r = s.get('http://example.com/login') soup = BeautifulSoup(r.content, 'html.parser') payload = { 'id': 'id', 'password': 'password' } s.post('http://example.com/login', data=payload)
payload の部分がこれくらいシンプルならいいけど、csrf token とかをつけて送る場合に BeautifulSoup を使って token 部分を抜き出す必要がある。そんなときはだいたい以下のようなコードを書いて payload の雛形を作る
内包表記ver
payload = { input['name']: input['value'] if input.has_attr('value') else '' for input in soup.select('form input') if input.has_attr('name') }
for でシンプルに書くとこんな感じ
payload = {} for input in soup.select('form input'): if not input.has_attr('name'): continue value = input['value'] if input.has_attr('value') else '' payload[input['name']] = value
あとはこの payload に適当に id/pass を詰め込んで post すればよい。
その他メモ
- BeautifulSoup はdict の ように in を使って要素があるか問い合わせてはダメ('value' in input みたいな)。has_attr を使う。
- Cookie とか使うなら Session を使う。
- Session の save / load は pickle でいけそう
import requests, requests.utils, pickle session = requests.session() with open('somefile', 'w') as f: pickle.dump(session, f) with open('somefile') as f: session = pickle.load(f)
- findAll ? find_all ? どっちやねん > find_all らしい (最近のpythonのスタイルに従う)