Python:找到<title> </title>

时间:2010-05-20 10:02:16

标签: python html string

我有这个:

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

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

如果网址为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">..."

实际发生了什么,为什么我无法返回“标题”?

3 个答案:

答案 0 :(得分:7)

该网址返回的文档包含<TITLE>...</TITLE>find区分大小写。我强烈建议您使用像Beautiful Soup这样的HTML解析器。

答案 1 :(得分: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()

答案 2 :(得分:0)

使用Python 3的lxml和urllib工作解决方案

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')