3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pythonでwebサイトをスクレイピングするときのtips

Last updated at Posted at 2020-05-02

はじめに

スクレイピングすることがあったので、そのときに得た小技の整理です。

使った環境

補足1

windowsでもpythonのインストールはかなりかんたんです。
pythonの公式サイトから、インストーラーをダウンロードして、実行するだけです。

Pycharmをつかえば、venvでの実行環境をつくるのもかんたんです。
pycharmからのterminalで、つくったpythonスクリプトの実行もできます。とくにこだわりがなく、さくっと実行環境をつくりたいならPycharmはおすすめです。(特に、Java系でIntelliJ IDEAをつかっている人に)

補足2

ライブラリのインストール

pip install requests
pip install beautifulsoup4

import文

import requests
from bs4 import BeautifulSoup
import math
import re
import csv

リクエストの作り方

パスパラメタ

これはpythonの文字列に変数を展開するのを使います

url1 = "https://sample.com/{path1}/{path2}".format(path1='testA', path2='testB')

クエリパラメタ

requestsの機能を使います。

res = requests.get('https://sample.com/test', params={'a': 'testA', 'b': 'testB'})

0埋めして、連番形式のパラメタを生成

01,02, ... 10 のような、数字の連番で2桁の文字列になっている、というようなパラメタのことがあります。このようなパラメタでfor文回すためのリストを、rangezfillで生成できます。

[str(i).zfill(2) for i in range(1, 11) ]

00, ... 09のように連番が0はじまりのときは

[str(i).zfill(2) for i in range(10) ]

なにがしかのprefixがつく場合は

[ 'XX' + str(i).zfill(2) for i in range(10) ]

とすると、XX00, ... XX09 となります。

レスポンスの取扱

beautifulsoupはbyte配列からも読み込めるので、requestsのレスポンスオブジェクトのcontentを使います。このやり方が文字化けが起きにくいようです。

res = requests.get(url)
soup = BeautifulSoup(res.content, "html.parser")

クラス名での検索

find_allかfindに、class_パラメタにセットしてやります。
タグを指定したい場合は、最初にそのタグを渡します

soup.find_all('a', class_='list-rst__rst-name-target')

固定のテキストでの検索

textパラメタに正規表現を渡します。

soup.find('th', text=re.compile('テスト'))

改行コード・空白文字の除去

strip()を使えば、だいたいうまくいきます

soup.find_all('a', class_='list-rst__rst-name-target').text.strip()

要素の存在チェック

if式を使えば、そこそこ楽にかけます。

tag = soup.find(id='test')
text = tag.text.strip() if tag else ''

ページング

最終ページの求め方

検索結果の最初のページなどで、全件の数がわかっているものとします。
1ページあたりの件数もわかっているものとします。

全件/1ページあたりの件数を、少数点切り上げするだけです。
割った結果が少数になるように、全件か、1ページあたりの件数のどちらかをfloatにします。

total_count = float(soup.find('p', id='total_count').string)
max_page = math.ceil(total_count / page_size)

ページングのためのfor文

1始まりなら、こうなります。

for page_number in range(1, max_page + 1):
    print(page_number)

0はじまりなら、下記のようになります。

for page_number in range(max_page):
    print(page_number)

ファイルへの書き込み

項目が決まっている場合は、csv.DictWriterが便利です。

csv、文字コードをUTF-8、囲み文字をダブルクォート、囲み文字をすべてつける場合は下記になります。delimiterを指定すれば、tsvにもできます。

with open('test.csv', 'a', newline='', encoding='utf8') as f:
     writer = csv.DictWriter(
            f,
            fieldnames=['id', 'name'],
            quotechar='"',
            quoting=csv.QUOTE_ALL
     )
     id = ...
     name = ... 
     rowdict = {'id': id, 'name': name}
     writer.writerow(rowdict) 

参考リンク

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?