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

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

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

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

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

2回答

3458閲覧

pythonで \r\n が削除できない

of_the_Europa

総合スコア66

スクレイピング

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

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

0クリップ

投稿2020/10/17 13:36

スクレイピングで取得した記事のリストから余分な \r\n を削除させたいのですが、次のエラーを吐き出してしまいました。

AttributeError: 'list' object has no attribute 'replace'

使用環境
GoogleCrome 86.0.4240.75(64bit)
JupyterLab 2.1.5
JupyterLabのノートブックでプログラムを記述

問題の記事はこのようになります。

#!/usr/bin/env python # coding: utf-8 from bs4 import BeautifulSoup import urllib.request as req import pandas as pd import numpy as num import re url = "https://www.msn.com/ja-jp" response = req.urlopen(url) soup = BeautifulSoup(response, 'html.parser') lists = soup.find_all(href=re.compile("/ja-jp/news")) #パスはサイトの右下に表示される lists[1:21] select = [] url_select = [] for list in lists: select.append(list.string) url_select.append(list.attrs['href']) selected = select.replace('\r\n','') selected

最後のselect.replaceを、select.strip()としてみたり、select.re(r'(.+)\r\n')としてみましたが、エラーはいずれも上記の通りでした。
エラーの意味を察するに、指定のオブジェクトは属性を持たないということでしょうか? だとしても、どのように対処すればいいのか分かりません。
どうかお力をいただきますように、なにか分かれば教えていただければ幸いです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

listは、組み込み関数とかぶるので、別の名前lstとかを使いましょう。

実際に動かしてみると、lst.stringがNoneなものがちらほら取得できるので、それらを取り除いてからreplaceしたものをappendすりゃいいのではないかな。

Python

1for lst in lists: 2 if lst.string: 3 select.append(lst.string.replace('\r\n', '')) 4 url_select.append(lst.attrs['href'])

投稿2020/10/17 14:41

編集2020/10/17 14:42
Daregada

総合スコア11990

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

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

of_the_Europa

2020/10/17 16:27

Daregada様 ありがとうございます! 上記の記述でうまくいきました。 おっしゃる通りに "list" と定義するのはあまりにユニークではないですね。ちょっと気になってはいたのですが、あまり関係のないことだと無視を決め込んでいました。 先のotn様も仰っていたように文字列に対してreplaceしなくてはならないとのことでしたが、その記述方法がいまいちピンときませんでした。なるほどif文の条件に lst.string と、まず記述するのですね。ここはそのような解釈の仕方が、自分は苦手かもしれません……。またそのうえで lst.string.replace と関数をつなげて書くという方法もあるのですね。オブジェクト名につなげることはできても、関数通しを繋げることは単純にドットではできないと思っていました。ドットで繋げられるのは同じクラス内のメソッドという関係性だけだと思っていました。 素早い御回答ありがとうございますm(__)m
Daregada

2020/10/17 16:37

> なるほどif文の条件に lst.string と、まず記述するのですね ちがいます。listsからひとつのlstを取り出すと、lst.stringには、通常は文字列が入っていますが、たまにNoneが得られます。Noneに対してreplaceを使うとエラーになるため、「lst.stringがNoneでなければ」という条件を短く書いているのです。lst.stringが全て文字列を得られるのであれば、このifは不要で、いきなりlsr.string.replaceすればいいです。
of_the_Europa

2020/10/17 17:07

わかりましたm(__)m よく見ると、記事の間にところどころあったNoneが、そういえば消えていました。Noneは 文字列型ではないため、ということですね。 すごく理解が深まりました! ありがとうございます!
guest

0

selectは文字列じゃなくてリストなので、replaceできません。

リストの要素である文字列に対して、replaceしましょう。

というか、select.appendする前のlist.string(これは文字列)に対してreplaceすればいいかと思います。

投稿2020/10/17 13:43

otn

総合スコア85901

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

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

of_the_Europa

2020/10/17 16:45

otn様 ご助言ありがとうございます。 文字列に対して replace するということでしたが、ではリスト型として定義されたのはどこからなのかと考えたとき、for文からという認識で合っているでしょうか? またその解釈で合っているとするならば、答えの一つであるfor文の中で、lst.string.replace('\r\n', '') と定義できるのは何故なのか、もし可能でしたら、その解釈を教えていただけないでしょうか。 御面倒お掛け致しますm(__)m
otn

2020/10/17 23:00

> リスト型として定義されたのはどこからなのか select = [] > lst.string.replace('\r\n', '') と定義できるのは何故なのか list は soup.find_all の結果である「ノードのリスト」の1つの要素なので、 list は「bs4のノード」。list.string は文字列です。 常に「この変数は何型なのか?このメソッドの返す物は何型なのか?」を考えながらプログラムを書きましょう。
of_the_Europa

2020/10/18 01:56

find_all がリスト型だったことを知らず、また何型かの意識もなく記述していた状態でしたので、今回はとてもためになりました。 まだメソッドや関数のそれぞれの役目や特徴に無知な部分が多いので、慣れるまでは別ファイルにでも型の判定した一覧を掲示してそれを見ながら進めてみようと思います。 とても感謝しております。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問