このブログではPythonを使ったスクレイピングを、初心者向けにサンプルコード付きで解説しています。以下に紹介する記事では、①から⑨のステップでスクレイピングの方法を学び、実践に役立てられるよう体系的にまとめています。
【①〜⑨まとめ】PythonでWebスクレイピングを実践する方法【サンプルコード付き】
このブログではPythonスクレイピングを初心者向けに解説していきます。順番に各記事で解説しており入門者向けです。サンプルコード付きで解説するので実践的…
この記事ではPythonでスクレイピングしたデータを整形する方法について解説しています。
スクレイピングしたデータはそのままでは利用しにくい場合があります。特定の文字列を削除・追加したり、辞書形式などにすることでデータを扱いやすくする方法を説明していきます。
目次
特定の文字列を置換、削除する方法
以下で取得している.post-title要素は、「これは1の記事です」、「これは2の記事です」のようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import requests from bs4 import BeautifulSoup # 1. ウェブページをリクエストして、指定されたURLからデータを取得 url = 'https://scraping-training.vercel.app/site?postCount=20&title=%E3%81%93%E3%82%8C%E3%81%AF{no}%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%A7%E3%81%99&dateFormat=YYYY-MM-DD&isTime=true&timeFormat=&isImage=true&interval=360&isAgo=true&countPerPage=0&page=1&robots=true&' # 変数urlに対象のURLを代入 webpage_response = requests.get(url) # 2. コンテンツ属性を使用して、ウェブページのコンテンツを取得 webpage_content = webpage_response.content # 3. BeautifulSoupを使用して、取得したウェブページのコンテンツを解析可能な形式に変換 webpage_soup = BeautifulSoup(webpage_content, "html.parser") post_titles = webpage_soup.select('.post-title') for post_title in post_titles: title_text = post_title.text.replace('これは', '') print(title_text) # 結果 # 1の記事です # 2の記事です # 3の記事です |
.replaceを使うことで特定の文字列を置換、また削除することができます。ここでは.replace(‘これは’, ‘’)によって、「これは」部分を削除しています。
.replace(‘これは’, ‘あれは’)のようにすることで文字を置換することもできます。
また.replace(‘これは’, ”).replace(‘です’, ‘’)のように複数の文字列を置換、削除することも可能です。
ファイル名を安全な文字列に置換する
このコードは、ファイル名に適さない文字列を一括で削除したい場合などに利用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# ファイル名修正 def sanitize_filename(filename): # ファイル名に適さない文字列を削除する invalid_chars = ['/', '\\', '|', ':', '*', '"', '<', '>', '.', '\', '/', ':', '*', '<', '>', '|', '「', '」'] for char in invalid_chars: filename = filename.replace(char, '_') filename = filename.replace('?', '?') filename = filename.replace('【', '') filename = filename.replace('】', '') # ファイル名が60文字を超える場合、最初の60文字にカットする if len(filename) > 60: filename = filename[:60] return filename |
先程と同じく.replaceを使った文字列の置換です。ただし関数化しており複数の文字列を一度に処理することができます。
詳しくは以下の記事で解説しています。
⑦ Pythonでファイル名に適さない文字を一括削除・置換する方法を解説【サンプルコード】
このブログではPythonを使ったスクレイピングを、初心者向けにサンプルコード付きで解説しています。以下に紹介する記事では、①から⑨のステップでスクレイピ…
文字を追加する方法
今度は逆に文字を追加する方法を見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import requests from bs4 import BeautifulSoup # 1. ウェブページをリクエストして、指定されたURLからデータを取得 url = 'https://scraping-training.vercel.app/site?postCount=20&title=%E3%81%93%E3%82%8C%E3%81%AF{no}%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%A7%E3%81%99&dateFormat=YYYY-MM-DD&isTime=true&timeFormat=&isImage=true&interval=360&isAgo=true&countPerPage=0&page=1&robots=true&' # 変数urlに対象のURLを代入 webpage_response = requests.get(url) # 2. コンテンツ属性を使用して、ウェブページのコンテンツを取得 webpage_content = webpage_response.content # 3. BeautifulSoupを使用して、取得したウェブページのコンテンツを解析可能な形式に変換 webpage_soup = BeautifulSoup(webpage_content, "html.parser") post_titles = webpage_soup.select('.post-title') for post_title in post_titles: title_text = post_title.text.replace('これは', '').replace('です', '') title_text = f'見出し:{title_text}' print(title_text) # 結果 # 見出し:1の記事 # 見出し:2の記事 # 見出し:3の記事 |
title_text = f’見出し:{title_text}’のようにf-stringを使って文字列に「見出し:」箇所を追加しています。プリント時にも同じことはできますが、変数として保存したい場合にはこのようにします。
取得したテキストを翻訳する
外国語のデータを取得した場合、後から手作業で翻訳するのは面倒です。翻訳APIを使って簡単に処理してしまいます。
1 2 3 4 5 6 7 8 9 10 |
from googletrans import Translator # 翻訳時に出力するデフォルト言語 en,ja,esなど output_lang = "ja" # 翻訳API def translate_text(text, dest_language = output_lang): translator = Translator() # Translator クラスのインスタンスを作成 translated_text = translator.translate(text, dest=dest_language) # テキストを指定された言語に翻訳 return translated_text.text # 翻訳されたテキストを返す |
上記の関数を使うことで簡単に翻訳することができます。
ただし上記は非公式のライブラリなのでGoogle Cloud Translation APIなどを利用したほうがいいと思います。
詳しくは以下の記事を参照ください。
⑤Pythonでスクレイピングしたテキストを翻訳する方法
このブログではPythonを使ったスクレイピングを、初心者向けにサンプルコード付きで解説しています。以下に紹介する記事では、①から⑨のステップでスクレイピ…
URLが相対パスの場合、絶対パス(フルURL)に変換
Pythonのurljoinを使って相対パスを絶対パスに変換することができます。
1 2 3 4 5 6 7 8 9 |
from urllib.parse import urljoin base_url = 'https://example.com' relative_url = '/path/to/resource' # 相対パスをフルURLに変換 full_url = urljoin(base_url, relative_url) print(full_url) # https://example.com/path/to/resource |
urljoinは、相対パスを基準URL(base_url)に基づいて絶対パスに変換します。
例えばimg src要素を取得してダウンロードする時、取得したデータが相対パスであれば上記のように処理をします。
取得したデータを辞書形式で保存する方法、取り出す方法
複数の要素をループして取得する場合、そのデータを辞書形式で保存すると便利です。
例えば記事一覧データを取得するとします。ページには複数の記事があり、各記事からタイトル、画像urlをまとめて取得していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import requests from bs4 import BeautifulSoup from urllib.parse import urljoin #指定ページから各リンクを見つける def find_links(): url = 'https://scraping-training.vercel.app/site?postCount=20&title=%E3%81%93%E3%82%8C%E3%81%AF{no}%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%A7%E3%81%99&dateFormat=YYYY-MM-DD&isTime=true&timeFormat=&isImage=true&interval=360&isAgo=true&countPerPage=0&page=1&robots=true&' webpage_response = requests.get(url) webpage_content = webpage_response.content webpage_soup = BeautifulSoup(webpage_content, "html.parser") base_url = 'https://scraping-training.vercel.app' links = [] count = 0 a_tags = webpage_soup.select(".post-link") if a_tags: for a_tag in a_tags: href = a_tag.get('href') href = urljoin(base_url, href) title_div = a_tag.select_one(".post-title").text.strip() # 辞書に格納 data_dict = {"id": count, "記事タイトル": title_div, "url": href} links.append(data_dict) count += 1 return links |
ここではlinksリストを作成し、またリストにIDを付けるためのカウンター(count)も使います。
<a> タグ要素には記事タイトルとhrefがあるので取得します。それらを辞書形式にまとめます。
辞書にはカウンターを使ってidを付与し、対応する記事タイトルとURLを格納していきます。
1 2 3 |
print(find_links()) # 結果 [{'id': 0, '記事タイトル': 'これは1の記事です', 'url': 'https://scraping-training.vercel.app/site/details/1'}, {'id': 1, '記事タイトル': 'これは2の記事です', 'url': 'https://scraping-training.vercel.app/site/details/2'}] |
上記のように、idと共に対応する記事タイトルとurlが辞書形式で格納されています。
辞書形式にすることでこの後データを利用する際や、書き出しする際に便利に使うことができます。
1 2 3 4 5 6 7 8 |
# 関数を実行し、戻り値を受け取る links = find_links() # urlだけを抽出 url_list = [link['url'] for link in links] print(url_list) # 結果 ['https://scraping-training.vercel.app/site/details/1', 'https://scraping-training.vercel.app/site/details/2'] |
このように、辞書に格納したデータを取り出して使うことができます。
1 2 3 4 5 |
# 2番目のリンクの URL を取り出す(インデックスは1) third_url = links[1]["url"] print(third_url) # 結果 https://scraping-training.vercel.app/site/details/2 |
このようにインデックスを指定して、特定の要素だけを取得できます。
1 2 3 4 5 6 7 8 |
target_url = None # 初期値としてNoneを設定 for link in links: if link["記事タイトル"] == "これは2の記事です": # 記事タイトルが一致するか確認 target_url = link["url"] # 一致する場合はURLを取得 break # 一致したらループを終了 print(target_url) # 結果 https://scraping-training.vercel.app/site/details/2 |
また、特定の文字列に一致するデータを取り出すこともできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def fetch_item_datas(): h1_texts = [] for url in url_list: webpage_response = requests.get(url) webpage_content = webpage_response.content webpage_soup = BeautifulSoup(webpage_content, "html.parser") # アイテム内容を取得し、テキストをリストに追加 h1_tags = webpage_soup.select('h1') for h1 in h1_tags: h1_texts.append(h1.text.strip()) return h1_texts print(fetch_item_datas()) # 結果 ['1番目の記事', '2番目の記事'] |
辞書形式で保存したURL(url_list)を利用して、各URLの遷移先の情報をまとめて取得することも可能です。
辞書形式のリストをMySQLデータベースにインポートする方法は以下の記事で解説しています。
PythonスクレイピングしたデータをMySQLデータベースにインポートする方法を解説
この記事ではPythonでスクレイピングしたデータをMySQLデータベースにインポートする方法を解説しています。 Pythonウェブスクレイピングの基本についてはこ…
まとめ
Pythonでスクレイピングしたデータを整形する方法について解説しました。.replaceは簡単にデータの置換、削除ができて便利です。
必要に応じて関数を作り一括処理できるようにすると簡潔なコードが完成します。
整形が完了したデータの書き出し方法については以下の記事で解説しています。
⑨PythonでスクレイピングしたデータをCSVファイルに書き出す方法を解説
このブログではPythonを使ったスクレイピングを、初心者向けにサンプルコード付きで解説しています。以下に紹介する記事では、①から⑨のステップでスクレイピ…