
python(3.10)のWebスクレイピングで、requestsとBeautifulSoup利用で、こんな現象。
find(最初の1行だけ)だとurl出るのに、find_allだとurlがNoneになる。
不思議です。
PCのpython-IDLEでも、googleのcolabでも結果は同じ。こんな経験された方、いませんか?
--------------------------------------------
PC Win10 python3.10 IDLE
urlはあるWebサイトで多数のリストを一覧表で掲載。
python プログラム
import requests
from bs4 import BeautifulSoup
load_url = "url"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")
chap = soup.find('div', id="aaa")
names = chap.find("li") #findだとhrefが機能する!
for name in names:
n_url = name.get("href")
n_name = name.getText()
print(n_url,"\t",n_name)
#htmlの該当部分は,下記の構造 <url 名前 県名> を表示
<li class=""><a href="url/***.pdf" target="_blank">伊藤</a><span class="small">(愛知)</span></li>
---------------
結果 問題なし期待した内容だ、ただ意味不明なNoneが入ってる
url/aaa.pdf 伊藤 None (愛知)
#htmlの該当部分は,下記の構造で、soup結果が複数行配列となっていることはprintで確認済み。
<li class=""><a href="url/***.pdf" target="_blank">名前</a><span class="small">(県名)</span></li>
-----------------------------------
import requests
from bs4 import BeautifulSoup
load_url = "url"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")
chap = soup.find('div', id="aaa")
names = chap.find_all("li") #find_allだとhrefがNoneに
for name in names:
n_url = name.get("href")
n_name = name.getText()
print(n_url,"\t",n_name)
------------------
結果 あるはずのurlが全てNoneになっている。それ以外は予定した内容。
None 伊藤(愛知)
None 吉田(東京)
None 佐藤(名古屋)
None 田中(広島)
以下同様
-----------------------------------
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
手持ちの環境にBeautifulSoupを入れてみてhelpをみたけど
find の返値は A PageElement で find_all の返値は A ResultSet of PageElements だった。後者はリストでなくセットですね。まあ大差ないでしょう。
PageElement から for で要素を取得した時に何が返るかは要確認だけど先の回答でおおよそ間違いないかと思う。
No.2
- 回答日時:
うーん。
動作チェックしていないのでコードからの推測ですが……names = chap.find("li")のときnamesは <li> <a href="url">xxx</a><span>yyy</span></li> というli要素だと思いますが、このときnameは何になっていますか? <a href="url">xxx</a>や<span>yyy</span>になっているのではないかと推測しますが。このとき前者のa要素はhrefタグを持つのでurlを返します。後者のspanはhrefを持たないのでNoneが返ります。getTextはそれぞれxxxとyyyを返します。
names = chap.find_all("li") のときのnamesはおそらく[<li> <a href="url">xxx</a><span>yyy</span></li>] という1要素のリストと思います。このときnameは <li> <a href="url">xxx</a><span>yyy</span></li> で、li要素はhrefタグを持たないのでNoneしか返しません。getTextはxxx yyyを返します。
要するにfindとfind_allは返る型が違うので、同じ操作で同じような結果にはなりません。findは中身かNoneが返るがfind_allは必ずリストが返るのでリストの中身を処理するように書かないと上手くいきません。
動作が分かりにくいようならところどころにprint文を入れて返値をチェックしながらコードを書くと良いでしょう。
返信、感謝!
小生、まだpython勉強始めて保育園以下です。
ネットと本で勉強中。今回、初めて壁に頭が当たって質問させてもらいました。
100件以上あるリストですが、配列3番目[2]でそれぞれをprintしたら中身は下記でした。1件目からすべて同じ構造でした。
1.find_all("li") →<li> <a href="url">xxx</a><span>yyy</span></li>
2.find_all("a") →<a href="url">xxx</a>
3.finde_all("span") →<span>yyy</span>
正解かどうかわかりませんが、1からurl, xxx, yyy 全てをまとめて取り出すのは諦め、
2と3をそれぞれ行って、2つの配列を作り、件数(2つとも同じ)をカウントし、
while文で
2から
url →2.get('href')
xxx →2.getText()
3から
yyy →3.getText()
を組み合わせて1行にprintすることで、目的の部分を取り出すことができました。
ただ、この方法はすべての行に同じ構造があったためにできたことで、汎用性はありません。スマートでもありません。
きっと何か良い方法があるはずです。
いつもやってる手動スクレイピングで、Webをコピーし、エディターで整形した方が正確かつ早くできました。自動スクレイピング前途遼遠!
No.1
- 回答日時:
liタグの中にはaタグだけで無くspanタグも入っているので、
for name in names.find_all("a"):
でしょう。
さっそくのご教示に感謝します。(投稿からわずか1時間以内!)
a要素のurlと名前は、教えていただいた方法で、表示できるようになりました。大進歩です!!!
ありがとうございます(^-^;
for name in names.find_all("a"):
で取り出せたのは、配列で
[<a href="url">xxx</a>,---,---,---]
で、取り出せたのは、url xxx だけ。
names = chap.find_all("li") で取り出された
<li> <a href="url">xxx</a><span>yyy</span></li>
のyyy部分が抽出できません。
ただ、こっちでは getText()で、None xxx yyy が抽出されています。Noneは謎!
names = chap.find("li") (最初の1件だけ)では
<li> <a href="url">xxx</a><span>yyy</span></li>
から、url xxx yyy が取り出せました。
find_allで配列要素になったら<span>が邪魔で取り出せないって理解困難。
これは、なんかのバグでしょうか?
ご教示いただいた方法+li要素で抽出しgetTextで取り出しものを加工しクエリーでくっつけることは可能です。
でも、これはpythonの簡潔さ方針とは反します。
難しいですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- HTML・CSS 書籍を見つつサイト造りの練習をしているのですが、見た目が一致しません 2 2022/11/28 15:00
- HTML・CSS CSS のみのタブ切り替えについて 1 2023/01/11 16:47
- JavaScript jqueryを使ったスムーススクロールのコードを書いたのですが、HTMLコード内にある、a butt 2 2022/04/14 10:59
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- その他(プログラミング・Web制作) python 気象データの取得 2 2023/06/20 23:54
- HTML・CSS CSSが効かずどのように指定すれば良いか分からないのでアドバイスお願い致します 2 2023/06/07 12:25
- HTML・CSS アコーディオンメニューが思うように動作しません。 1 2023/08/20 16:48
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- HTML・CSS cssの display: flex;で横並びにならずに困ってます 1 2022/12/04 13:18
- HTML・CSS ヘッダーの画像にメインエリアがかぶってしまいます 1 2022/11/28 14:06
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
<a href="#" …>の意味を教えて...
-
HPで同じページ内にリンクを貼...
-
サイトの最新記事へのリンクを...
-
リンクの文字の色
-
ブログのhtmlのリンクを触...
-
フレームでリンク先を2つ指定...
-
ページ内、ピクセル移動でスム...
-
IE10で画像切り替えがされません
-
フレームだけ閉じる方法ありま...
-
リンクの表現
-
リンクとリンクの間に空白の行が
-
php関数を使用しないリダイレクト
-
JavaSciprtでの条件分岐
-
リンク先をジャバスクリプトで...
-
GETを使ってテキストリンクで値...
-
リンクの既読制御について
-
A Href=~ で飛んだときに特定...
-
cgiファイル内での、mailto...
-
ジャバスクリプトが無効になっ...
-
Netscape4.7で。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
<a href="#" …>の意味を教えて...
-
html メールリンクにて自動ファ...
-
相対パスと絶対パスの速度
-
HTMLソースからURLだけを抜き出...
-
pythonのWebスクレイピングでfi...
-
フレームだけ閉じる方法ありま...
-
テキストから文字列を抜き出す...
-
時間によってリンク先を変える...
-
同意を求めて、次のページに進...
-
リンクに飛ばない・・・
-
アンカーをクリックしても遷移...
-
個別にハイパーリンクの色を指...
-
二つのプルダウンメニューで最...
-
HTML内に記載された画像のURLを...
-
ホームページ作成 ツリーメニュー
-
<META HTTP-EQUIV='refresh' CO...
-
ページ内リンクについて
-
ホームページの一部の表示をラ...
-
ツリーメニューを2個つづけると
-
CGI検索エンジンをHTMLに
おすすめ情報
とりあえず、目的を達成できたけど、もやもやしてさらに調べているうちにこのサイトを発見。
BeautifulSoupの使い方
https://lets-hack.tech/programming/languages/pyt …
解説分かりやすく、「こうすれば失敗」も書かれてる。
これを参考にして、liのリストを作り、件数を数えwhileで、liごとに
print(liのaのhref、liのテキスト)で、url 名前 県 を作ることに成功!
liのリストの各要素は、<class 'bs4.element.Tag'>でした。単なる文字列(str)ではなかった。
なのでbs4のメソッドが使えました。
まとめ
最初にdivで抽出し
その中のliを抽出し
liの1つごとにメソッド適用し、対象全件の url 名前 県名 を抽出できました。
load_url = "http://******"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")
div_abcd = soup.find('div', id="abcd") #soupメソッドで特定divタグ抽出
lists = div_abcd.find_all("li") #soupメソッドでliタグ全件抽出
for list in lists: #liタグリスト全体を
print(list.a.get('href'),list.text) #抽出したliタグ一件ごとにa要素のurlと、textをprint