تمرير بيانات الويب إلى حساء جميل-قائمة فارغة
-
26-12-2019 - |
سؤال
لقد قمت بإعادة فحص الكود الخاص بي ونظرت إلى عمليات مماثلة عند فتح عنوان ورل لتمرير بيانات الويب إلى حساء جميل ، لسبب ما ، لا يعيد الكود الخاص بي أي شيء على الرغم من أنه في الشكل الصحيح:
>>> 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...
كما هو مبين ، فمن الواضح أن إرموبين() إرجاع استجابة هتب التي يتم التقاطها من قبل المحتوى المتغير ، فمن المنطقي أنه يمكن قراءة حالة الاستجابة ، ولكن بعد تمريرها إلى حساء جميل ، لا يتم تحويل بيانات الويب إلى كائن حساء جميل (حساء متغير).يمكنك أن ترى أنني حاولت قراءة بعض العلامات والنص ، فإن جيت_تكست() إرجاع قائمة فارغة ، وهذا أمر غريب.
الغريب ، عندما أقوم بالوصول إلى بيانات الويب عبر المحتوى.البيانات ، تظهر البيانات ولكنها ليست مفيدة لأنني لا أستطيع استخدام حساء جميل لتحليلها.ما هي مشكلتي?شكرا.
المحلول
إذا كنت تريد فقط كشط الصفحة, 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'
نصائح أخرى
أورليب3 بإرجاع كائن استجابة ، والذي يحتوي على .data
التي لديها حمولة الجسم مسبقة التحميل.
لكل بداية سريعة أعلى مثال الاستخدام هنا, ، وأود أن تفعل شيئا من هذا القبيل:
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
...
يجب أن يعمل الباقي على النحو المنشود.
--
قليلا عن ما حدث من خطأ في التعليمات البرمجية الأصلية:
لقد مررت بالكامل response
الكائن بدلا من حمولة الجسم.يجب أن يكون هذا جيدا عادة لأن response
الكائن هو كائن يشبه الملف, باستثناء في هذه الحالة أورليب3 يستهلك بالفعل كل من الاستجابة ويوزع لك ، بحيث لا يوجد شيء اليسار إلى .read()
.انها مثل تمرير فيلبوانتر التي تم قراءتها بالفعل. .data
من ناحية أخرى سوف الوصول إلى البيانات بالفعل قراءة.
إذا كنت تريد استخدام كائنات استجابة أورليب3 ككائنات تشبه الملف ، فستحتاج إلى تعطيل التحميل المسبق للمحتوى ، مثل هذا:
response = http.request('GET', 'http://www.crummy.com/software/BeautifulSoup/', preload_content=False)
soup = BeautifulSoup(response) # We can pass the original `response` object now.
الآن يجب أن تعمل كما هو متوقع.
وأنا أفهم أن هذا ليس سلوك واضح جدا ، وكما مؤلف أورليب3 أعتذر.:) نحن نخطط لجعل preload_content=False
الافتراضي يوما ما.ربما يوما ما قريبا (فتحت قضية هنا).
--
ملاحظة سريعة على .urlopen
مقابل .request
:
.urlopen
يفترض أنك ستهتم بترميز أي معلمات تم تمريرها إلى الطلب.في هذه الحالة ، من الجيد استخدام .urlopen
لأنك لا تمر أي معلمات للطلب ، ولكن بشكل عام .request
سوف تفعل كل عمل إضافي بالنسبة لك حتى انها أكثر ملاءمة.
إذا كان أي شخص على استعداد لتحسين وثائقنا لهذا الغرض ، فسيكون ذلك موضع تقدير كبير.:) يرجى إرسال العلاقات العامة إلى https://github.com/shazow/urllib3 وإضافة نفسك كمساهم!
كما هو مبين ، فمن الواضح أن إرموبين () بإرجاع استجابة هتب التي يتم التقاطها من قبل محتوى متغير…
ما كنت قد دعا content
ليس المحتوى ، ولكنه كائن يشبه الملف يمكنك قراءة المحتوى منه.بوتيفولسوب سعيد تماما أخذ مثل هذا الشيء ، ولكن ليس من المفيد جدا لطباعته لأغراض التصحيح.لذلك ، دعونا في الواقع قراءة المحتوى للخروج منه لجعل هذا أسهل لتصحيح:
>>> response = connectBuilder.urlopen('GET', 'http://www.crummy.com/software/BeautifulSoup/')
>>> response
<urllib3.response.HTTPResponse object at 0x00000000032EC390>
>>> content = response.read()
>>> content
b''
هذا يجب أن يوضح ذلك BeautifulSoup
ليست المشكلة هنا.لكن الاستمرار في:
but ولكن بعد تمريرها إلى حساء جميل ، لا يتم تحويل بيانات الويب إلى كائن حساء جميل (حساء متغير).
نعم هو كذلك.حقيقة أن soup.title
أعطاك None
بدلا من رفع AttributeError
هو دليل جيد جدا ، ولكن يمكنك اختباره مباشرة:
>>> type(soup)
bs4.BeautifulSoup
هذا بالتأكيد BeautifulSoup
كائن.
عندما تمر BeautifulSoup
سلسلة فارغة ، بالضبط ما تحصل عليه مرة أخرى سوف تعتمد على أي محلل انها تستخدم تحت الأغطية;إذا كان الاعتماد على الثعبان 3.س ستدليب ، ما ستحصل عليه هو html
عقدة مع فارغة head
, ، وفارغة body
, ، ولا شيء غير ذلك.لذلك ، عندما تبحث عن title
عقدة ، ليس هناك واحد ، وتحصل None
.
وبالتالي, كيف يمكنك إصلاح هذا?
كما الوثائق يقول ، كنت تستخدم " أدنى مستوى الدعوة لتقديم طلب ، لذلك سوف تحتاج إلى تحديد جميع التفاصيل الخام."ما هي تلك التفاصيل الخام?بصراحة ، إذا كنت لا تعرف بالفعل ، فلا يجب أن تستخدم هذه الطريقة لتعليمك كيفية التعامل مع التفاصيل تحت غطاء المحرك urllib3
قبل أن تعرف حتى الأساسيات لن تفعل لك خدمة.
في الواقع ، أنت حقا لا تحتاج urllib3
هنا على الإطلاق.مجرد استخدام الوحدات التي تأتي مع بيثون:
>>> # 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.'
كان رمز الحساء الجميل الخاص بي يعمل في بيئة واحدة (جهازي المحلي) وإرجاع قائمة فارغة في واحد آخر (خادم Ubuntu 14).
لقد حلت مشكلتي تغيير التثبيت. التفاصيل في موضوع آخر:
href="https://stackoverflow.com/questions/15821789/html-parsing-with-beautiful-sourop-returns-ampty-list"> تحليل HTML مع الحساء الجميل إرجاع قائمة فارغة / ص>