質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1003閲覧

pythonのライブラリを使ったwebスクレイピングでリスト作成について

kakugen

総合スコア3

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/09/01 15:26

編集2020/09/01 15:40

前提・実現したいこと

pythonのライブラリを使って、webスクレイピングで、司法書士の会員名簿を作ろうとしており、リストをcsvに落とすことまではできましたが、それを上手く整形することに躓いています。

発生している問題・エラーメッセージ

実際にリストを作成することはできたのですが、下記のことを解決したいです。

①列の幅の調整や、改行文字の分割。具体的には、氏名欄の氏名とフリガナの分割、事務所所在地欄の住所と電話番号の分割。
②数ページにまたがっているものをforループを回して、全頁取得する方法。私が書いた方法だと、1ページづつ取る必要があります。
③1行目の空白行の削除。

書いたコードは、下記のコードをご確認ください。

該当のソースコード

import csv import requests import urllib.request from bs4 import BeautifulSoup import pandas as pd urls = ["http://kensaku.shiho-shoshi.or.jp/search/member.php?search_code=01&search_name=&search_address=&x=140&y=16&pageID=1"] for url in urls: html = urllib.request.urlopen(url) bsObj = BeautifulSoup(html, "html.parser") table = bsObj.findAll("table", {"id":"kojin"})[0] tables = table.findAll("tr") print(tables) with open("札幌司法書士会リスト.csv", "a", encoding='utf-8_sig',newline='') as file: writer = csv.writer(file) for row in tables: csvRow = [] for cell in row.findAll(['td', 'th']): csvRow.append(cell.get_text()) writer.writerow(csvRow) df = pd.DataFrame() pd.read_csv("札幌司法書士会リスト.csv")

補足情報

非エンジニアですが、独学でpythonを学んでいます。まったくの初心者のため、質問の内容も的を射てないところもありますが、
何卒ご指導のほどよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2020/09/01 15:28 編集

インデントが崩れてしまうため、コードは質問編集画面の「コードの挿入」ボタンを押して出てくるコードと書かれている中に入れてください。 ```ここに言語を入力 コード ```
kakugen

2020/09/01 15:41

ありがとうございました。 修正しました。
guest

回答1

0

ベストアンサー

テーブルデータのスクレイピングであれば、pandas.read_html() を使ったほうが圧倒的に楽です。read_html() はページ内のテーブルを DataFrame として返す関数です。
そうすれば、住所と電話番号を分けるなどの後処理は pandas の機能でできます。

①列の幅の調整や、改行文字の分割。具体的には、氏名欄の氏名とフリガナの分割、事務所所在地欄の住所と電話番号の分割。

それらを区切る文字列に注目して、Series.str.split() で分割する。

②数ページにまたがっているものをforループを回して、全頁取得する方法。私が書いた方法だと、1ページづつ取る必要があります。

サイトを観察すると、ページが変わると URL の pageID=<ページ> が変化することに気づくので、そこを for で変化させながら、1ページずつ取得する。

③1行目の空白行の削除。

DataFrame の1行目を df = df.iloc[1:] で除く

サンプルコード

python

1import pandas as pd 2import time 3 4url_tmpl = r"http://kensaku.shiho-shoshi.or.jp/search/member.php?search_code=01&search_name=&search_address=&x=140&y=16&pageID={}" 5max_pages = 3 # 適宜変更してください 6 7dfs = [] 8for page_no in range(1, max_pages + 1): 9 url = url_tmpl.format(page_no) 10 print(f"fetching... {url}") 11 # ページを取得する。 12 (df,) = pd.read_html(url) 13 # 1行目の空白行無視 14 df = df.iloc[1:] 15 # スリープ 16 time.sleep(1) 17 18 dfs.append(df) 19 20df = pd.concat(dfs) 21 22# "名前 フリガナ" となっているため、" " で分割して、列を分ける。 23df[["氏名", "フリガナ"]] = df["氏名"].str.split(" ", expand=True) 24# "事務所所在地 TEL : 電話番号" となっているため、" TEL : " で分割して、列を分ける。 25df[["事務所所在地", "電話番号"]] = df["事務所所在地"].str.split(" TEL : ", expand=True) 26 27df.to_csv("output.csv")

投稿2020/09/01 15:57

編集2020/09/01 15:58
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakugen

2020/09/02 03:44

ありがとうございました。
kakugen

2020/09/02 03:45

ただ、データは取得できたのですが、文字化けがおきました。どこの部分を修正すれば、よろしいでしょうか?お手数かけますが、よろしくお願いいたします。
kakugen

2020/09/02 03:56

すいません、最後のコードに引数に文字コードを入れたら、解決できました。早く見ていただいて、助かりました。今後ともよろしくお願いいたします。
tiitoi

2020/09/02 05:18

解決済みであれば、お手数ですが質問はクローズしていただけますか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問