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

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

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

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

HTML

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

Q&A

解決済

1回答

769閲覧

Htmlデータから特定の文字を抽出したい

Kirari

総合スコア32

Python

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

HTML

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

0グッド

0クリップ

投稿2019/07/07 03:17

編集2019/07/07 06:22

前提・実現したいこと

Htmlデータからpython3.7で特定の文字を抽出しエクセルでリスト化したいのです。現在、下記の質問内容、途中で止まっています。

[質問内容]
Htmlデータからpython3.7で特定の文字を抽出しエクセルでリスト化したいのです。
今、以下のコードまで書きました。下記のコードを実行すると、最初の名前(発信者)1だけ読んで、次の名前(発信者)2を読んでもらえません。どうやったら次の名前を読んでもらえるのでしょうか。

<htmlデータ>

<div class="d-chat_timeline-post"> <p class="d-chat_timeline-name"> 名 前(発信者)1 </p> <ul class="d-chat_timeline-info"> <li>日付と時間1 </li> </ul> <div>名前1-1(受信者)<br /> 名前1-2(受信者)<br /> 名前1-3(受信者)<br /> 内容1</div> <div class="d-chat_timeline-post"> <p class="d-chat_timeline-name"> 名 前(発信者)2 </p> <ul class="d-chat_timeline-info"> <li>日付と時間2 </li> </ul> <div>名前2-1(受信者)<br /> 名前2-2(受信者)<br /> 名前2-3(受信者)<br /> 内容2</div> <div class="d-chat_timeline-post">

以下、同じ<div class="d-chat_timeline-post">の塊が続く。

<エクセルのリスト形式は以下の形式です>
エクセルのA-1には名前(発信者)1、B-1には日付と時間1、C-1には名前1-1名前1-3、D-1には内容1、
A-2には名前(発信者)2、B-2には日付と時間2、C-2には名前2-1
名前2-3、D-2には内容2……というリスト

<書いたコード>

#ファイルを読み込む
import os, tkinter, tkinter.filedialog, tkinter.messagebox
root = tkinter.Tk()
root.withdraw()
fTyp = [("","*.html")]
file = tkinter.filedialog.askopenfilename(filetypes = fTyp)
fd=open(file,"r",encoding="utf-8")

#htmlファイルを書き出す
res=fd.read()
from bs4 import BeautifulSoup
soup = BeautifulSoup(res,"html.parser")

#htmlファイルから取りだす
i=0
while True :
kaishi = res[i:].find('<p class="d-chat_timeline-name">')
i=res[kaishi:].find('<p class="d-chat_timeline-name">')
mojis = res[i:].find('<p class="d-chat_timeline-name">')
mojie = res[mojis:mojis+res[mojis:].find('</p>')]
print(mojie)
if i == -1 :
break

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

上記のコードを実行すると、最初の名前(発信者)1だけ読んで、次の名前(発信者)2を読んでもらえません。

エラーメッセージ <p class="d-chat_timeline-name"> 発信者1 <p class="d-chat_timeline-name"> 発信者1 <p class="d-chat_timeline-name"> 発信者1 <p class="d-chat_timeline-name"> 発信者1 <p class="d-chat_timeline-name"> 発信者1 <p class="d-chat_timeline-name"> 発信者1 <p class="d-chat_timeline-name"> 発信者1 がずっと続きます。 ### 該当のソースコード python3.7 ソースコード ### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まずはソースコードおよびHTMLはMarkdown記法のコードブロックを使用して記述してください。

不具合の原因ですが、現状でループ処理の中で、対象となるタグをfind() して位置を検索しておりますが、毎回同じ位置から検索をしておりますので、毎回同じ結果を得てしまう事が原因です。ですので、ループ2回目以降の検索では前回 find()の結果として得た位置後から検索を行うと不具合は解決するかと思います。

その他にも何点か気になることを列挙します。

  • htmlデータなのですが、<div class="d-chat_timeline-post"> に対応する </div> が無いように見えますが、このデータは間違ってませんでしょうか?
  • せっかく Beautifulsoup をimportしているのに、何故文字列操作にて表示を行おうとしているのでしょうか?
  • 同じタグ情報 <p class="d-chat_timeline-name"> にて3回連続で find() を行っておりますが、何か意図があるのでしょうか?

とりあえず参考までに、現状のコードのループ処理を少し改良して簡単にしたコードをサンプルとして記述しましたので参考にしてみてください。(コード簡略化の為、若干の不具合があるのでこのままでは使えませんが)

Python

1#htmlファイルから取りだす 2cur_pos=0 3while True : 4 target_tag = '<p class="d-chat_timeline-name">' 5 closing_tag = '</p>' 6 start_pos = res[cur_pos:].find(target_tag) 7 end_pos = res[cur_pos:].find(closing_tag) 8 if (start_pos == -1) or (end_pos == -1) or (start_pos > end_pos): 9 break 10 mojie = res[cur_pos + start_pos + len(target_tag) : cur_pos + end_pos] 11 print(mojie) 12 cur_pos = cur_pos + end_pos + len(closing_tag)

投稿2019/07/08 01:48

magichan

総合スコア15898

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

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

Kirari

2019/07/08 02:47

迅速なご回答ありがとうございます。プログラミングをはじめて2日目で、すみません、よくわかっておらず、いただいたコメントを読み解くのに時間がかかりそうですが、わからないところがあれば質問させてください。取り急ぎ御礼まで。 >>>> htmlデータなのですが、<div class="d-chat_timeline-post"> に対応する </div> が無いように見えますが、このデータは間違ってませんでしょうか? →すみません。間違っていました。ありがとうございます。 せっかく Beautifulsoup をimportしているのに、何故文字列操作にて表示を行おうとしているのでしょうか? →勉強します。ありがとうございます。 同じタグ情報 <p class="d-chat_timeline-name"> にて3回連続で find() を行っておりますが、何か意図があるのでしょうか? →ないです。どうしたらいいのかわからず、findを3回連続で使用してしまいました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問