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

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

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

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

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Beautiful Soup

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

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Python

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

Q&A

1回答

760閲覧

pythonでwebサイトからのスクレイピングについて

kakugen

総合スコア3

スクレイピング

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

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Beautiful Soup

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

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Python

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

0グッド

0クリップ

投稿2023/05/10 05:32

実現したいこと

pythonで下記サイトからスクレイピングし、csvデータを作成したい。
http://kensaku.shiho-shoshi.or.jp/search/member.php?search_code=29&search_name=&search_address=&x=122&y=11&pageID=1

前提

pythonで日本司法書士連合会のホームページからデータを取得し、csvデータを作成したいと思っております。
ほぼ大方完成しておりますが、解決すべき問題が2点あります。

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

エラーメッセージはありませんが、下記の点を解決したいと思っております。 ①ホームページを見ていると、ところどころ外字が画像になっております。画像のところを〓にして表記しているのですが、現在のプログラムでは、画像があった場合の対応は、名前のところに付けるようにしています。それを、住所のところに画像があった場合、住所欄に〓を付けるようにしたいです。 ②法人名/事務所名も新たに項目を付けたいのですが、コードをどのようにつければよいでしょうか? 下記のコードに、上記の2点を改良したいと思っております。

該当のソースコード

import re import time from urllib.parse import urljoin from bs4 import BeautifulSoup import requests # 追記 import csv #予め正規表現でそれぞれのパターンを準備しておく 郵便番号パターン = r'〒\d{3}-\d{4}' 電話番号パターン = r'TEL : \d{2,4}?-\d{2,4}?-\d{3,4}' # 今回のケースの場合56行目で相対パスとして取得される為、予めここでもウェブサイトURL部分と分割しておく url = 'http://kensaku.shiho-shoshi.or.jp' href = 'search/member.php?search_code=29&search_name=&search_address=&x=125&y=18&pageID=1' # 追記 output = [['郵便番号', '住所', '電話番号', '氏名', 'ふりがな']] while True: html = requests.get(urljoin(url, href)) # urljoinでURLの結合 soup = BeautifulSoup(html.content, 'html.parser') # table要素を指定 table = soup.find('table', id='kojin') # table内から全てのtr要素を取得 tr_list = soup.find_all('tr') for tr in tr_list: # table要素内にtacクラスの要素がある場合に実行(要は1番目のtr要素の除外) if tr.find_all(class_='tac'): # 大まかにtr要素内の全ての文字列を取得・分割しておく td_list = [td.text for td in tr.find_all('td')] # 氏名を漢字表記とルビ表記で分割 # 氏名欄にimg要素が含まれていた場合には名前の先頭に目印として○をつける if tr.find('img'): names = td_list[1].split('\n') names[0] = '〓' + names[0] else: names = td_list[1].split('\n') # 正規表現のパターンが一致した場合に郵便番号の取得 zipcode = re.search(郵便番号パターン, td_list[4]).group() # 正規表現のパターンが一致した場合に電話番号の取得 # (電話番号を載せていないケースもある為try文を使用する) try: telephone = re.search(電話番号パターン, td_list[4]).group() locate = td_list[4].replace('\t', '').replace( '\n', '').replace(zipcode, '').replace(telephone, '') # 電話番号を掲載していなかった場合の処理 except: telephone = 'NO TEL' locate = td_list[4].replace('\t', '').replace( '\n', '').replace(zipcode, '') # 追記 output.append([zipcode,locate,telephone,names[0],names[1]]) # ページ内に[次のページ]を表す[>]が存在するかを判定 # 存在した場合Trueが返ってくる為、if文が実行される(hrefの値が更新され次のページにループする) if soup.find(class_='pagebottom').find_all('a', attrs={'title': 'next page'}): # 取得したhrefは相対パスである為、16行目でウェブサイトURLと結合される href = soup.find(class_='pagebottom').find( 'a', attrs={'title': 'next page'}).get('href') # 次のページが存在しなかった場合にはループが終了 else: break # 短時間に連続してリクエストを送る行為はマナー違反且つサーバーへの負荷となる為 # 標準ライブラリよりtimeモジュールを使用して1秒間隔でリクエストを送る様に調整 time.sleep(1) # 追記 with open('./京都.csv', 'w') as file: writer = csv.writer(file, lineterminator='\n') writer.writerows(output)

試したこと

①について、td_list[4]で分割したlocateに〓をつけようとしたのですが、その方法が良く分かりませんでした。
②について、法人名/事務所名は、td_list[5]ではないかと思って、色々と試しましたが、うまくいきませんでした。

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

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

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

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

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

m.ts10806

2023/05/10 06:20

スクレイピングの許可は取られてるのでしょうか
guest

回答1

0

まず、各列の値をすぐに文字列にするのではなく要素として処理するようにします。
そのうえでreplace_withでimgタグを指定の文字に置換することができます。
また、フリガナを抽出することもできます。

Python

1from bs4 import BeautifulSoup 2 3html = """ 4<table id="kojin"> 5<tr> 6<td class="tac">1</td> 7<td class="nowrap">豊<img src="hoge.png">秀<img src="huga.png"><br> 8<small>トヨトミ ヒデヨシ</small></td> 9<td class="nowrap">大<img src="hoge.png">司法書士会</td> 10<td class="tac">○</td> 11<td class="font_m10">〒540-0002<br> 12大阪府大阪市中央区大阪城1−1<br> 13TEL : 06-6941-3044</td> 14<td>豊<img src="hoge.png">政権</td> 15</tr> 16</table>""" 17 18soup = BeautifulSoup(html, 'html.parser') 19table = soup.find('table', id='kojin') 20tr_list = soup.find_all('tr') 21for tr in tr_list: 22 if not tr.find_all(class_='tac'): 23 continue 24 25 line = [] 26 # 各列毎に処理 27 tds = tr.find_all('td') 28 for idx, td in enumerate(tds): 29 # 画像は?に置換 30 imgs = td.find_all('img') 31 for img in imgs: 32 img.replace_with('?') 33 34 if idx == 1: # 名前の列 35 # フリガナ 36 hu = td.find('small') 37 if hu: 38 line.append(hu.text) 39 hu.extract() # 取得したのでフリガナの要素を削除 40 41 line.append(td.text) # 名前のフリガナは除去済み 42 43 print(line) 44# ['1', 'トヨトミ ヒデヨシ', '豊?秀?\n', '大?司法書士会', '○', '〒540-0002\n大阪府大阪市中央区大阪城1−1\nTEL : 06-6941-3044', '豊?政権']

投稿2023/05/10 06:43

can110

総合スコア38266

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問