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
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
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)
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'
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')
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
deferror_callback(*_, **__):passdefis_string(data):return isinstance(data, str)
defis_bytes(data):return isinstance(data, bytes)
defto_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
classParser(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:
returnexcept urllib.error.URLError:
returnexcept ValueError:
return
self.rec = False
self.error = error_callback
defhandle_starttag(self, tag, attrs):if tag == 'title':
self.rec = Truedefhandle_data(self, data):if self.rec:
self.title = data
defhandle_endtag(self, tag):if tag == 'title':
self.rec = Falsedefget_title(url):return Parser(url).title
print(get_title('http://www.google.com'))
Antworten:
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
quelle
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
quelle
urlllib.request
stattdessen verwendenurllib2
. Nicht sicher warum. Um die BeautifulSoup-Warnung über meinen Parser zu vermeiden, musste ich dies tunsoup = BeautifulSoup(urllib.request.urlopen(url), "lxml")
.import urllib.request as urllib
anstelle vonimport urllib2
<title></title>
soup.title.string
None
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()
quelle
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'
quelle
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()
quelle
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)
quelle
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
quelle
r=urlopen(url)
,encoding = r.info().get_content_charset()
undhtml_string = r.read().decode(encoding)
.Reguläre Ausdrücke verwenden
import re match = re.search('<title>(.*?)</title>', raw_html) title = match.group(1) if match else 'No title'
quelle
group(0)
würde das gesamte Spiel zurückgeben. Siehe Match-Objekte als Referenz.soup.title.string
Gibt tatsächlich eine Unicode-Zeichenfolge zurück. Um dies in eine normale Zeichenfolge umzuwandeln, müssen Sie dies tunstring=string.encode('ascii','ignore')
quelle
encode
gibt) und keine Zeichenfolge wollen, codieren Sie mit der richtigencharset
. zB ,string.encode('utf-8')
.Hier ist eine fehlertolerante
HTMLParser
Implementierung.Sie können so ziemlich alles darauf werfen,
get_title()
ohne dass es kaputt geht. Wenn etwas Unerwartetes passiert,get_title()
wird es zurückkehrenNone
.Wenn
Parser()
die Seite heruntergeladen wird, wird sieASCII
unabhängig vom auf der Seite verwendeten Zeichensatz codiert, wobei Fehler ignoriert werden. Es wäre trivial zu ändernto_ascii()
, um die Daten inUTF-8
oder eine andere Codierung zu konvertieren . Fügen Sie einfach ein Codierungsargument hinzu und benennen Sie die Funktion in etwas umto_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 dieHTMLParser()
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'))
quelle
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
quelle