Web データを Beautiful Soup に渡す - 空のリスト
-
26-12-2019 - |
質問
コードを再チェックし、URL を開いて Web データを Beautiful Soup に渡す際の同等の操作を調べました。何らかの理由で、コードは正しい形式であるにもかかわらず、何も返しません。
>>> from bs4 import BeautifulSoup
>>> from urllib3 import poolmanager
>>> connectBuilder = poolmanager.PoolManager()
>>> content = connectBuilder.urlopen('GET', 'http://www.crummy.com/software/BeautifulSoup/')
>>> content
<urllib3.response.HTTPResponse object at 0x00000000032EC390>
>>> soup = BeautifulSoup(content)
>>> soup.title
>>> soup.title.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'name'
>>> soup.p
>>> soup.get_text()
''
>>> content.data
a stream of data follows...
示されているように、urlopen() が変数コンテンツによってキャプチャされた HTTP 応答を返すことは明らかです。応答のステータスを読み取ることができることは理にかなっていますが、それが Beautiful Soup に渡された後、Web データは変換されませんBeautiful Soup オブジェクト (可変スープ) に変換します。いくつかのタグとテキストを読み取ろうとしたところ、get_text() が空のリストを返したことがわかります。これは奇妙です。
奇妙なことに、content.data 経由で Web データにアクセスすると、データは表示されますが、Beautiful Soup を使用して解析できないため、役に立ちません。私の問題は何ですか?ありがとう。
解決
ページを削り取るだけの場合、requests
が必要なコンテンツを取得します。
from bs4 import BeautifulSoup
import requests
r = requests.get('http://www.crummy.com/software/BeautifulSoup/')
soup = BeautifulSoup(r.content)
In [59]: soup.title
Out[59]: <title>Beautiful Soup: We called him Tortoise because he taught us.</title>
In [60]: soup.title.name
Out[60]: 'title'
. 他のヒント
urllib3は、プリロードされたボディペイロードを持つ.data
を含む応答オブジェクトを返します。
トップQuickStart 使用例ここでは、このようなことをします。
import urllib3
http = urllib3.PoolManager()
response = http.request('GET', 'http://www.crummy.com/software/BeautifulSoup/')
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.data) # Note the use of the .data property
...
.
URLLIB3応答オブジェクトをファイルのようなオブジェクトとして使用する場合は、次のようにコンテンツのプリロードを無効にする必要があります。
response = http.request('GET', 'http://www.crummy.com/software/BeautifulSoup/', preload_content=False)
soup = BeautifulSoup(response) # We can pass the original `response` object now.
.
preload_content=False
vs .urlopen
に関するクイックノート:
誰かがこの効果に当社のドキュメントを改善するために起きているならば、それは大いに感謝されるでしょう。 :) PRを https://github.com/shazow/urllib3 を送ってください。
示されているように、urlopen() が変数 content によってキャプチャされた HTTP 応答を返すことは明らかです。
あなたが呼んだもの content
はコンテンツではなく、コンテンツを読み取ることができるファイルのようなオブジェクトです。BeautifulSoup はそのようなものを喜んで受け入れますが、デバッグ目的で出力するのはあまり役に立ちません。そこで、デバッグを容易にするために、実際にコンテンツを読み取ってみましょう。
>>> response = connectBuilder.urlopen('GET', 'http://www.crummy.com/software/BeautifulSoup/')
>>> response
<urllib3.response.HTTPResponse object at 0x00000000032EC390>
>>> content = response.read()
>>> content
b''
これでかなり明確になるはずです BeautifulSoup
ここでは問題ではありません。しかし、続けて:
…しかし、Web データは Beautiful Soup に渡された後、Beautiful Soup オブジェクト (変数スープ) に変換されません。
はい、そうです。事実 soup.title
あなたにあげた None
上げる代わりに AttributeError
これはかなり良い証拠ですが、直接テストすることもできます。
>>> type(soup)
bs4.BeautifulSoup
それは間違いなく BeautifulSoup
物体。
通過するとき BeautifulSoup
空の文字列。正確に何が返されるかは、内部でどのパーサーが使用されているかによって異なります。Python 3.x stdlib に依存している場合、得られるものは html
空のノード head
, 、そして空 body
, 、 何もありません。それで、あなたが探すとき、 title
ノードはありません。 None
.
それで、これをどうやって修正しますか?
として 文書 「リクエストを行うための最低レベルの呼び出しを使用しているため、すべての生の詳細を指定する必要があります。」それらの生の詳細は何ですか?正直なところ、まだ知らない場合は、この方法を使用すべきではありません。 urllib3
基本的なことはあなたにサービスを提供していないことに気づく前に。
実際、本当に必要ありません urllib3
まったくここにあります。Python に付属のモジュールを使用するだけです。
>>> # on Python 2.x, instead do: from urllib2 import urlopen
>>> from urllib.request import urlopen
>>> r = urlopen('http://www.crummy.com/software/BeautifulSoup/')
>>> soup = BeautifulSoup(r)
>>> soup.title.text
'Beautiful Soup: We called him Tortoise because he taught us.'
私の美しいスープコードは1つの環境(私のローカルマシン)で働いていて、別のものに空のリストを返していました(Ubuntu 14サーバー)。
私は私の問題を解決しました。 他のスレッドの詳細: