前提・実現したいこと
今私は、
pythonとSeleniumというモジュールを使用して、GoogleMapから自動的にビル情報を抜き出す
プログラムを作成しております。
今私が苦戦しております内容は、
'''
東京都渋谷区恵比寿西1丁目12−14エイビスビルB1
大阪府大阪市北区角田町5−1楽天地ビル
奈良県奈良市東向中町28 奈良近鉄ビル3F
福岡県福岡市中央区天神1丁目12−20
'''
GoogleMapから抜き出した上記のようなビルの住所から、
・都道府県
・市区町村
・町名
・番地
・ビル名
をPythonの正規表現を用いて抜き出すという作業です。Pythonの正規表現の使い方がまだ初心者レベルで、どうしてもわからないのでご協力いただけるとありがたいです。
ちなみに、
・「都道府県」は、「都道府県」の文字まで出力
・「市区町村」は、「奈良市東向中町」のように、「市」で区切らずに「区町村」で区切る
・「町名」は、「天神1丁目」のように、「区町村」の文字の後から「目」の文字まで
・「番地」は、「12−20」と「28」の2パターンがあります。
・正規表現で抽出した文字列は、住所の文から毎回消去してビル名は最後に残るので、「ビル名」の処理は必要ありません。
そして、抜き出したい要素が見つからない場合には、「null」で出力したいのですが、ここに関してはまだ実装内容を細かく考え切れていません。
###プログラム全体のソースコード
### 質問サイト提出用のコード ## GoogleMapスクレイピング from selenium import webdriver import time from bs4 import BeautifulSoup as BS import re # クロームのドライバーを用意 driver = webdriver.Chrome() # クロームドライバーが「GoogleMap」urlを取得・開く url = 'https://www.google.co.jp/maps/' driver.get(url) # time.sleepは、ロード中の処理でエラーが起こらないように、処理を待機させるために使用 time.sleep(3) # 検索欄にキーワードを入力 keys = input('「郵便番号」の後にハイフンを入れて郵便番号を入力>') # データ入力 building_search_id = driver.find_element_by_id("searchboxinput") building_search_id.send_keys(keys) # サーチボックスに、keysにインプットされた要素を代入 time.sleep(3) # クリック search_button = driver.find_element_by_xpath("//*[@id='searchbox-searchbutton']") search_button.click() time.sleep(5) # 「付近を検索」をクリック near_search_button = driver.find_element_by_xpath("//*[@id='pane']/div/div[1]/div/div/div[5]/div[3]/div/button") near_search_button.click() time.sleep(5) # 「付近のビル」と入力 building_search_id = driver.find_element_by_id("searchboxinput") building_search_id.send_keys('付近のビル') time.sleep(3) # 「付近のビル」と入力し終わった後の検索蘭をクリック search_button2 = driver.find_element_by_xpath("//*[@id='searchbox-searchbutton']") search_button2.click() time.sleep(6) ## リンクを順にクリックするループ処理 while True: try: ## リンク数解析 link_list = [] page_source = driver.page_source # htmk解析 soup = BS(page_source, 'html.parser') link_text = soup.find(class_ = 'n7lv7yjyC35__left') # スクレイピング link_list.append(link_text.text.strip()) # スクレイピングした文字を一個一個分解する処理(n_gramを使用) # 下のfor文をdefの中に収納する可能性あり def n_gram(target, n): result = [] for i in range(0, len(target) - n + 1): result.append(target[i : i + n]) return result for i in link_list: target = i result = n_gram(target, 1) # 1文字ごとに分解してリストに収納したリスト if result[0] == '1': link1 = int(result[0]) link2_s = result[2:4] link2 = int("".join(link2_s)) elif result[2] == '〜': link1_s = result[0:2] link1 = int("".join(link1_s)) link2_s = result[3:5] link2 = int("".join(link2_s)) else: pass ## スクレイピングに使用する空のリストをここに設置 title_list = [] # スクレイピング要素がないリンクを飛ばすためのリスト address_list = [] # 検索結果のxpathというものでループを回しています path_front = '//*[@id="pane"]/div/div[1]/div/div/div[4]/div[1]/div[' count = 1 path_end = ']' roop_counter = 1 # ループを強制終了させるためのカウンター while roop_counter <= link2 - link1 + 1: # リンクを順にクリックさせています path = path_front + str(count) + path_end l = driver.find_element_by_xpath(path) l.click() time.sleep(5) if count == 1 or 3: # HTML解析 page_source = driver.page_source soup = BS(page_source, 'html.parser') # 例外ページをスキップ title = soup.find(class_ = 'GLOBAL__gm2-headline-5 section-hero-header-title-title') title_list.append(title.text.strip()) title_list_del = title_list.pop() # 内部の例外処理 if '-' not in title_list_del: pass else: count += 2 roop_counter += 1 back_button = driver.find_element_by_xpath('//*[@id="pane"]/div/div[1]/div/div/button/span') back_button.click() # 検索一覧に戻ります time.sleep(4) continue # スクレイピングの準備 address = soup.find_all(class_ = 'section-info-text') # 郵便番号をスクレイピングする処理 target = address[0].text.strip() address_result_old = n_gram(target, 1) # 分解した後のリスト address_result = [i for i in address_result_old if i != ' '] postal_code_list = address_result[0:9] postal_code = "".join(postal_code_list) # 郵便番号が完成 ## 正規表現を使用した住所解析 scraping_list = address_result[9:] # 一文字ずつ分けた、正規表現用のリスト scraping_str = "".join(scraping_list) # 正規表現用のリストを文字列に ###############ここから質問箇所です###################### # 「県」の抽出 Ken_match = re.match('', scraping_str) # matchの部分は適当に変えてください Ken = Ken_match.group() scraping_list = [i for i in scraping_list if i == Ken] # 「市区町村」の抽出 City_match = re.match('', scraping_str) # matchの部分は適当に変えてください City = City_match.group() scraping_list = [i for i in scraping_list if i == City] # 「町名」の抽出 Town_match = re.match('', scraping_str) # matchの部分は適当に変えください Town = Town_match.group() scraping_list = [i for i in scraping_list if i == Town] # 「番地」の抽出 num_match = re.match('', scraping_str) # matchの部分は適当に変えてください num = num_match.group() scraping_list = [i for i in scraping_list if i == num] #################ここまでが質問箇所です##################### # 「ビル名」の抽出 ## リストの残りを出力すれば完了 # 出力 print('--------------------------') print(scraping_str) # 正規表現の材料、あとで消す print(title.text.strip()) # タイトルの出力 最後は使わないかも print(postal_code) # 郵便番号の出力 print(Ken) # 「県名」の出力 print(City) # 「市区町村」の出力 print(Town) # 「町名」の出力 print(num) # 「番地」の出力 back_button = driver.find_element_by_xpath('//*[@id="pane"]/div/div[1]/div/div/button/span') back_button.click() # 検索一覧に戻ります count += 2 roop_counter += 1 time.sleep(5) # 次のページへ移動します next_button = driver.find_element_by_xpath('//*[@id="n7lv7yjyC35__section-pagination-button-next"]') next_button.click() time.sleep(7) except: driver.close() # 最後にブラウザを閉じて終了
質問したい部分のソースコード
Python3
1 # スクレイピングの準備 2 address = soup.find_all(class_ = 'section-info-text') 3 4 # 郵便番号をスクレイピングする処理 5 target = address[0].text.strip() 6 address_result_old = n_gram(target, 1) # 分解した後のリスト 7 address_result = [i for i in address_result_old if i != ' '] # 空白消す 8 postal_code_list = address_result[0:9] 9 postal_code = "".join(postal_code_list) # 郵便番号が完成 10 11 ## 正規表現を使用した住所解析 12 scraping_list = address_result[9:] # 一文字ずつ分けた、正規表現用のリスト 13 14 scraping_str = "".join(scraping_list) # 正規表現用のリストを文字列に 15 # 例(渋谷区恵比寿西1丁目12−14エイビスビルB1) 16 17 ###############ここから質問箇所です###################### 18 # 「県」の抽出 19 Ken_match = re.match('', scraping_str) # matchの部分は適当に変えてください 20 Ken = Ken_match.group() 21 scraping_list = [i for i in scraping_list if i == Ken]# マッチを消去 22 23 # 「市区町村」の抽出 24 City_match = re.match('', scraping_str) # matchの部分は適当に変えてください 25 City = City_match.group() 26 scraping_list = [i for i in scraping_list if i == City] 27 28 # 「町名」の抽出 29 Town_match = re.match('', scraping_str) # matchの部分は適当に変えください 30 Town = Town_match.group() 31 scraping_list = [i for i in scraping_list if i == Town] 32 33 # 「番地」の抽出 34 num_match = re.match('', scraping_str) # matchの部分は適当に変えてください 35 num = num_match.group() 36 scraping_list = [i for i in scraping_list if i == num] 37 #################ここまでが質問箇所です#####################
補足情報
Ken_match = re.match('', scraping_str)の、''の部分正規表現を考えていただきたいです。
re.matchの、matchは適宜適切なものに変えてください。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/01/09 00:36