2010-05-20 4 views
0

Я это:Python: найти <title>

response = urllib2.urlopen(url) 
html  = response.read() 

begin = html.find('<title>') 
end = html.find('</title>',begin) 
title = html[begin+len('<title>'):end].strip() 

если URL = http://www.google.com то название не проблема, как "Google",

но если URL = "http://www.britishcouncil.org/learning-english-gateway", то название стало

"<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML> 
<HEAD> 
<base href="http://www.britishcouncil.org/" /> 
<META http-equiv="Content-Type" Content="text/html;charset=utf-8"> 
<meta name="WT.sp" content="Learning;Home Page Smart View" /> 
<meta name="WT.cg_n" content="Learn English Gateway" /> 
<META NAME="DCS.dcsuri" CONTENT="/learning-english-gateway.htm">..." 

Что на самом деле происходит, почему я не смог вернуть «название»?

ответ

7

Этот URL-адрес возвращает документ с <TITLE>...</TITLE> и find чувствителен к регистру. Я настоятельно рекомендую вам использовать HTML-парсер, например Beautiful Soup.

2

Давайте проанализируем, почему мы получили этот ответ. Если вы откроете веб-сайт и просмотрите источник, отметим, что он не имеет <title>...</title>. Вместо этого у нас есть <TITLE>...</TITLE>. Так что случилось с 2 находками? Оба будут -1!

begin = html.find('<title>') # Result: -1 
end = html.find('</title>') # Result: -1 

Тогда begin+len('<title>') будет -1 + 7 = 6. Таким образом, ваша последняя строка будет извлекая html[6:-1]. Оказывается, отрицательные индексы фактически означают что-то законное в Python (по уважительным причинам). Это означает считать со спины. Следовательно, здесь -1 относится к последнему символу в html. Так что вы получаете подстроку от 6-го символа (включительно) до последнего символа (эксклюзивного).

Что мы можем сделать тогда? Ну, во-первых, вы можете использовать регулярные выражения, которые игнорируют регистр или используют правильный парсер HTML. Если это разовый вещь и пространство/производительность не большая проблема, быстрый подход может создать копию html и в нижнем регистре всю строку:

def get_title(html): 
    html_lowered = html.lower(); 
    begin = html_lowered.find('<title>') 
    end = html_lowered.find('</title>') 
    if begin == -1 or end == -1: 
     return None 
    else: 
     # Find in the original html 
     return html[begin+len('<title>'):end].strip() 
0

Рабочий раствор с LXML и urllib с использованием Python 3

import lxml.etree, urllib.request 

def documenttitle(url): 
    conn = urllib.request.urlopen(url) 
    parser = lxml.etree.HTMLParser(encoding = "utf-8") 
    tree = lxml.etree.parse(conn, parser = parser) 
    return tree.find('.//title') 
Смежные вопросы