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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

HTML

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

Q&A

解決済

1回答

1583閲覧

HTMLのtableのセル間での対応関係を維持したままPythonデータフレーム形式へ出力したい

tak_ysk

総合スコア4

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

HTML

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

0グッド

1クリップ

投稿2020/06/17 02:04

前提・実現したいこと

取得したhtmlのtableについて,ブラウザ表示上の対応関係を維持したPythonデータフレーム形式のデータの出力を試みています。

以下で説明するようにHanako SuzukiのBiographyにおけるJun.2007とTakahashi Corp. CEOの対応関係が維持されたデータフレーム形式のデータを出力したいです。

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

ブラウザ表示すると分かるように,抽出したtableのBiography列(colspan=2)の年月セル(Apr.1962など)と内容セル(Joined our companyなど)は隣り合わせで対応しています。

htmlのtable

しかし,htmlコードでは各tdタグのなかでpタグで改行しているだけであり,明確に対応関係が表現されているわけではありません。
そのため,以下のpandasおよびBeautifulSoupを活用したPythonコードから出力されたデータフレーム形式(変数名table)では,年月セルと内容セルの内容がそれぞれ一つの要素として結合されており,対応関係が失われてしまいました。

特に,Hanako SuzukiのBiographyではもともとJun。2007にGeneral ManagerとTakahashi Corp. CEOという2つの情報が対応していたのですが,出力されたデータフレーム形式ではその関係性を復元することが困難になっています。

該当のソースコード

html

1<html lang="en"> 2<head> 3 <meta charset="utf-8"> 4</head> 5 6<body> 7 <div> 8 <h2>Directors</h2> 9 <table border="1"> 10 <tbody> 11 <tr> 12 <td> 13 <p>Position1</p> 14 </td> 15 <td> 16 <p>Position2</p> 17 </td> 18 <td> 19 <p>Name</p> 20 </td> 21 <td> 22 <p>Date of Birth</p> 23 </td> 24 <td colSpan="2"> 25 <p>Biography</p> 26 </td> 27 <td> 28 <p>Number of Shares</p> 29 <p>(thousands)</p> 30 </td> 31 </tr> 32 <tr> 33 <td> 34 <p>Executive Director</p> 35 <p>President</p> 36 </td> 37 <td> 38 <p>CEO</p> 39 </td> 40 <td> 41 <p>Taro Yamada</p> 42 </td> 43 <td> 44 <p>9/17/1940</p> 45 </td> 46 <td> 47 <p>&#xA0;Apr. 1962</p> 48 <p>&#xA0;Aug. 1989</p> 49 <p>&#xA0;Jun. 1991</p> 50 <p>&#xA0;Jun. 1997</p> 51 <p>&#xA0;Jun. 2000</p> 52 <p>&#xA0;Jun. 2005</p> 53 </td> 54 <td> 55 <p>Joined our company</p> 56 <p>President of Tokyo branch</p> 57 <p>Director</p> 58 <p>Managing Director</p> 59 <p>Senior Managing Director</p> 60 <p>Executive Director</p> 61 </td> 62 <td> 63 <p>18</p> 64 </td> 65 </tr> 66 <tr> 67 <td> 68 <p>Managing Director</p> 69 </td> 70 <td> 71 <p>CFO</p> 72 </td> 73 <td> 74 <p>Hanako Suzuki</p> 75 </td> 76 <td> 77 <p>3/29/1947</p> 78 </td> 79 <td> 80 <p>&#xA0;Apr. 1970</p> 81 <p>&#xA0;Jun. 2005</p> 82 <p>&#xA0;Jun. 2007</p> 83 <p> 84 <font>&#xA0;</font> 85 </p> 86 <p> 87 <font>&#xA0;</font> 88 </p> 89 <p>&#xA0;Jun. 2009</p> 90 <p>&#xA0;May. 2011</p> 91 </td> 92 <td> 93 <p>Joined our company</p> 94 <p>Manager</p> 95 <p>General Manager</p> 96 <p>Takahashi Corp.</p> 97 <p>CEO</p> 98 <p>Director</p> 99 <p>Managing Director</p> 100 </td> 101 <td> 102 <p>10</p> 103 </td> 104 </tr> 105 </tbody> 106 </table> 107 </div> 108</body> 109 110</html> 111

python

1import pandas as pd 2from bs4 import BeautifulSoup 3import html5lib 4import lxml 5 6with open("test_en.html") as f: 7 soup = BeautifulSoup(f, "lxml") 8 9tables = soup.find_all("table") 10table_list = pd.read_html(str(tables)) 11 12for i in range(len(table_list)): 13 table_list[i].columns = table_list[i].loc[0,] 14 table_list[i] = table_list[i].drop(table_list[i].index[0]) 15 16table = table_list[0] 17print(table)

以下,出力結果です。
出力結果

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

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

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

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

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

guest

回答1

0

ベストアンサー

pタグごとに抽出して縦に展開

python

1 2from bs4 import BeautifulSoup 3 4soup = BeautifulSoup(html, "html.parser") 5 6data = [] 7 8for tr in soup.find("table").find_all("tr"): 9 10 temp = [] 11 12 for td in tr.find_all("td"): 13 d = [p.get_text(strip=True) for p in td.find_all("p")] 14 15 for i in range(int(td.get("colspan", 1))): 16 temp.append(d) 17 18 data.append(temp) 19 20import pandas as pd 21 22df = pd.DataFrame(data) 23 24df = pd.concat([row.apply(pd.Series).T for _, row in df.iterrows()])

投稿2020/06/17 06:35

barobaro

総合スコア1286

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

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

tak_ysk

2020/06/17 07:19

ありがとうございます。無事に出力できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問