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

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

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

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

CSV

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

Python

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

Q&A

解決済

2回答

1405閲覧

Python, CSV変換の方法(タブ 区切りされていないテキストファイル)

hankechi78

総合スコア8

スクレイピング

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

CSV

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

Python

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

0グッド

0クリップ

投稿2020/08/05 23:25

編集2020/08/06 02:35

現在、タブに区切られていないtxtファイルをcsvファイル形式に変換しようとしています。
色々と検索してみましたが、初心者なものでいまいち良い考えが浮かびません・・・。

ファイルの内容としては以下のように複数の新聞記事が羅列されているものです。
日付、タイトル(含む副題)、本文(複数段落)のみを列の項目にしてそれ以外の情報は捨象し、csv形式に変換したいのですが、何か方法はあるでしょうか。

Le Monde (新聞社名)

Economie, mardi 13 mars 2012 30 mots, p. 16 (カテゴリ・日付・文字数・ページ数)
ECONOMIE (サブカテゴリ)
En baisse(サブタイトル?)
Le Japon(タイトル)
本文1行のみ.

© 2012 SA Le Monde. Tous droits réservés.       Le présent document est protégé par les lois et conventions internationales sur le droit d'auteur et son utilisation est régie par ces lois et conventions. 

Certificat émis le 31 juillet 2020 à ECOLE-NATIONALE-D'ADMINISTRATION à des fins de visualisation personnelle et temporaire.

news·20120313·LM·0q1303_527225

Le Monde (新聞社名)

Environnement & Sciences, lundi 12 mars 2012 489 mots, p. 9 (カテゴリ・日付・文字数・ページ数)
Planète (サブカテゴリ)
L'APRÈS-FUKUSHIMA Le Japon, l'année d'après la vague ENTRETIEN(サブタイトル)
Pierre-François Souyri « Les gens de Fukushima se sentent comme des sacrifiés »(タイトル)
本文1行目
本文2行目
本文3行目. 
本文4行目 
本文5行目.
(以下記事本文略)

© 2012 SA Le Monde. Tous droits réservés.       Le présent document est protégé par les lois et conventions internationales sur le droit d'auteur et son utilisation est régie par ces lois et conventions. 

Certificat émis le 31 juillet 2020 à ECOLE-NATIONALE-D'ADMINISTRATION à des fins de visualisation personnelle et temporaire.

news·20120312·LM·0q1103_526673

(以下略)

※著作権上、記事本文は掲載しておりません。

一応以下のとおり自分なりに実装してみましたが、記事本文を一塊にしてリストに追加する方法がわからず、一つの記事が複数のバラバラの要素としてリストに追加されてしまっています。
当然の帰結として「日付」リスト(list_categorie_date)の要素数と「本文」(list_text)リストの要素数が合致せずにエラーメッセージ「ValueError: arrays must all be same length」が表示されます。

また、以下ソースコードのような単純なfor文の記述では、記事カテゴリ(ex. Environnement & Sciences)と日付、文字数(mots)とページ数が分離できないだけでなく、タイトル・副題・筆者名・本文も一体となってしまいますが、良い解決方法が思い浮かびません。

ソースコード

Python

1import pandas as pd 2 3with open('/Users/hankechi78/Desktop/lemonde_test/articles/13032012-21032011lemonde_Japon_articles.txt', encoding='utf-8') as f: 4 lines = f.readlines() 5 6lines_strip = [line.strip() for line in lines] 7 8#日付の含まれる行には必ず「mots, p. 」という文字列があることに着目(ただし、これでは不要な情報であるカテゴリ・ページ数を日付の情報から分離できない) 9list_categorie_date = [line for line in lines_strip if ' mots, p. ' in line] 10 11list_text = [] 12#不要な部分をif文で全て排除しながらリストにfor文で一文ずつ追加していく 13for line in lines_strip: 14 if (not line.startswith('Le Monde') 15 and not ' mots, p. ' in line 16 and not line.startswith('©') 17 and not line.startswith('Certificat émis le 31 juillet 2020') 18 and not line.startswith('news·20')): 19 list_text.append(line) 20#これではタイトル・副題・筆者名・記事本文が区別できない上に同じ記事がバラバラの要素としてリストに保存されてしまいますが、他に思いつきません・・・ 21 22df_lemonde = pd.DataFrame( 23 {'categorie_and_date': list_categorie_date, 24 'text': list_text 25 }) 26 27df.to_csv('lemonde_test')

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

Traceback (most recent call last): File "csv_convert.py", line 19, in <module> df_lemonde = pd.DataFrame( File "/Users/hankechi78/opt/anaconda3/lib/python3.8/site-packages/pandas/core/frame.py", line 435, in __init__ mgr = init_dict(data, index, columns, dtype=dtype) File "/Users/hankechi78/opt/anaconda3/lib/python3.8/site-packages/pandas/core/internals/construction.py", line 254, in init_dict return arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype) File "/Users/hankechi78/opt/anaconda3/lib/python3.8/site-packages/pandas/core/internals/construction.py", line 64, in arrays_to_mgr index = extract_index(arrays) File "/Users/hankechi78/opt/anaconda3/lib/python3.8/site-packages/pandas/core/internals/construction.py", line 365, in extract_index raise ValueError("arrays must all be same length") ValueError: arrays must all be same length

補足

「Le Monde」〜「news·20XXXXXX·LM·0q2003_33XXXX」で一つの記事のブロックになっており、「© 20・・・」、「Certificat émis ・・・」の部分は同じ文字列が毎回繰り返されています。

副題や筆者名が無い記事も混在し、また文章の段落数も当然ながらまちまちです。

なお、list_categorie_dateを表示すると以下のとおりです。

'Economie, mardi 13 mars 2012 30 mots, p. 16', 'Environnement & Sciences, lundi 12 mars 2012 489 mots, p. 9', 'Environnement & Sciences, lundi 12 mars 2012 390 mots, p. 11', 'Environnement & Sciences, lundi 12 mars 2012 661 mots, p. 9', 'Environnement & Sciences, lundi 12 mars 2012 604 mots, p. 11', 'Environnement & Sciences, lundi 12 mars 2012 460 mots, p. 9', 'Environnement & Sciences, lundi 12 mars 2012 447 mots, p. 11', 'Environnement & Sciences, lundi 12 mars 2012 32 mots, p. 11', 'Environnement & Sciences, lundi 12 mars 2012 372 mots, p. 10', 'Environnement & Sciences, lundi 12 mars 2012 1041 mots, p. 8', 'Environnement & Sciences, lundi 12 mars 2012 295 mots, p. 10', 'Environnement & Sciences, lundi 12 mars 2012 87 mots, p. 11', 'Environnement & Sciences, lundi 12 mars 2012 84 mots, p. 11', 'Environnement & Sciences, lundi 12 mars 2012 444 mots, p. 10', 'Environnement & Sciences, lundi 12 mars 2012 112 mots, p. 8', 'A la Une, lundi 12 mars 2012 27 mots, p. 1', (以下略)

また、list_textを表示すると以下のとおりです。

['', '', 'ECONOMIE', 'En baisse', 'Le Japon', "本文(1行のみ).", '', '', '', '', '', '', '', 'Planète', "L'APRÈS-FUKUSHIMA Le Japon, l'année d'après la vague ENTRETIEN", 'Pierre-François Souyri « Les gens de Fukushima se sentent comme des sacrifiés »', "本文1行目", '本文2行目', "本文3行目", (以下記事本文略), '', '', '', '', '', '', '', (以下略)

※著作権上、記事本文を記載しておりません

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

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

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

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

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

jeanbiego

2020/08/05 23:59

まずはその思いついたことを実装して、コードと実行結果を書いて下さい。その方が有用な回答がつくと思います。 完全な元データが貼られてないのでわかりませんが、タイトル名と著者名は改行で見分ける手もありそうです。
hankechi78

2020/08/06 02:37

早速ありがとうございます。コードと実行結果を追記いたしましたので、もし可能であればご助言いただけると幸いです。
guest

回答2

0

ベストアンサー

・本文行数が変動あり
ということで下のように書いてみました。
'Le Monde (新聞社名)\n'で記事を分けて、そこからタイトルとかを抜き出しています。
サブタイトルとかの有無も変動して行数が変わるようなら、これだと駄目かも知れません…

python3

1import pandas as pd 2 3with open('13032012-21032011lemonde_Japon_articles.txt', encoding='utf-8') as f: 4 lines = f.readlines() 5 6content_lst = list() 7content = list() 8for line in lines: 9 if line == 'Le Monde (新聞社名)\n': 10 content_lst.append(content) 11 content = list() 12 content.append(line) 13content_lst.append(content) 14 15title_lst = list() 16subtitle_lst = list() 17text_lst = list() 18date_lst = list() 19for content in content_lst: 20 if content == []: 21 continue 22 title_lst.append(content[4]) 23 subtitle_lst.append(content[3]) 24 text_lst.append(" ".join(content[5:-6])) 25 [date_lst.append(c) for c in content if c[:5] == "news·"] 26df_lemonde = pd.DataFrame({"title":title_lst, "subtitle":subtitle_lst, "text":text_lst, "date":date_lst}) 27print(df_lemonde) 28""" 29 30title subtitle text date 310 Le Japon(タイトル)\n En baisse(サブタイトル?)\n 本文1行のみ.\n \n news·20120313·LM·0q1303_527225\n 321 Pierre-François Souyri « Les gens de Fukushima... L'APRÈS-FUKUSHIMA Le Japon, l'année d'après la... 本文1行目\n 本文2行目\n 本文3行目.\n 本文4行目\n 本文5行目.\n (以下記... news·20120312·LM·0q1103_526673 33"""

投稿2020/08/06 03:53

jeanbiego

総合スコア3966

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

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

hankechi78

2020/08/06 04:37

ありがとうございます! for文で記事ごとのブロックを作る方法から、join関数、末尾から行数を指定する方法まで、非常に勉強になりました。特に一つ目のfor文は動作イメージが掴めた時、感動いたしました。 初歩的な質問で申し訳ないのですが、for content in content_lst:の後の if content == []: continue ここのコードはどんな役割を果たしているのでしょうか。 まさに、サブタイトルが複数あったり、記者名の行が入ったブロックがあったりと、本文以外も行数が変動してしまうのですが、そこはもはや、「サブカテゴリの後〜末尾の日付情報前」の部分を、サブタイトルもタイトルも記者名も含めて丸ごと本文として扱うしか無いのかなと思います・・・
jeanbiego

2020/08/06 05:19

すみません、1個目のfor文の書き方が雑だったのでcontent_lstの一つ目は空のリストが入ってしまっています。そこのif文は、空リストをスキップしかっただけの汚いコードです。 人名やタイトルは、法則性があれば正規表現とかでどうにかなるのかもしれませんが、なかなか大変そうですね。 少しでもお力になれたなら幸いです。
hankechi78

2020/10/09 14:36

ありがとうございます。理解しました。 回答が遅くなりすみません!
guest

0

1行目:新聞名
2行目:発行日ページ数
3行目:タイトル
4行目:副題
5行目:筆者名
6行目~news·YYYYMMDD型の日付· までを本文かつ1記事の区切り

を繰り返すでよいのでは

投稿2020/08/06 00:01

aokikenichi

総合スコア2218

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

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

hankechi78

2020/08/06 02:38

早速ありがとうございます。補足に追記したように、記事によって記事本文の長さも、記事本文以外に含まれる要素もバラバラで、その点で苦労しております・・・ コードと実行結果を追記いたしましたので、もし可能であればご助言いただけると幸いです。
aokikenichi

2020/08/06 03:58

私のやり方であれば ・記事本文の長さ は関係ありません。 ・記事本文以外に含まれる要素もバラバラ とはどうバラバラなのでしょうか
hankechi78

2020/08/06 04:43

言葉足らずで失礼いたしました。副題の行数(2行以上あることもある)、筆者名の有無が記事ごとにバラバラです。
aokikenichi

2020/08/06 08:59

「副題の行数(2行以上あることもある)」 改行なしで折り返されているだけでなく改行されているのでしょうか。 特に副題を示す記号もないようですので、それだと諦めるしかないかと。 「筆者名の有無が記事ごとにバラバラ」 これも特に筆者を示すような記号がないならば ・別途筆者DBを作りそれに合致したら筆者、なければ筆者なしとするしかない ・諦める しかないですね。 少なくとも本文は何行であっても1つにまとめられるので、そこまでで我慢ですかね。
hankechi78

2020/10/09 14:36

ありがとうございます、なかなかスクレイピング も難しいのですね・・・ 返信が遅くなり失礼しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問