سؤال

لقد قمت بإعادة فحص الكود الخاص بي ونظرت إلى عمليات مماثلة عند فتح عنوان ورل لتمرير بيانات الويب إلى حساء جميل ، لسبب ما ، لا يعيد الكود الخاص بي أي شيء على الرغم من أنه في الشكل الصحيح:

>>> 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 مع الحساء الجميل إرجاع قائمة فارغة / ص>

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top