Beautifulsoup oder lxml.html?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
addi
User
Beiträge: 28
Registriert: Donnerstag 29. März 2018, 22:54

Hallo Leute, ich versuche mich gerade an einen Scraper. Naja jedenfalls "läuft" er und macht was er soll. Ich habe ihn mit BeautifulSoup realisiert. Jedoch stelle ich mir die Frage ob lxml.html nicht geeigneter wären? (Besonders weil man lxml nicht zusätzlich installieren muss)

Dazu noch, wäre es nich sinnvoller, wenn ich folgendes Programm in einer Klasse zusammenfasse?

Code: Alles auswählen

#-*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import time
import re

start_time = time.time()

def soup(link):
	data = requests.get(link).content
	datasoup = BeautifulSoup(data, "html5lib")
	onesite = datasoup.find('a', {'class': 'article-toc__onesie'})
	if onesite != None:
		data = requests.get(f"{link}/komplettansicht").content
		datasoup = BeautifulSoup(data, "html5lib")
	return datasoup

def artikel(datasoup):
	artikelraw = []
	text = datasoup.findAll( "p", { "class": "paragraph article__item" })
	for row in text:
		artikelraw.append(row.text)
	artikeltext = "".join(artikelraw)
	return(artikeltext)

def autor(datasoup):
	text = datasoup.find( "a", { "rel" : "author" })
	if text == None:
		autor= "N/A"
	else:
		autor = text.text.strip()
	return autor

def datum(datasoup):
	text = datasoup.findAll("time")
	datum = []
	for row in text:
		datum.append(row.text)
	return " ".join(datum)

def agents(datasoup):
	text = datasoup.find("span", {"class": "metadata__source"})
	if text != None:
		agent = text.text
	else:
		agent = "None"
	return agent

def kommentare(datasoup):
	text = datasoup.find("a", {"class": "metadata__commentcount js-scroll"})
	kommentare = []
	if text != None:
		kommentare = text.text
		kommentare = re.findall('\d+',kommentare)
	else:
		kommentare.append("FEHLER")
	return kommentare[0]

def keywords(datasoup):
	text = datasoup.find("meta", {"name": "keywords"})
	return text["content"]

def beschreibung(datasoup):
	text = datasoup.find("meta", {"name": "description"})
	return text["content"]

def title(datasoup):
	text = datasoup.find(property = "og:title").get("content")
	return text

datasoup = soup("https://www.zeit.de/wissen/2018-07/selbsterkenntnis-psychologie-forschung")

artikel = artikel(datasoup)
autor = autor(datasoup)
datum = datum(datasoup)
agent = agents(datasoup)
kommentare = kommentare(datasoup)
keywords = keywords(datasoup)
beschreibung = beschreibung(datasoup)
title = title(datasoup)
print(f"""
Titel: {title}

Autor: {autor}
Datum: {datum}
Kommentare: {kommentare}
Agentur: {agent}

Beschreibung: {beschreibung}

Artikel: {artikel}
Keywords: {keywords}
""")
print(time.time() - start_time)
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@addi: `lxml` ist eine externes Package, das *muss* man extra installieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

Ich arbeite nur mit bs4 und html5lib (wie du anscheinend auch) und komme damit gut zurecht.

Du hast gesehen, dass man lxml auch mittels bs4 nutzen kann?

https://www.crummy.com/software/Beautif ... g-a-parser

Du könntest es m. E. also "einfach" mal testen, wenn du dir in Sachen Performance unsicher bist.

Zusammenfassen in einer Klasse: ja, würde ich machen, allerdings binde ich in so einem Fall wie oben die Funktionen nur an die Methoden der Klasse, weil ich ja später vielleicht die Funktionalität auch für eine andere Klasse nutzen muss und (!) die Funktionen so leichter testen kann, als wenn ich noch die Klasse daran hängen hätte. Das ist aber meine Lösung und möglicherweise nicht state of the art.
addi
User
Beiträge: 28
Registriert: Donnerstag 29. März 2018, 22:54

__blackjack__ hat geschrieben: Sonntag 22. Juli 2018, 16:05 @addi: `lxml` ist eine externes Package, das *muss* man extra installieren.
Achso danke, ich habe gedacht, es wäre schon dabei.

@pixewakb
Könntest du das eventuell näher erläutern?
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

addi hat geschrieben: Montag 23. Juli 2018, 13:28 @pixewakb
Könntest du das eventuell näher erläutern?
Ich habe das selbst bislang nicht genutzt, aber laut docs kannst du anstelle von html5lib auch lxml nutzen, wenn du es auf dem Computer installiert hast. Schau dazu in den Beitrag von BlackJack. Das sagt die von mir verlinkte Dokumentation. Wenn du das so machst, dann kannst du deinen Quellcode lassen (solltest du ... lassen können) und musst nur den Parser ändern.
Antworten