Python kullanarak HTML'yi ayrıştırma


185

Python listeleri / sözlükler / nesneler şeklinde etiketleri almak için bana yardımcı olabilir Python için bir HTML Ayrıştırıcı modülü arıyorum.

Formun bir belgesi varsa:

<html>
<head>Heading</head>
<body attr1='val1'>
    <div class='container'>
        <div id='class'>Something here</div>
        <div>Something else</div>
    </div>
</body>
</html>

iç içe etiketlere HTML etiketinin adı veya kimliği yoluyla erişmenin bir yolunu vermelidir, böylece temelde bana divetiketin class='container'içindeki etiketi / içeriği bodyveya benzer bir şeyi almasını isteyebilirim .

Firefox'un "Öğeyi incele" özelliğini (HTML'yi görüntüle) kullandıysanız, tüm etiketleri size bir ağaç gibi güzel bir yuvalanmış şekilde verdiğini bilirsiniz.

Yerleşik bir modülü tercih ederim ama bu biraz fazla soruyor olabilir.


Stack Overflow ve internetteki birkaç blog hakkında birçok sorudan geçtim ve çoğu BeautifulSoup veya lxml veya HTMLParser'ı önerdi, ancak bu özelliklerin bir kısmı işlevselliği detaylandırıyor ve sadece daha hızlı / daha verimli olduğu bir tartışma olarak sona eriyor.


2
diğer tüm yanıtlayıcılar gibi, BeautifulSoup'u tavsiye ederim çünkü kırık HTML dosyalarını işlemede gerçekten iyidir.
Pascal Rosin

Yanıtlar:


196

Böylece vücut etiketinde bulunan class = 'container' ile div etiketindeki içeriği / metni almasını isteyebilirim, Veya benzer bir şey.

try: 
    from BeautifulSoup import BeautifulSoup
except ImportError:
    from bs4 import BeautifulSoup
html = #the HTML code you've written above
parsed_html = BeautifulSoup(html)
print(parsed_html.body.find('div', attrs={'class':'container'}).text)

Performans açıklamalarına ihtiyacınız yok sanırım - BeautifulSoup'un nasıl çalıştığını okuyun. Onun bak resmi belgeler .


2
Parsed_html nesnesi tam olarak nedir?
ffledgling

1
parsed_html bir BeautifulSoup nesnesidir, bir DOMElement veya DOMDocument gibi düşünün, ancak "body" gibi "zor" özellikleri vardır. , sadece) kök elemanın gövde elemanı (bizim durumumuzda, html)
Aadaam

18
Sadece bir güncelleme: BeautifulSoup 4'ten itibaren, ithalat hattı şimdifrom bs4 import BeautifulSoup
Bailey Parker

2
Genel bilgi: Performans kritikse, lxmlbunun yerine kütüphaneyi daha iyi kullanın (aşağıdaki cevaba bakınız). İle cssselectoldukça kullanışlı lutfen var ve performans genellikle 10- etmektir mevcut diğer kütüphanelerin daha iyi 100 kat.
Lenar Hoyt

not: classözellik özeldir:BeautifulSoup(html).find('div', 'container').text
jfs

85

Aradığın şey pyquery :

pyquery: python için jquery benzeri bir kütüphane.

İstediğinize bir örnek şöyle olabilir:

from pyquery import PyQuery    
html = # Your HTML CODE
pq = PyQuery(html)
tag = pq('div#id') # or     tag = pq('div.class')
print tag.text()

Ve Firefox veya Chrome'un inceleme öğesiyle aynı seçicileri kullanır. Örneğin:

öğe seçici 'div # mw-head.noprint'

Denetlenen öğe seçici 'div # mw-head.noprint'. Bu yüzden, pırlantada, bu seçiciyi geçmeniz yeterlidir:

pq('div#mw-head.noprint')

2
Bunun için seni 3000 seviyorum!
progyammer

41

Burada Python'daki farklı HTML ayrıştırıcıları ve performansları hakkında daha fazla bilgi edinebilirsiniz. Makale biraz tarihli olmasına rağmen hala size iyi bir genel bakış sunuyor.

Python HTML ayrıştırıcı performansı

Dahili olmasa bile BeautifulSoup'u tavsiye ederim. Bu tür görevler için çalışmak çok kolay olduğu için. Örneğin:

import urllib2
from BeautifulSoup import BeautifulSoup

page = urllib2.urlopen('http://www.google.com/')
soup = BeautifulSoup(page)

x = soup.body.find('div', attrs={'class' : 'container'}).text

2
Performans / verimlilik yerine özellikleri / işlevselliği ayrıntılandıran bir şey arıyordum. EDIT: Olgunlaşmış cevap için üzgünüm, bu bağlantı aslında iyi. Teşekkürler.
ffledgling

İlk nokta listesi türleri özellikleri ve işlevleri özetler :)
Qiau

5
BeautifulSoup4 (en son sürüm) kullanıyorsanız:from bs4 import BeautifulSoup
Franck Dernoncourt

29

Diğer ayrıştırıcı kitaplıklarıyla karşılaştırıldığında lxmloldukça hızlıdır:

Ve cssselectHTML sayfalarını kazımak için kullanımı oldukça kolaydır:

from lxml.html import parse
doc = parse('http://www.google.com').getroot()
for div in doc.cssselect('a'):
    print '%s: %s' % (div.text_content(), div.get('href'))

lxml.html Belgeler


HTTPS desteklenmiyor
Sergio

@Sergio kullanımı import requests, arabelleği dosyaya kaydedin: stackoverflow.com/a/14114741/1518921 (veya urllib), ayrıştırılmış olarak kaydedilen dosyayı yükledikten sonradoc = parse('localfile.html').getroot()
Guilherme Nascimento

Belirli bir veri için büyük HTML'leri ayrıştırıyorum. BeautifulSoup ile yapmak bir 1.7saniye sürdü , ama bunun yerine lxml uygulamak neredeyse *100HIZLI kat kat arttı ! Performansı önemsiyorsanız, lxml en iyi seçenektir
Alex-Bogdanov

9

HTML'yi ayrıştırmak için lxml öneririm . Bkz. "HTML'yi Ayrıştırma" (lxml sitesinde).

Benim tecrübelerime göre, Güzel Çorba bazı karmaşık HTML ile uğraşır. İnanıyorum ki Güzel Çorba ayrıştırıcı değil, çok iyi bir string analizörü.


3
AIUI Güzel Çorba çoğu "arka uç" XML ayrıştırıcısı ile çalışmak için yapılabilir, lxml desteklenen ayrıştırıcılardan biri gibi görünüyor crummy.com/software/BeautifulSoup/bs4/doc/#instal-a-parser
ffledgling

@Fledgling BeautifulSoup'un bazı işlevleri oldukça durgun.
Lenar Hoyt

2

Justext kitaplığını kullanmanızı öneririm :

https://github.com/miso-belica/jusText

Kullanım: Python2:

import requests
import justext

response = requests.get("http://planet.python.org/")
paragraphs = justext.justext(response.content, justext.get_stoplist("English"))
for paragraph in paragraphs:
    print paragraph.text

Python3:

import requests
import justext

response = requests.get("http://bbc.com/")
paragraphs = justext.justext(response.content, justext.get_stoplist("English"))
for paragraph in paragraphs:
    print (paragraph.text)

0

EHP kullanırdım

https://github.com/iogf/ehp

İşte burada:

from ehp import *

doc = '''<html>
<head>Heading</head>
<body attr1='val1'>
    <div class='container'>
        <div id='class'>Something here</div>
        <div>Something else</div>
    </div>
</body>
</html>
'''

html = Html()
dom = html.feed(doc)
for ind in dom.find('div', ('class', 'container')):
    print ind.text()

Çıktı:

Something here
Something else

5
Lütfen açıkla. Popüler BeautifulSoup veya lxml üzerinde EHP'yi ne kullanırsınız?
ChaimG
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.