Wie kann ich die Links einer Webseite abrufen und die URL-Adresse der Links mit Python kopieren?
141
Wie kann ich die Links einer Webseite abrufen und die URL-Adresse der Links mit Python kopieren?
Hier ist ein kurzer Ausschnitt aus der SoupStrainer-Klasse in BeautifulSoup:
import httplib2
from bs4 import BeautifulSoup, SoupStrainer
http = httplib2.Http()
status, response = http.request('http://www.nytimes.com')
for link in BeautifulSoup(response, parse_only=SoupStrainer('a')):
if link.has_attr('href'):
print(link['href'])
Die BeautifulSoup-Dokumentation ist eigentlich recht gut und deckt eine Reihe typischer Szenarien ab:
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
Bearbeiten: Beachten Sie, dass ich die SoupStrainer-Klasse verwendet habe, weil sie etwas effizienter ist (Speicher und Geschwindigkeit), wenn Sie im Voraus wissen, was Sie analysieren.
/usr/local/lib/python2.7/site-packages/bs4/__init__.py:128: UserWarning: The "parseOnlyThese" argument to the BeautifulSoup constructor has been renamed to "parse_only."
has_attr
. Stattdessen sehe ich, dass es etwas gibt, das heißthas_key
und es funktioniert.Der Vollständigkeit halber die BeautifulSoup 4-Version, die auch die vom Server bereitgestellte Codierung verwendet:
oder die Python 2-Version:
und eine Version mit der
requests
Bibliothek , die wie geschrieben sowohl in Python 2 als auch in Python 3 funktioniert:Der
soup.find_all('a', href=True)
Aufruf findet alle<a>
Elemente, die einhref
Attribut haben. Elemente ohne das Attribut werden übersprungen.BeautifulSoup 3 hat die Entwicklung im März 2012 eingestellt. Neue Projekte sollten wirklich immer BeautifulSoup 4 verwenden.
Beachten Sie, dass Sie den HTML-Code von Bytes in BeautifulSoup dekodieren sollten . Sie können BeautifulSoup über den Zeichensatz informieren, der in den HTTP-Antwortheadern enthalten ist, um die Dekodierung zu unterstützen. Dies kann jedoch falsch sein und mit
<meta>
den im HTML selbst enthaltenen Headerinformationen in Konflikt stehen. Aus diesem Grund wird die interne Klassenmethode BeautifulSoup verwendetEncodingDetector.find_declared_encoding()
, um dies sicherzustellen Solche eingebetteten Codierungshinweise überzeugen einen falsch konfigurierten Server.Bei
requests
ist dasresponse.encoding
Attribut standardmäßig Latin-1, wenn die Antwort einentext/*
Mimetyp hat, auch wenn kein Zeichensatz zurückgegeben wurde. Dies stimmt mit den HTTP-RFCs überein, ist jedoch bei der HTML-Analyse schmerzhaft. Daher sollten Sie dieses Attribut ignorieren, wenncharset
im Content-Type-Header no festgelegt ist.quelle
SoupStrainer
meinst du? Es ging nirgendwo hin, es ist immer noch Teil des Projekts .Andere haben BeautifulSoup empfohlen, aber es ist viel besser, lxml zu verwenden . Trotz seines Namens dient es auch zum Parsen und Scraping von HTML. Es ist viel, viel schneller als BeautifulSoup und es handhabt sogar "kaputtes" HTML besser als BeautifulSoup (ihr Anspruch auf Ruhm). Es hat auch eine Kompatibilitäts-API für BeautifulSoup, wenn Sie die lxml-API nicht lernen möchten.
Ian Blicking stimmt zu .
Es gibt keinen Grund mehr, BeautifulSoup zu verwenden, es sei denn, Sie verwenden Google App Engine oder etwas, bei dem etwas, das nicht nur Python ist, nicht zulässig ist.
lxml.html unterstützt auch CSS3-Selektoren, so dass solche Dinge trivial sind.
Ein Beispiel mit lxml und xpath würde folgendermaßen aussehen:
quelle
lxml
bei Installation als Standardparser verwendet.quelle
Der folgende Code dient zum Abrufen aller auf einer Webseite verfügbaren Links mit
urllib2
undBeautifulSoup4
:quelle
Unter der Haube verwendet BeautifulSoup jetzt lxml. Anfragen, lxml & Listenverständnis machen eine Killer-Combo.
In der Liste comp ist das "if '//' und 'url.com' not in x" eine einfache Methode, um die URL-Liste der 'internen' Navigations-URLs der Websites usw. zu bereinigen.
quelle
Nur um die Links zu erhalten, ohne B.soup und Regex:
Für komplexere Operationen wird BSoup natürlich immer noch bevorzugt.
quelle
<a
undhref
? Sagen Sierel="nofollow"
oderonclick="..."
oder nur eine neue Zeile? stackoverflow.com/questions/1732348/…Dieses Skript macht das, wonach Sie suchen, löst aber auch die relativen Links zu absoluten Links auf.
quelle
Um alle Links zu finden, verwenden wir in diesem Beispiel das Modul urllib2 zusammen mit dem Modul re.module. * Eine der leistungsstärksten Funktionen im Modul re ist "re.findall ()". Während re.search () verwendet wird, um die erste Übereinstimmung für ein Muster zu finden, findet re.findall () alle Übereinstimmungen und gibt sie als Liste von Zeichenfolgen zurück, wobei jede Zeichenfolge eine Übereinstimmung darstellt *
quelle
Warum nicht reguläre Ausdrücke verwenden:
quelle
(r"<a.*?\s*href=\"(.*?)\".*?>(.*?)</a>", page)
bedeutet? Vielen Dank!Links können sich innerhalb einer Vielzahl von Attributen befinden, sodass Sie eine Liste dieser Attribute zur Auswahl übergeben können
Zum Beispiel mit den Attributen src und href (hier verwende ich den Operator begin with ^, um anzugeben, dass einer dieser Attributwerte mit http beginnt. Sie können dies nach Bedarf anpassen
Attribut = Wertauswahl
quelle
Hier ist ein Beispiel @ars akzeptierte Antwort mit und
BeautifulSoup4
,requests
undwget
Module die Downloads zu handhaben .quelle
Ich fand die Antwort von @ Blairg23 nach der folgenden Korrektur (die das Szenario abdeckt, in dem es nicht richtig funktioniert hat):
Für Python 3:
urllib.parse.urljoin
muss verwendet werden, um stattdessen die vollständige URL zu erhalten.quelle
Der Parser von BeatifulSoup kann langsam sein. Es ist möglicherweise praktikabler, lxml zu verwenden, das direkt von einer URL aus analysiert werden kann (mit einigen unten genannten Einschränkungen).
Der obige Code gibt die Links so zurück, wie sie sind, und in den meisten Fällen handelt es sich um relative oder absolute Links vom Site-Stammverzeichnis. Da mein Anwendungsfall darin bestand, nur eine bestimmte Art von Links zu extrahieren, finden Sie unten eine Version, die die Links in vollständige URLs konvertiert und optional ein Glob-Muster wie akzeptiert
*.mp3
. Es werden zwar keine einfachen und doppelten Punkte in den relativen Pfaden verarbeitet, aber bisher hatte ich keine Notwendigkeit dafür. Wenn Sie zu parsen URL - Fragmente enthalten../
oder./
dann urlparse.urljoin könnte sich als nützlich.HINWEIS : Das direkte Parsen von lxml-URLs übernimmt nicht das Laden von
https
und leitet keine Weiterleitungen durch. Aus diesem Grund verwendet die folgende Versionurllib2
+lxml
.Die Verwendung ist wie folgt:
quelle
lxml
kann nur gültige Eingaben verarbeiten, wie kann es ersetzenBeautifulSoup
?lxml.html
ist ein bisschen nachsichtiger als dielxml.etree
. Wenn Ihre Eingabe nicht korrekt ist, können Sie den BeautifulSoup-Parser explizit festlegen: lxml.de/elementsoup.html . Und wenn Sie sich für BeatifulSoup entscheiden, ist BS3 die bessere Wahl.quelle
Es kann viele doppelte Links zusammen mit externen und internen Links geben. Um zwischen den beiden zu unterscheiden und nur eindeutige Links mithilfe von Sets zu erhalten:
quelle