Top

Beautiful Soup

Eine Bibliothek um Daten aus HTML und auch XML abzufragen.

$ pip install beautifulsoup4

Das Objekt macht aus einem String eine Struktur, die abgefragt werden kann.

>>> from bs4 import BeautifulSoup
>>> content = '<h1>Head</h1><p id="first">Paragraph1</p><p class="second">Paragraph2</p>'
>>> soup = BeautifulSoup(content, "lxml")

Es wird der Standard HTML Parser unterstützt und weitere die aber zusätzlich installiert werden müssen.
Hier wird der lxml Parser verwendet.

Die Struktur kann auf verschiedene Arten abgefragt werden.

>>> soup.body
<body><h1>Head</h1><p>Paragraph1</p><p class="second">Paragraph2</p></body>
>>> soup.h1
<h1>Head</h1>
>>> soup.prettify()

Für komplexere Abfragen nutzt man find oder findAll.

>>> soup.find('p', attrs={'class': 'second'})
[<p class="second">Paragraph2</p>]
>>> soup.find(‘h1’, attrs={'class': 'headline'})
[]
>>> soup.findAll('p')
[<p id="first">Paragraph1</p>, <p class="second">Paragraph2</p>]
>>> p = soup.findAll('p')
>>> p[0].text
u'Paragraph1'
>>> p[0].name
'p'
>>> soup.findAll(["h1", "p"])
[<h1>Head</h1>, <p>Paragraph1</p>, <p class="second">Paragraph2</p>]

Es gibt auch eine Menge an Methoden und Attributen sowie Keywords.

>>> soup.text
u'HeadParagraph1Paragraph2'
>>> soup.getText()
u'HeadParagraph1Paragraph2'
>>> soup.get_text()
u'HeadParagraph1Paragraph2'
>>> soup.find_all('p')
[<p>Paragraph1</p>, <p class="second">Paragraph2</p>]
>>> soup.find_all(id=True)
[]

Die findAll Methode versteht auch Funktionen als Argument.

>>> def class_without_id(tag):
...     return tag.has_attr('class') and not tag.has_attr('id')
...
>>> soup.findAll(class_without_id)
[<p class="second">Paragraph2</p>]

Beispiele

Eine Funktion um Links die mit http:// beginnen von einer Seite zu sammeln.

import urllib2
from bs4 import BeautifulSoup

def find_links(url):
    link_list = []
    content = urllib2.urlopen(url).read()
    soup = BeautifulSoup(content, "lxml")
    links = soup.findAll('a')
    for link in links:
        href = link.get('href')
        if href[0:7] == "http://":
            link_list.append(href)
    return link_list

Zwei Funktionen um Bilder auf einer Seite zu finden und dann herunterzuladen.

import urllib2
from os.path import basename
from urlparse import urlsplit
from bs4 import BeautifulSoup

def find_images(url):
    content = urllib2.urlopen(url).read()
    soup = BeautifulSoup(content, "lxml")
    images = soup.findAll('img')
    return images

def download_image(image):
    try:
        img_src = image['src']
        content = urllib2.urlopen(img_src).read()
        filename = basename(urlsplit(img_src)[2])
        file = open(filename, 'wb')
        file.write(content)
        file.close()
        return filename
    except:
        return ''