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 ''