Güzel Çorba - Sorun Giderme

Hata yönetimi

BeautifulSoup'ta ele alınması gereken iki ana hata türü vardır. BeautifulSoup API bir hata attığından, bu iki hata komut dosyanızdan değil, kod parçacığının yapısından kaynaklanmaktadır.

İki ana hata aşağıdaki gibidir -

AttributeError

Nokta notasyonunun mevcut HTML etiketine bir kardeş etiket bulmaması neden olur. Örneğin, eksik "bağlantı etiketi" nedeniyle bu hatayla karşılaşmış olabilirsiniz, maliyet anahtarı geçiş yaparken bir hata atar ve bir bağlantı etiketi gerektirir.

KeyError

Bu hata, gerekli HTML etiketi özniteliği eksikse oluşur. Örneğin, bir ön bilgide data-pid özniteliğimiz yoksa, pid anahtarı anahtar hatası atar.

Bir sonucu ayrıştırırken yukarıda listelenen iki hatayı önlemek için, veritabanlarına hatalı biçimlendirilmiş bir snippet eklenmediğinden emin olmak için bu sonuç atlanacaktır -

except(AttributeError, KeyError) as er:
pass

teşhis koymak()

BeautifulSoup'un belgemize veya HTML'ye ne yaptığını anlamada herhangi bir zorluk bulduğumuzda, bunu diagnose () işlevine aktarmanız yeterlidir. Belge dosyasını diagnose () işlevine iletirken, farklı ayrıştırıcı listesinin belgeyi nasıl işlediğini gösterebiliriz.

Aşağıda diagnose () işlevinin kullanımını gösteren bir örnek verilmiştir -

from bs4.diagnose import diagnose

with open("20 Books.html",encoding="utf8") as fp:
   data = fp.read()
   
diagnose(data)

Çıktı

Ayrıştırma hatası

İki ana tür ayrıştırma hatası vardır. Belgenizi BeautifulSoup'a beslediğinizde HTMLParseError gibi bir istisna elde edebilirsiniz. Ayrıca, BeautifulSoup ayrıştırma ağacının ayrıştırma belgesinden beklenen sonuçtan çok farklı göründüğü beklenmedik bir sonuç da alabilirsiniz.

Ayrıştırma hatalarının hiçbiri BeautifulSoup'tan kaynaklanmadı. BeautifulSoup herhangi bir ayrıştırıcı kodu içermediğinden, kullandığımız harici ayrıştırıcıdan (html5lib, lxml) kaynaklanmaktadır. Yukarıdaki ayrıştırma hatasını çözmenin bir yolu, başka bir ayrıştırıcı kullanmaktır.

from HTMLParser import HTMLParser

try:
   from HTMLParser import HTMLParseError
except ImportError, e:
   # From python 3.5, HTMLParseError is removed. Since it can never be
   # thrown in 3.5, we can just define our own class as a placeholder.
   class HTMLParseError(Exception):
      pass

Python yerleşik HTML ayrıştırıcısı en yaygın iki ayrıştırma hatasına neden olur, HTMLParser.HTMLParserError: hatalı biçimlendirilmiş başlangıç ​​etiketi ve HTMLParser.HTMLParserError: bozuk bitiş etiketi ve bunu çözmek için, esas olarak başka bir ayrıştırıcı kullanmaktır: lxml veya html5lib.

Diğer bir yaygın beklenmedik davranış türü, belgede olduğunu bildiğiniz bir etiketi bulamamanızdır. Ancak, çalıştırdığınızda find_all () [] döndürür veya find () None döndürür.

Bunun nedeni python yerleşik HTML ayrıştırıcısının bazen anlamadığı etiketleri atlaması olabilir.

XML ayrıştırıcı Hatası

Varsayılan olarak, BeautifulSoup paketi belgeleri HTML olarak ayrıştırır, ancak kullanımı çok kolaydır ve güzel biçimlendirilmiş XML'i beautifulsoup4 kullanarak çok zarif bir şekilde işleyebilir.

Belgeyi XML olarak ayrıştırmak için, lxml ayrıştırıcısına sahip olmanız ve ikinci bağımsız değişken olarak "xml" yi Beautifulsoup yapıcısına iletmeniz yeterlidir -

soup = BeautifulSoup(markup, "lxml-xml")

veya

soup = BeautifulSoup(markup, "xml")

Yaygın bir XML ayrıştırma hatası:

AttributeError: 'NoneType' object has no attribute 'attrib'

Bu, find () veya findall () işlevi kullanılırken bazı elemanların eksik olması veya tanımlanmaması durumunda meydana gelebilir.

Diğer ayrıştırma hataları

Aşağıda, bu bölümde tartışacağımız diğer ayrıştırma hatalarından bazıları verilmiştir -

Çevresel sorun

Yukarıda belirtilen ayrıştırma hatalarının dışında, betiğinizin bir işletim sisteminde çalışıp başka bir işletim sisteminde çalışmayabileceği veya bir sanal ortamda çalışıp başka bir sanal ortamda çalışmayabileceği veya çalışmayabileceği çevre sorunları gibi başka ayrıştırma sorunları ile karşılaşabilirsiniz. sanal ortamın dışında. Tüm bu sorunlar, iki ortamın farklı ayrıştırıcı kitaplıklarına sahip olmasından kaynaklanabilir.

Mevcut çalışma ortamınızda varsayılan ayrıştırıcınızı bilmeniz veya kontrol etmeniz önerilir. Geçerli çalışma ortamı için mevcut olan geçerli varsayılan ayrıştırıcıyı kontrol edebilir veya gerekli ayrıştırıcı kitaplığını, BeautifulSoup yapıcısına ikinci bağımsız değişkenler olarak açıkça iletebilirsiniz.

Büyük / küçük harfe duyarlı değil

HTML etiketleri ve nitelikleri büyük / küçük harfe duyarlı olmadığından, üç HTML ayrıştırıcı da etiket ve nitelik adlarını küçük harfe dönüştürür. Ancak karışık veya büyük harfli etiketleri ve nitelikleri korumak istiyorsanız, belgeyi XML olarak ayrıştırmak daha iyidir.

UnicodeEncodeError

Aşağıdaki kod segmentine bakalım -

soup = BeautifulSoup(response, "html.parser")
   print (soup)

Çıktı

UnicodeEncodeError: 'charmap' codec can't encode character '\u011f'

Yukarıdaki sorun iki ana durumdan kaynaklanıyor olabilir. Konsolunuzun nasıl görüntüleneceğini bilmediği bir unicode karakteri yazdırmaya çalışıyor olabilirsiniz. İkincisi, bir dosyaya yazmaya çalışıyorsunuz ve varsayılan kodlamanız tarafından desteklenmeyen bir Unicode karakteri iletiyorsunuz.

Yukarıdaki sorunu çözmenin bir yolu, istenen sonucu elde etmek için çorbayı yapmadan önce yanıt metnini / karakterini aşağıdaki gibi kodlamaktır -

responseTxt = response.text.encode('UTF-8')

KeyError: [attr]

Bunun nedeni, söz konusu etiket attr niteliğini tanımlamadığında ['attr'] etiketine erişilmesidir. En yaygın hatalar şunlardır: “KeyError: 'href'” ve “KeyError: 'class'”. Attr'ın tanımlı olduğundan emin değilseniz tag.get ('attr') kullanın.

for item in soup.fetch('a'):
   try:
      if (item['href'].startswith('/') or "tutorialspoint" in item['href']):
      (...)
   except KeyError:
      pass # or some other fallback action

AttributeError

AttributeError ile aşağıdaki gibi karşılaşabilirsiniz -

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

Yukarıdaki hata temel olarak find_all () işlevinin tek bir etiket veya dize döndürmesini beklediğiniz için oluşur. Bununla birlikte, juice.find_all bir python öğe listesi döndürür.

Tek yapmanız gereken, listeyi yinelemek ve bu öğelerden veri toplamaktır.