Wie kann ich mit Python den Seitentitel einer Webseite abrufen?

78

Wie kann ich mit Python den Seitentitel einer Webseite (title html tag) abrufen?

cschol
quelle
Seit diese Frage gestellt wurde, verwenden viele Webseiten ein og: title-Meta-Tag, das den Originaltitel enthält, während <title> häufig anderen Daten vorangestellt und mit einem Suffix versehen wird. Ursprünglich nur von Facebook als Teil von OpenGraph verwendet, stellen viele Websites OpenGraph-Metadaten bereit. og: title ist zur Standardquelle für den Titel einer Seite geworden, insbesondere für Nachrichtenartikel.
Nicolas

Antworten:

64

Ich werde immer lxml für solche Aufgaben verwenden. Sie könnten auch schöne Suppe verwenden.

import lxml.html
t = lxml.html.parse(url)
print t.find(".//title").text

BEARBEITEN basierend auf Kommentar:

from urllib2 import urlopen
from lxml.html import parse

url = "https://www.google.com"
page = urlopen(url)
p = parse(page)
print p.find(".//title").text
Peter Hoffmann
quelle
5
Nur für den Fall, dass Sie IOError mit dem obigen Code erhalten: stackoverflow.com/questions/3116269/…
Yosh
91

Hier ist eine vereinfachte Version der Antwort von @Vinko Vrsalovic :

import urllib2
from BeautifulSoup import BeautifulSoup

soup = BeautifulSoup(urllib2.urlopen("https://www.google.com"))
print soup.title.string

HINWEIS:

  • soup.title findet das erste Titelelement überall im HTML - Dokument

  • title.string geht davon aus, dass es nur einen untergeordneten Knoten gibt und dieser untergeordnete Knoten eine Zeichenfolge ist

Verwenden Sie für beautifulsoup 4.x einen anderen Import:

from bs4 import BeautifulSoup
jfs
quelle
7
Vielen Dank! Falls jemand auf ähnliche Probleme stößt, musste ich in meiner Python3-Umgebung urlllib.requeststattdessen verwenden urllib2. Nicht sicher warum. Um die BeautifulSoup-Warnung über meinen Parser zu vermeiden, musste ich dies tun soup = BeautifulSoup(urllib.request.urlopen(url), "lxml").
Sudo
Für Python 3 import urllib.request as urllibanstelle vonimport urllib2
blueray
<title></title>soup.title.stringNone
Beachten
14

Das mechanize Browser-Objekt verfügt über eine title () -Methode. Der Code aus diesem Beitrag kann also wie folgt umgeschrieben werden:

from mechanize import Browser
br = Browser()
br.open("http://www.google.com/")
print br.title()
Codeape
quelle
13

Keine Notwendigkeit, andere Bibliotheken zu importieren. In Request ist diese Funktionalität integriert.

>> hearders = {'headers':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0'}
>>> n = requests.get('http://www.imdb.com/title/tt0108778/', headers=hearders)
>>> al = n.text
>>> al[al.find('<title>') + 7 : al.find('</title>')]
u'Friends (TV Series 1994\u20132004) - IMDb' 
Rahul Chawla
quelle
11

Dies ist wahrscheinlich ein Overkill für eine so einfache Aufgabe, aber wenn Sie mehr als das tun möchten, ist es sinnvoller, von diesen Tools (mechanisieren, BeautifulSoup) auszugehen, da sie viel einfacher zu verwenden sind als die Alternativen (urllib, um Inhalte und Regexen zu erhalten) oder ein anderer Parser zum Parsen von HTML)

Links: BeautifulSoup mechanisieren

#!/usr/bin/env python
#coding:utf-8

from BeautifulSoup import BeautifulSoup
from mechanize import Browser

#This retrieves the webpage content
br = Browser()
res = br.open("https://www.google.com/")
data = res.get_data() 

#This parses the content
soup = BeautifulSoup(data)
title = soup.find('title')

#This outputs the content :)
print title.renderContents()
Vinko Vrsalovic
quelle
6

Verwenden Sieoup.select_one, um das Titel-Tag als Ziel festzulegen

import requests
from bs4 import BeautifulSoup as bs

r = requests.get('url')
soup = bs(r.content, 'lxml')
print(soup.select_one('title').text)
QHarr
quelle
6

Verwenden von HTMLParser :

from urllib.request import urlopen
from html.parser import HTMLParser


class TitleParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.match = False
        self.title = ''

    def handle_starttag(self, tag, attributes):
        self.match = tag == 'title'

    def handle_data(self, data):
        if self.match:
            self.title = data
            self.match = False

url = "http://example.com/"
html_string = str(urlopen(url).read())

parser = TitleParser()
parser.feed(html_string)
print(parser.title)  # prints: Example Domain
Finn
quelle
Es ist erwähnenswert, dass dieses Skript für Python 3 ist. Das HtmlParser-Modul wurde in Python 3.x in html.parser umbenannt. In ähnlicher Weise wurde urllib.request in Python 3 hinzugefügt.
satishgoda
1
Es ist wahrscheinlich besser, explizit zu wandeln die Bytes in einen String r=urlopen(url), encoding = r.info().get_content_charset()und html_string = r.read().decode(encoding).
Reubano
4

Reguläre Ausdrücke verwenden

import re
match = re.search('<title>(.*?)</title>', raw_html)
title = match.group(1) if match else 'No title'
Finn
quelle
Was eigentlich .group (1)? Irgendeine Referenz?
pije76
Hallo, group(0)würde das gesamte Spiel zurückgeben. Siehe Match-Objekte als Referenz.
Finn
1
Dies wird alle Fälle übersehen, in denen die Titel-Tags nicht genau als <title> </ title> (Großbuchstaben, Groß- und Kleinschreibung, Abstand) gebildet werden
Luke Rehmann
Ich würde auch <title. *?> Einschließen, falls das title-Tag andere Daten enthält.
Pranav Wadhwa
1

soup.title.stringGibt tatsächlich eine Unicode-Zeichenfolge zurück. Um dies in eine normale Zeichenfolge umzuwandeln, müssen Sie dies tun string=string.encode('ascii','ignore')

Sai Kiriti Badam
quelle
Dadurch werden nur alle Nicht-ASCII-Zeichen entfernt, die wahrscheinlich nicht Ihren Wünschen entsprechen. Wenn Sie wirklich Bytes (was encodegibt) und keine Zeichenfolge wollen, codieren Sie mit der richtigen charset. zB , string.encode('utf-8').
Reubano
1

Hier ist eine fehlertolerante HTMLParserImplementierung.
Sie können so ziemlich alles darauf werfen, get_title()ohne dass es kaputt geht. Wenn etwas Unerwartetes passiert, get_title()wird es zurückkehren None.
Wenn Parser()die Seite heruntergeladen wird, wird sie ASCII unabhängig vom auf der Seite verwendeten Zeichensatz codiert, wobei Fehler ignoriert werden. Es wäre trivial zu ändern to_ascii(), um die Daten in UTF-8oder eine andere Codierung zu konvertieren . Fügen Sie einfach ein Codierungsargument hinzu und benennen Sie die Funktion in etwas um to_encoding().
Standardmäßig HTMLParser()wird bei defektem HTML-Code sogar bei trivialen Dingen wie nicht übereinstimmenden Tags ein Fehler auftreten. Um dieses Verhalten zu verhindern, habe ich die HTMLParser()Fehlermethode durch eine Funktion ersetzt, die die Fehler ignoriert.

#-*-coding:utf8;-*-
#qpy:3
#qpy:console

''' 
Extract the title from a web page using
the standard lib.
'''

from html.parser import HTMLParser
from urllib.request import urlopen
import urllib

def error_callback(*_, **__):
    pass

def is_string(data):
    return isinstance(data, str)

def is_bytes(data):
    return isinstance(data, bytes)

def to_ascii(data):
    if is_string(data):
        data = data.encode('ascii', errors='ignore')
    elif is_bytes(data):
        data = data.decode('ascii', errors='ignore')
    else:
        data = str(data).encode('ascii', errors='ignore')
    return data


class Parser(HTMLParser):
    def __init__(self, url):
        self.title = None
        self.rec = False
        HTMLParser.__init__(self)
        try:
            self.feed(to_ascii(urlopen(url).read()))
        except urllib.error.HTTPError:
            return
        except urllib.error.URLError:
            return
        except ValueError:
            return

        self.rec = False
        self.error = error_callback

    def handle_starttag(self, tag, attrs):
        if tag == 'title':
            self.rec = True

    def handle_data(self, data):
        if self.rec:
            self.title = data

    def handle_endtag(self, tag):
        if tag == 'title':
            self.rec = False


def get_title(url):
    return Parser(url).title

print(get_title('http://www.google.com'))
Ricky Wilson
quelle
0

Verwenden von lxml ...

Abrufen von Seiten-Metas, die gemäß dem Facebook-Opengraph-Protokoll markiert sind:

import lxml.html.parse
html_doc = lxml.html.parse(some_url)

t = html_doc.xpath('//meta[@property="og:title"]/@content')[0]

oder mit .xpath mit lxml:

t = html_doc.xpath(".//title")[0].text
Markierung
quelle