精华内容
下载资源
问答
  • Python 字符串匹配、搜索及替换

    千次阅读 2019-12-31 23:11:45
    文章目录字符串匹配、搜索及替换字符串开头或结尾匹配str.startswith() 和 str.endswith()用 Shell 通配符匹配字符串fnmatch() 和 fnmatchcase()字符串匹配和搜索 字符串匹配、搜索及替换 字符串开头或结尾匹配 ...

    字符串匹配、搜索及替换


    在处理字符串中,有时会需要定位字符串,然后对字符串进行相应的处理。

    字符串开头或结尾匹配


    对于字符串的检查,可以通过特定的文本模式进行匹配。在 Python 内置类型中也提供了 str.startswith()str.endswith() 方法对字符串进行开头或结尾的检查。

    str.startswith() 和 str.endswith()

    str.startswith()str.endswith() 是检查字符串开头或结尾的一个简单方法。例如文件的后缀,URL 跳转协议,示例如下:

    >>> filename = "string.txt"
    >>> filename.endswith('.txt')
    True
    >>> filename.startswith('file:')
    False
    >>> url = 'http://www.python.org'
    >>> url.startswith('http:')
    True
    

    如果要检查多种匹配的可能,可以提供一个元组,将所有的匹配项写入元组中,然后传给 startswith()endswith() 方法的第一个参数中:

    >>> import os
    >>> filenames = os.listdir('.')
    >>> filenames
    ['tools', 'list_links.txt', 'access_test.py', 'control_roll.py', 'access.log', 'data.xls']
    >>> [name for name in filenames if name.endswith(('.py', '.txt'))]
    ['list_links.txt', 'access_test.py', 'control_roll.py']
    >>> any(name.endswith('.py') for name in filenames)
    True
    

    这里需要说明的是startswith()endswith() 两个方法的第一个参数,如果是要传入多种匹配选项,需要传入的类型必须是 tuple,如果有 listset 类型的选项,可以使用 tuple() 方法将已有选项进行转换。

    上面提及的 startswith()endswith() 方法有一种替代的方法,就是切片操作,但是代码看起来会相对繁冗。示例如下:

    >>> filename = 'string.txt'
    >>> filename[-4:] == '.txt'
    True
    >>> url = 'http://www.python.org'
    >>> url[:5] == 'http:' or url[:6] == 'https:' or url[:4] == 'ftp:'
    True
    

    还有另外一种方法是通过正则表达式去实现,示例如下:

    >>> import re
    >>> url = 'http://www.python.org'
    >>> re.match('http:|https:|ftp:', url)
    <_sre.SRE_Match object; span=(0, 5), match='http:'>
    

    正则表达式方法放在这里,的确能够解决问题,但是有点大材小用。而且,Python 内置的 startswith()endswith() 方法,对于这种简单匹配运行会更快。

    用 Shell 通配符匹配字符串


    除了通过你内置类型的方法对字符串进行匹配,还可以使用 Unix Shell 中的常用的通配符(比如 *.pyDat[0-9]*.csv 等)去匹配字符串。

    fnmatch() 和 fnmatchcase()

    Python 提供的 fnmatch 模块就有两个函数 fnmatch()fnmatchcase() 可以用来实现这样的匹配。示例如下:

    >>> from fnmatch import fnmatch, fnmatchcase
    >>> fnmatch('string.txt','*.txt')
    True
    >>> fnmatch('string.txt','?ing.txt')
    False
    >>> fnmatch('string.txt','?tring.txt')
    True
    >>> fnmatch('Dat57.csv','Dat[0-9]*')
    True
    >>> names = ['Dat1.csv','Dat2.csv','config.ini','test.py']
    >>> [name for name in names if fnmatch(name, 'Dat*.csv')]
    ['Dat1.csv', 'Dat2.csv']
    

    但是需要注意的是 fnmatch() 函数,在使用不同的底层操作系统的大小写敏感规则是不同的。这里是因为这个函数中的形参都会使用 os.path.normcase() 进行大小写正规化,在 Linux,Mac 中,会原样返回;而在 Windows 中,这里会将字符转换为小写返回。示例如下:

    >>> # On Mac
    >>> fnmatch('string.txt', '*.TXT')
    False
    >>> # On Windows
    >>> fnmatch('string.txt', '*.TXT')
    True
    

    如果对于这个大小写敏感规则很在意的情况下,可以使用 fnmatchcase() 来替代。这个函数完全区分大小写。示例如下:

    >>> fnmatchcase('string.txt', '*TXT')
    False
    

    fnmatch() 函数匹配的能力介于简单字符串方法和正则表达式之间。如果在数据处理操作中,能够用简单通配符匹配的情况下,这是一个可以考虑的方案。

    如果需求中需要做文件名的匹配,建议使用 glob 模块中的方法。具体的使用方法可参考下面的官方文档:

    https://docs.python.org/3.6/library/glob.html

    字符串匹配和搜索


    如果需要匹配的字符串比较简单,通常情况下,需要调用基本字符串方法就可以。

    str.find()

    除了前面介绍的 str.endswith()str.startswith() 的方法,还有 str.find() 方法,这个方法用于查找匹配项第一次出现的位置,这些都能够实现简单的匹配搜索,示例如下:

    >>> text = 'yeah, but no, but yeah, but no, but yeah'
    >>> # 匹配开头或结尾
    ...
    >>> text.startswith('yeah')
    True
    >>> text.endswith('no')
    False
    >>> # 搜索第一次出现位置
    ...
    >>> text.find('no')
    10
    

    正则表达式及 re 模块


    对于一些复杂的匹配,则需要借助正则表达式1re 模块。

    re.match()

    下面举例简单介绍匹配数字格式的日期字符串,示例如下:

    >>> text1 = '11/27/2012'
    >>> text2 = 'Nov 27, 2012'
    >>> import re
    >>> # 简单匹配一个或多个数字
    ...
    >>> if re.match(r'\d+/\d+/\d+', text1):
    ...     print('yes')
    ... else:
    ...     print('no')
    ...
    yes
    >>> if re.match(r'\d+/\d+/\d+', text2):
    ...     print('yes')
    ... else:
    ...     print('no')
    ...
    no
    >>>
    

    re.compile()

    如果需要使用同个模式进行多次匹配,那么可以考虑将模式字符串编译为模式对象。re.compile() 提供编译正则表达式字符串,示例如下:

    >>> pattern = re.compile(r'\d+/\d+/\d+')
    >>> if re.match(pattern, text1):
    ...     print('yes')
    ... else:
    ...     print('no')
    ...
    yes
    >>> if re.match(pattern, text2):
    ...     print('yes')
    ... else:
    ...     print('no')
    ...
    no
    

    re.findall()

    match() 方法总是从字符串开始去匹配,如果查找字符串任意部分出现的位置,建议使用 findall() 方法代替。示例如下:

    >>> text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
    >>> pattern = r'\d+/\d+/\d+'
    >>> re.findall(pattern, text)
    ['11/27/2012', '3/13/2013']
    >>>
    

    有时候定义正则表达式的时候,会利用括号进行捕获分组。示例如下:

    >>> pattern = re.compile(r'(\d+)/(\d+)/(\d+)')
    >>>
    

    捕获分组的用处主要是用于将每个组的内容提取出来,也对后续的处理进行备用。示例如下:

    >>> import re
    >>> pattern = re.compile(r'(\d+)/(\d+)/(\d+)')
    >>> match_data = re.match(pattern,'11/27/2012')
    >>> match_data
    <_sre.SRE_Match object; span=(0, 10), match='11/27/2012'>
    >>> match_data.group(0)
    '11/27/2012'
    >>> match_data.group(1)
    '11'
    >>> match_data.group(2)
    '27'
    >>> match_data.group(3)
    '2012'
    >>> match_data.groups()
    ('11', '27', '2012')
    >>> month, day, year = match_data.groups()
    >>> text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
    >>> # 使用 findall(),注意返回的结果是列表里面包裹元组
    ... re.findall(pattern, text)
    [('11', '27', '2012'), ('3', '13', '2013')]
    >>> for month, day, year in re.findall(pattern, text):
    ...     print('{}-{}-{}'.format(year, month, day))
    ...
    2012-11-27
    2013-3-13
    

    re.finditer()

    findall() 方法会以搜索文本并以列表形式返回所有的匹配。如果想以迭代的方式返回匹配,可以考虑使用 re.finditer() 方法代替。

    re.finditer() 方法返回一个迭代器,方法是从左到右扫描字符串,按照找到匹配项的顺序返回,示例如下:

    >>> for match_data in re.finditer(pattern, text):
    ...     print(match_data.groups())
    ...
    ('11', '27', '2012')
    ('3', '13', '2013')
    

    综合上述,re 模块进行匹配和搜索文本,核心的步骤是先使用 re.compile() 将正则表达式字符串进行编译,然后根据需求使用 match()findall() 或者 finditer() 方法。

    一些建议: 编写正则表达式字符串的时候,通常会是 r'' 这种形式,这种使用原始字符串的做法,能够不用去解析反斜杠。如果不这样做的话,需要使用两个反斜杠,例如:(\\d+/\\d+/\\d+)

    注意事项: match() 方法仅仅检查字符串的开始部分, 匹配的结果可能并非期望的结果。示例如下:

    >>> pattern = re.compile(r'(\d+)/(\d+)/(\d+)')
    >>> match_data = re.match(pattern, '11/27/2012abcdef')
    >>> match_data
    <_sre.SRE_Match object; span=(0, 10), match='11/27/2012'>
    >>> match_data.group()
    '11/27/2012'
    

    如果需要精确匹配,得在正则表达式以 $ 结尾,如下示例:

    >>> pattern = re.compile(r'(\d+)/(\d+)/(\d+)$')
    >>> re.match(pattern, '11/27/2012abcdef')
    >>> re.match(pattern, '11/27/2012')
    <_sre.SRE_Match object; span=(0, 10), match='11/27/2012'>
    >>>
    

    上面的代码并未匹配 11/27/2012abcdef,因为编译的正则表达式以 $ 结尾,说明必须精确匹配才会返回结果。

    如果仅仅是做一次简单的文本匹配/搜索操作的话,可以略过编译部分,但是,需要进行大量的匹配和搜索操作的话,最好先对正则表达式字符串进行编译,然后再重复使用。这样做的原因是不会消耗太多的性能 。

    字符串搜索和替换


    对于字符串的搜索时,有时候会对搜索的匹配项进行替换操作。

    str.replace()

    如果是简单的字面模式,可以直接用 str.replace() 方法,示例如下:

    >>> text = 'yeah, but no, but yeah, but no, but yeah'
    >>> text.replace('yeah', 'yep')
    'yep, but no, but yep, but no, but yep'
    >>>
    

    re.sub()

    对于复杂的模式,请使用 re 模块中的 sub() 函数。现在的需求是这样,将形式为 11/27/2012 的日期字符串改为 2012-11-27,下面的是实现的代码:

    >>> text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
    >>> import re
    >>> re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text)
    'Today is 2012-11-27. PyCon starts 2013-3-13.'
    

    sub() 函数中,第一个参数表示的是被匹配的模式,第二个参数表示的是替换模式。反斜杠数字,比如 \3 指向的是前面模式捕获分组的组号。

    如果打算用相同的模式做多次替换,同样可以考虑先编译再重复使用。

    re.subn()

    如果除了替换后的结果外,还需要知道进行了多少次替换,可以使用 re.subn() 来代替。比如:

    >>> text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
    >>> pattern = re.compile(r'(\d+)/(\d+)/(\d+)')
    >>> newtext, n = re.subn(pattern, r'\3-\1-\2', text)
    >>> newtext
    'Today is 2012-11-27. PyCon starts 2013-3-13.'
    >>> n
    2
    >>>
    

    以上就是本篇的主要内容。


    结语: 新年快乐!


    1. 可参考【正则表达式 笔记整理↩︎

    展开全文
  • 利用Python抓取和解析网页

    千次阅读 2012-03-24 18:38:46
    对搜索引擎、文件索引、文档转换、数据检索、站点备份或...本文将详细介绍如何利用Python抓取和解析网页。首先,我们介绍一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块,然后,我们论述如何使用Python

    对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文将详细介绍如何利用Python抓取和解析网页。首先,我们介绍一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块,然后,我们论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。最后,我们会给出一个规整HTML文件的格式标签的例子,通过这个例子您会发现使用python处理HTML文件的内容是非常简单的一件事情。

      一、解析URL

      通过Python所带的urlparse模块,我们能够轻松地把URL分解成元件,之后,还能将这些元件重新组装成一个URL。当我们处理HTML 文档的时候,这项功能是非常方便的。

     

    Python代码  收藏代码
    1. import urlparse  
    2.   
    3.   parsedTuple = urlparse.urlparse(  
    4.   
    5.   "http://www.google.com/search?  
    6.   
    7.   hl=en&q=urlparse&btnG=Google+Search")  
    8.   
    9.   unparsedURL = urlparse.urlunparse((URLscheme, \  
    10.   
    11.   URLlocation, URLpath, ''''''))  
    12.   
    13.   newURL = urlparse.urljoin(unparsedURL,  
    14.   
    15.   "/module-urllib2/request-objects.html")  

     函数urlparse(urlstring [, default_scheme [, allow_fragments]])的作用是将URL分解成不同的组成部分,它从urlstring中取得URL,并返回元组 (scheme, netloc, path, parameters, query, fragment)。注意,返回的这个元组非常有用,例如可以用来确定网络协议(HTTP、FTP等等 )、服务器地址、文件路径,等等。

     

      函数urlunparse(tuple)的作用是将URL的组件装配成一个URL,它接收元组(scheme, netloc, path, parameters, query, fragment)后,会重新组成一个具有正确格式的URL,以便供Python的其他HTML解析模块使用。

      函数urljoin(base, url [, allow_fragments]) 的作用是拼接URL,它以第一个参数作为其基地址,然后与第二个参数中的相对地址相结合组成一个绝对URL地址。函数urljoin在通过为URL基地址附加新的文件名的方式来处理同一位置处的若干文件的时候格外有用。需要注意的是,如果基地址并非以字符/结尾的话,那么URL基地址最右边部分就会被这个相对路径所替换。比如,URL的基地址为Http://www.testpage.com/pub,URL的相对地址为test.html,那么两者将合并成http://www.testpage.com/test.html,而非http://www.testpage.com/pub/test.html。如果希望在该路径中保留末端目录,应确保URL基地址以字符/结尾。

      下面是上面几个函数的详细一点的用法举例:

     

    Python代码  收藏代码
    1. import urlparse  
    2.   
    3.   URLscheme = "http"  
    4.   
    5.   URLlocation = "www.python.org"  
    6.   
    7.   URLpath = "lib/module-urlparse.html"  
    8.   
    9.   modList = ("urllib""urllib2", \  
    10.   
    11.   "httplib""cgilib")  
    12.   
    13.   #将地址解析成组件  
    14.   
    15.   print "用Google搜索python时地址栏中URL的解析结果"  
    16.   
    17.   parsedTuple = urlparse.urlparse(  
    18.   
    19.   "http://www.google.com/search?  
    20.   
    21.   hl=en&q=python&btnG=Google+Search")  
    22.   
    23.   print parsedTuple  
    24.   
    25.   #将组件反解析成URL  
    26.   
    27.   print "\反解析python文档页面的URL"  
    28.   
    29.   unparsedURL = urlparse.urlunparse( \  
    30.   
    31.   (URLscheme, URLlocation, URLpath, ''''''))  
    32.   
    33.   print "\t" + unparsedURL  
    34.   
    35.   #将路径和新文件组成一个新的URL  
    36.   
    37.   print "\n利用拼接方式添加更多python文档页面的URL"  
    38.   
    39.   for mod in modList:  
    40.   
    41.   newURL = urlparse.urljoin(unparsedURL, \  
    42.   
    43.   "module-%s.html" % (mod))  
    44.   
    45.   print "\t" + newURL  
    46.   
    47.   #通过为路径添加一个子路径来组成一个新的URL  
    48.   
    49.   print "\n通过拼接子路径来生成Python文档页面的URL"  
    50.   
    51.   newURL = urlparse.urljoin(unparsedURL,  
    52.   
    53.   "module-urllib2/request-objects.html")  
    54.   
    55.   print "\t" + newURL  

      上述代码的执行结果如下所示:

      用Google搜索python时地址栏中URL的解析结果

     

    Python代码  收藏代码
    1. ('http''www.google.com''/search''',  
    2.   
    3.  'hl=en&q=python&btnG=Google+Search''')  
    4.   
    5.  反解析python文档页面的URL  
    6.   
    7.  http://www.python.org/lib/module-urlparse.html  
    8.   
    9.  利用拼接方式添加更多python文档页面的URL  
    10.   
    11.  http://www.python.org/lib/module-urllib.html  
    12.   
    13.  http://www.python.org/lib/module-urllib2.html  
    14.   
    15.  http://www.python.org/lib/module-httplib.html  
    16.   
    17.  http://www.python.org/lib/module-cgilib.html  
    18.   
    19.  通过拼接子路径来生成Python文档页面的URL  
    20.   
    21.  http://www.python.org/lib/module-urllib2/request-objects.html  

     

       二、打开HTML文档

      上面介绍了如何解析页面的URL,现在开始讲解如何通过URL打开一个网页。实际上,Python所带的urllib和urllib2这两个模块为我们提供了从URL打开并获取数据的功能,当然,这包括HTML文档。

     

    Python代码  收藏代码
    1. import urllib  
    2.   
    3.  u = urllib.urlopen(webURL)  
    4.   
    5.  u = urllib.urlopen(localURL)  
    6.   
    7.  buffer = u.read()  
    8.   
    9.  print u.info()  
    10.   
    11.  print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )  

      若要通过urllib模块中的urlopen(url [,data])函数打开一个HTML文档,必须提供该文档的URL地址,包括文件名。函数urlopen不仅可以打开位于远程web服务器上的文件,而且可以打开一个本地文件,并返回一个类似文件的对象,我们可以通过该对象从HTML文档中读出数据。

     

      一旦打开了HTML文档,我们就可以像使用常规文件一样使用read([nbytes])、readline()和readlines()函数来对文件进行读操作。若要读取整个HTML文档的内容的话,您可以使用read()函数,该函数将文件内容作为字符串返回。

      打开一个地址之后,您可以使用geturl()函数取得被获取网页的真正的URL。这是很有用的,因为urlopen(或使用的opener对象)也许会伴随一个重定向。获取的网页URL也许和要求的网页URL不一样。

      另一个常用的函数是位于从urlopen返回的类文件对象中的info()函数,这个函数可以返回URL位置有关的元数据,比如内容长度、内容类型,等等。下面通过一个较为详细的例子来对这些函数进行说明。

     

    Python代码  收藏代码
    1. import urllib  
    2.   
    3.   webURL = "http://www.python.org"  
    4.   
    5.   localURL = "index.html"  
    6.   
    7.   #通过URL打开远程页面  
    8.   
    9.   u = urllib.urlopen(webURL)  
    10.   
    11.   buffer = u.read()  
    12.   
    13.   print u.info()  
    14.   
    15.   print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )  
    16.   
    17.   #通过URL打开本地页面  
    18.   
    19.   u = urllib.urlopen(localURL)  
    20.   
    21.   buffer = u.read()  
    22.   
    23.   print u.info()  
    24.   
    25.   print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )  

      上面代码的运行结果如下所示:

     

    Python代码  收藏代码
    1. Date: Fri, 26 Jun 2009 10:22:11 GMT  
    2.   
    3.  Server: Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_wsgi/2.3 Python/2.5.2  
    4.   
    5.  Last-Modified: Thu, 25 Jun 2009 09:44:54 GMT  
    6.   
    7.  ETag: "105800d-46e7-46d29136f7180"  
    8.   
    9.  Accept-Ranges: bytes  
    10.   
    11.  Content-Length: 18151  
    12.   
    13.  Connection: close  
    14.   
    15.  Content-Type: text/html  
    16.   
    17.  从http://www.python.org读取了18151 字节数据.  
    18.   
    19.  Content-Type: text/html  
    20.   
    21.  Content-Length: 865  
    22.   
    23.  Last-modified: Fri, 26 Jun 2009 10:16:10 GMT  
    24.   
    25.  从index.html读取了865 字节数据.  
     三、小结

      对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文中,我们介绍了一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块。在下篇中,我们将论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。

    展开全文
  • 因为在python字符串被定义为字符的有序集合

    Python索引和分片详解

    [开始:结束]:默认值为序列的开始和结束

    索引值是指到要在那里“切下”


    >>> S[0],S[-2]
    ('s', 'a')
    >>> S = 'spam'
    >>> S[0],S[-2]   #索引
    ('s', 'a')
    >>> S[1:3],S[1:],S[:-1]   #分片
    ('pa', 'pam', 'spa')
    

    因为在python中字符串被定义为字符的有序集合,所以我们能够通过其位置获取元素。Python中字符串中的字符是通过索引提取的,这时候你会获得字符串中在特定位置的一个字符。

    索引(s[i])获取特定偏移的元素:

    ——第一个元素的偏移为0.

    ——负偏移意味着从最后或右边反向进行计数。

    ——S[0]获取第一个元素

    ——S[-2]获取倒数第二个元素(就像S[len(S)-2]一样)

    python的偏移量是从0开始的,并且比字符串长度小1,负偏移量是从结束出反向计数。


    分片:索引的一种通用形式,返回的是字符串的一部分,而不是单个项(能够让我们从整个字符串中提取一部分内容即子字符串)。

    分片运作原理:

    S[i:j]

    ——提取S的一部分作为一个序列。

    ——上边解并不包含在内,j为上边界,i为下边界

    ——分片的边界默认为0和序列的长度(如果没有明确给出)

    ——S[1:3]  获取从偏移为1的元素,直到但不包括偏移为3的元素

    ——S[1:] 获取从偏移为1的元素直到末尾(偏移序列长度)元素

    ——S[:3] 获取从偏移为0的元素直到但不包括偏移为3的元素

    ——S[:-1] 获取从偏移为0的元素直到但不包括最后一个元素之间的元素

    ——S[:] 获取从偏移为0的元素直到末尾的元素,实现了S的拷贝


    扩展分片:第三限制值

    python2.3中,分片表达式增加了一个可选的第三个索引,用作步进(stride),默认值为1.

    >>> S = 'abcdefghijk'
    >>> S[1:8:2]
    'bdfh'
    >>> S[::2]
    'acegik'
    >>> 
    
    完整形式的分片现在变为X[i:j:k],表示索引X对象中的元素,从偏移值i直到偏移值为j-1,每个k元素索引一次。k值默认为1.

    也可以使用负数作步进:

    >>> S = 'hello'
    >>> S[::-1]
    'olleh'
    >>> S[::-2]
    'olh'
    
    -1步进表示分片会从右到左而不是通常的从左到右,实际效果就是实现了字符串的翻转。

    通过一个负数步进,两个边界的意义实际上进行了反转

    也就是说:分片S[5:1:-1]以反的顺序获取从2到5的元素

    >>> S = 'abcdefg'
    >>> S[5:1:-1]
    'fedc'
    
    像这样使用三重限制列表实现跳过或反序输出很常见。

    分片等同于用一个分片对象进行索引:

    >>> 'spam'[1:3]
    'pa'
    >>> 'spam'[slice(1,3)]
    'pa'
    >>> 'spam'[::-1]
    'maps'
    >>> 'spam'[slice(None,None,-1)]
    'maps'
    


     字符串转换工具:

    一个简单的例子:

    在python中不能够让字符串和数字相加,甚至字符串看起来像数字也不可以:

    >>> '42'+1
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: cannot concatenate 'str' and 'int' objects
    >>> int('42')+1
    43
    >>> '42'+str(1)
    '421'
    >>> 
    
    这样设计是有意义的,因为“+”既能够作加法运算也能够进行字符串合并操作,这种转换的选择会变得模棱两可。因此Python会将其作为错误来处理。在上述例子中int函数将字符串转换为数字str函数将数字转换为字符串表达式。类似的内置函数也可以把浮点数转换为字符串,或把字符串转换为浮点数:

    >>> str(3.1415),float('123')
    ('3.1415', 123.0)
    

    字符串代码的转换:

    同样是转换单个字符也可以通过将其传给内置的ord函数转换为对应的ASCII码——这个函数实际上返回的是这个字符在内存中对应字符的二进制值,chr函数将会执行相反的操作,获取ASCLL码将其转换为对应的字符:

    >>> ord('s')
    115
    >>> chr(115)
    's'
    
    可以利用循环完成对字符串内所有字符的函数运算,这些工具也可以用来执行对字符串的数学运算。

    例如:为了生成下一个字符,我们可以将当前字符串转换为整型,并进行如下数学运算:

    >>> S = '5'
    >>> S = chr(ord(S) + 1)
    >>> S
    '6'
    

    修改字符串:

    字符串在Python中具有不可变性——在创建后不能就地改变。就是不能在原地修改字符串。

    >>> S = 'spam'
    >>> S[0]
    's'
    >>> S[0] = 'x'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'str' object does not support item assignment
    

    若要改变一个字符串需要利用合并、分片这样的工具建立并赋值给一个新的字符串,若是有必要的话可以将结果赋值给字符串最初的变量值。 

    >>> H = 'hello'
    >>> H = H + 'HELLO'
    >>> H
    'helloHELLO'
    >>> H = H[:4]+'world'+H[-1]
    >>> H
    'hellworldO'
    
    replace也可以改变字符串:

    >>> S = 'splot'
    >>> S = S.replace('pl','pamal')
    >>> S
    'spamalot'
    

    通过字符串格式化表达式来创建新的文本值:

    >>> 'This is %d %s bird' % (1,'dead')
    'This is 1 dead bird'
    >>> 'This is %d %s bird!' % (1,'dead')
    'This is 1 dead bird!'
    >>> 'That is {0} {1} bird!'.format(1,'dead')
    'That is 1 dead bird!'
    

    上述这两种方式都是把对象替换为字符串,其实是将对象转换为字符串并且根据指定的格式来改变最初的字符串。

    尽管用替换这个词,但是格式化的结果是一个新的字符串对象,而不是修改后的对象。

    字符串方法:

    1、字符串处理空格

    strip是trim掉字符串两边的空格。
    lstrip, trim掉左边的空格
    rstrip, trim掉右边的空格

    >>> line = ' The knights who say hi!\n'
    >>> line
    ' The knights who say hi!\n'
    >>> line.strip()
    'The knights who say hi!'
    >>> line.lstrip()
    'The knights who say hi!\n'
    >>> line.rstrip()
    ' The knights who say hi!'
    

    strip lstrip rstrip使用方法

    Python中的strip用于去除字符串的首位字符,同理,lstrip用于去除左边 的字符,rstrip用于去除右边的字符。这三个函数都可传入一个参数,指定要去除的首尾字符。注意的是,传入的是一个字符数组,编译器去除两端所有相应 的字符,直到没有匹配的字符,比如:
    <span style="font-size:14px;">>>> S = 'saaaay yes no yaaaaaasss'
    >>> S.strip('say')
    ' yes no '
    </span>
    S依次被去除首尾在['s','a','y']数组内的字符,直到字符在不数组内。所以,输出的结果为: 
    yes no 
    比较简单吧,lstrip和rstrip原理是一样的。注意:
    当没有传入参数时,是默认去除首尾空格的。 

    2、修改字符串

    <span style="font-size:14px;">>>> S = 'spammy'
    >>> S = S[:3]+'xx'+S[-1]  #使用分片加索引来修改字符串
    >>> S
    'spaxxy'
    >>> S.replace('xx','mm') #使用内置函数修改replace(old,new)
    'spammy'
    >>> S = 'xxxxSPAMxxxxSPAMxxxx'  #find方法返回子字符串出现的偏移量(默认从前往后搜索,未找到返回-1)
    >>> where = S.find('SPAM')
    >>> where
    4
    >>> S = S[:where]+'EGGS'+S[(where+4):]
    >>> S
    'xxxxEGGSxxxxSPAMxxxx'</span>

    <span style="font-size:14px;">>>> S
    'xxxxEGGSxxxxSPAMxxxx'
    >>> S = 'xxxxSPAMxxxxSPAMxxxx'
    >>> S.replace('SPAM','EGGS')     #注意replace每次返回的是一个新的字符串对象
    'xxxxEGGSxxxxEGGSxxxx'
    >>> S.replace('SPAM','EGGS',1)
    'xxxxEGGSxxxxSPAMxxxx'
    </span>
    为了优化性能需要将字符串转化成一个支持原处修改的对象,内置list函数以任意序列中的元素创立一个新的列表,在这个例子中,list将字符串打散为一个列表,一旦字符串以这样的形式出现,就无需在每次修改之后进行复制就可以对其进行多次修改,修改之后如果需要将其变回一个字符串,可以用字符串方法jion将列表合并成一个字符串

    <span style="font-size:14px;">>>> S = 'SPAM'
    >>> L = list(S)
    >>> L
    ['S', 'P', 'A', 'M']
    >>> L[2],L[3]
    ('A', 'M')
    >>> L[2] = 'a'
    >>> S
    'SPAM'
    >>> L
    ['S', 'P', 'a', 'M']
    >>> S =''.join(L)  #<span style="color:#FF9966;">''空字符串作为分隔符(jion将列表字符串连接在一起并用分隔符分开)</span>
    >>> S
    'SPaM'
    >>> 'SPAM'.join(['eggs','sausage','ham','toast'])<span style="color:#FF9966;">#'SPAM'作为字符串分隔符</span>
    'eggsSPAMsausageSPAMhamSPAMtoast'
    </span>

    3、文本解析:

    <span style="font-size:14px;">>>> line = 'aaa bbb ccc'   #这组数据出现在固定偏移处可以用过分片技术
    >>> line1 = line[:3]
    >>> line2 = line[8:]
    >>> line1,line2
    ('aaa', 'ccc')
    >>> line.split()       #split()方法将字符串分割为一个子字符串的列表,以分隔符为字符串分割标准,没有传递参数时默认分隔符为空格
    ['aaa', 'bbb', 'ccc']
    >>> line = 'bob,hacker,30'
    >>> line.split(',')
    ['bob', 'hacker', '30']
    >>> line = "i'mSPAMaSPAMlumberjack"  #分隔符也可以是字符串
    >>> line.split('SPAM')
    ["i'm", 'a', 'lumberjack']
    </span>

    4、其他的字符串方法:

    字符串中的大小写转换:

    S.lower() #小写 
    S.upper() #大写 
    S.swapcase() #大小写互换 
    S.capitalize() #首字母大写 
    String.capwords(S) #这是模块中的方法。它把S用split()函数分开,然后用capitalize()把首字母变成大写,最后用join()合并到一起

    >>> S = 'Hello'
    >>> S.lower()
    'hello'
    >>> S.upper()
    'HELLO'
    >>> S.swapcase()
    'hELLO'
    >>> S = 'hello'
    >>> S.capitalize()
    'Hello'
    >>> S = 'hello world'
    

    字符串长度

    <span style="font-weight: normal;">>>> S = 'hello world'
    >>> len(S)</span>
    

    追加指定长度的字符串、

    <span style="font-weight: normal;">>>> Str1 = '12345'
    >>> Str2 = 'abcdef'
    >>> n = 3
    >>> Str1 += Str2[0:n]   #等价C中的 <span style="font-family: Arial, Tahoma, Verdana, sans-serif; font-size: 14px; color: rgb(51, 51, 51); line-height: 25px; ">strncat(sStr1,sStr2,n)</span></span>
    

    扫描字符串是否包含指定的字符:

    <span style="font-weight: normal;">>>> Str2 = '456'
    >>> Str1 = '12345678'
    >>> print len(Str1 and Str2)
    3</span>
    

    字符串指定长度比较:

    <span style="font-weight: normal;">>>> Str1 = '12345'</span>
    <span style="font-weight: normal;">>>> Str2 = '123bc'
    >>> n = 3
    >>> print cmp(Str1[0:n],Str2[0:n])   #返回值为0表示相等
    0
    >>> n = 4
    >>> print cmp(Str1[0:n],Str2[0:n])   #返回值为-1表示不相等
    -1</span>
    
    复制指定长度的字符:

    <span style="font-weight: normal;">>>> Str1 = ''
    >>> Str2 = '12345'
    >>> n = 3
    >>> Str1 = Str2[0:n]
    >>> print Str1
    123</span>

    将字符串前n个字符替换为指定的字符

    >>> sStr1 = '12345'
    >>> ch = 'r'
    >>> n = 3
    >>> sStr1 = n * ch + sStr1[3:]   #字符串操作中+表示字符串链接,*表示重复
    >>> print sStr1
    rrr45
    扫描字符串:

    <span style="font-weight: normal;">>>> Str1 = 'cekjgdklab'
    >>> Str2 = 'gka'
    >>> Pos = -1</span>
    <span style="font-weight: normal;">>>> for c in Str1:
    ...     if c in Str2:
    ...             Pos = Str1.index(c)  #</span><span style="font-size: 14px; color: rgb(68, 68, 68); line-height: 23px; "><span style="font-weight: normal;">python 的index方法是在字符串里查找子串第一次出现的位置,类似字符串的find方法,不过比fi                                      nd方法更好的是,如果查找不到子串,会抛出异常,而不是返回-1</span></span><span style="font-weight: normal;">
    ...             break
    ... 
    >>> print Pos
    2</span>
    翻转字符串
    <span style="font-weight: normal;">>>>Str1 = 'abcdefg'
    >>>Str1 = Str1[::-1]
    >>> print Str1
    gfedcba</span>
    查找字符串
    <span style="font-weight: normal;">>>> Str1 = 'abcdefg'
    >>> Str2 = 'cde'
    >>> print Str1.find(Str2)  #查找成功
    2
    >>> Str2 = 'cdm'
    >>> print Str1.find(Str2)  #查找失败
    -1</span>
    
    连接字符串
    <span style="font-family:Arial, Tahoma, Verdana, sans-serif;">>>> mylist = ['Brazil', 'Russia', 'India', 'China']
    >>> mylist = ','.join(mylist)      #‘,’为链接字符串使用的分隔符
    >>> mylist
    'Brazil,Russia,India,China'
    </span>
    字符串在输出时的对齐

    <span style="font-weight: normal;">S.ljust(width,[fillchar]) 
    #输出width个字符,S左对齐,不足部分用fillchar填充,默认的为空格。 
    S.rjust(width,[fillchar]) #右对齐 
    S.center(width, [fillchar]) #中间对齐 
    S.zfill(width) #把S变成width长,并在右对齐,不足部分用0补足</span>
    字符串中的搜索和替换 
    <span style="font-weight: normal;">S.find(substr, [start, [end]]) 
    #返回S中出现substr的第一个字母的标号,如果S中没有substr则返回-1。start和end作用就相当于在S[start:end]中搜索 
    S.index(substr, [start, [end]]) 
    #与find()相同,只是在S中没有substr时,会返回一个运行时错误(抛出异常) 
    S.rfind(substr, [start, [end]]) 
    #返回S中最后出现的substr的第一个字母的标号,如果S中没有substr则返回-1,也就是说从右边算起的第一次出现的substr的首字母标号 
    S.rindex(substr, [start, [end]]) 
    S.count(substr, [start, [end]]) #计算substr在S中出现的次数 
    S.replace(oldstr, newstr, [count]) 
    #把S中的oldstar替换为newstr,count为替换次数。这是替换的通用形式,还有一些函数进行特殊字符的替换 
    S.strip([chars]) 
    #把S中前后chars中有的字符全部去掉,可以理解为把S前后chars替换为None 
    S.lstrip([chars]) 
    S.rstrip([chars]) 
    S.expandtabs([tabsize]) 
    #把S中的tab字符替换没空格,每个tab替换为tabsize个空格,默认是8个</span>
    字符串的分割和组合
    <span style="font-weight: normal;">S.split([sep, [maxsplit]]) 
    #以sep为分隔符,把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符 
    S.rsplit([sep, [maxsplit]]) 
    S.splitlines([keepends]) 
    #把S按照行分割符分为一个list,keepends是一个bool值,如果为真每行后而会保留行分割符。 
    S.join(seq) #把seq代表的序列──字符串序列,用S连接起来</span>
    字符串的mapping,这一功能包含两个函数 

    <span style="font-weight: normal;">String.maketrans(from, to) 
    #返回一个256个字符组成的翻译表,其中from中的字符被一一对应地转换成to,所以from和to必须是等长的。 
    S.translate(table[,deletechars]) 
    # 使用上面的函数产后的翻译表,把S进行翻译,并把deletechars中有的字符删掉。需要注意的是,如果S为unicode字符串,那么就不支持 deletechars参数,可以使用把某个字符翻译为None的方式实现相同的功能。此外还可以使用codecs模块的功能来创建更加功能强大的翻译表。</span>
    字符串一对编码和解码的函数 
    <span style="font-weight: normal;">S.encode([encoding,[errors]]) 
    # 其中encoding可以有多种值,比如gb2312 gbk gb18030 bz2 zlib big5 bzse64等都支持。errors默认值为"strict",意思是UnicodeError。可能的值还有'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 和所有的通过codecs.register_error注册的值。这一部分内容涉及codecs模块,不是特明白 
    S.decode([encoding,[errors]])</span>
    字符串的测试、判断函数,这一类函数在string模块中没有,这些函数返回的都是bool值 
    <span style="font-weight: normal;">S.startswith(prefix[,start[,end]]) 
    #是否以prefix开头 
    S.endswith(suffix[,start[,end]]) 
    #以suffix结尾 
    S.isalnum() 
    #是否全是字母和数字,并至少有一个字符 
    S.isalpha() #是否全是字母,并至少有一个字符 
    S.isdigit() #是否全是数字,并至少有一个字符 
    S.isspace() #是否全是空白字符,并至少有一个字符 
    S.islower() #S中的字母是否全是小写 
    S.isupper() #S中的字母是否便是大写 
    S.istitle() #S是否是首字母大写的</span>
    字符串类型转换函数,这几个函数只在string模块中有
    <span style="font-weight: normal;">string.atoi(s[,base]) 
    #base默认为10,如果为0,那么s就可以是012或0x23这种形式的字符串,如果是16那么s就只能是0x23或0X12这种形式的字符串 
    string.atol(s[,base]) #转成long 
    string.atof(s[,base]) #转成float</span>
    这里再次强调,字符串对象是不可改变的,也就是说在python创建一个字符串后,你不能把这个字符中的某一部分改变。任何上面的函数改变了字符串后,都会返回一个新的字符串,原字串并没有变。其实这也是有变通的办法的,可以用S=list(S)这个函数把S变为由单个字符为成员的list,这样的话就可以使用S[3]='a'的方式改变值,然后再使用S=" ".join(S)还原成字符串
    <span style="font-size:14px; ">>>> S = 'SPAM'
    >>> L = list(S)
    >>> L
    ['S', 'P', 'A', 'M']
    >>> L[2],L[3]
    ('A', 'M')
    >>> L[2] = 'a'
    >>> S
    'SPAM'
    >>> L
    ['S', 'P', 'a', 'M']
    >>> S =''.join(L)  #<span style="color:#FF9966;">''空字符串作为分隔符(jion将列表字符串连接在一起并用分隔符分开)</span>
    >>> S
    'SPaM'
    >>> 'SPAM'.join(['eggs','sausage','ham','toast'])<span style="color:#FF9966;">#'SPAM'作为字符串分隔符</span>
    'eggsSPAMsausageSPAMhamSPAMtoast'</span>


    字符串格式化表达式:


    字符串格式化符号
    格式化符号 说明
    %c 转换成字符(ASCII 码值,或者长度为一的字符串)
    %r 优先用repr()函数进行字符串转换(Python2.0新增)
    %s 优先用str()函数进行字符串转换
    %d / %i  转成有符号十进制数
    %u 转成无符号十进制数
    %o 转成无符号八进制数
    %x / %X (Unsigned)转成无符号十六进制数(x / X 代表转换后的十六进制字符的大
    小写)
    %e / %E 转成科学计数法(e / E控制输出e / E)
    %f / %F 转成浮点数(小数部分自然截断)
    %g / %G %e和%f / %E和%F 的简写
    %% 输出%

    当然,还有一些辅助符号,如下表所示:

    辅助符号 说明
    * 定义宽度或者小数点精度
    - 用做左对齐
    + 在正数前面显示加号(+)
    <sp> 在正数前面显示空格
    # 在八进制数前面显示零(0),在十六进制前面显示“0x”或者“0X”(取决于用的是“x”还是“X”)
    0 显示的数字前面填充“0”而不是默认的空格
    m.n m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)

    注意:辅助符号要在百分号(%)和格式化符号之间。

    Python提供了一种高级的字符串处理任务——字符串格式化:允许在一个单个的步骤中对一个字符串执行多个特定类型的替换。

    字符串格式化可以以两种形式实现:

    1、字符串格式化表达式:这是从Python诞生的时候就有的最初技术,是基于C语言的printf模型,并且在大多数现有的代码中使用;

    字符串格式化表达式格式化字符串方法:

    1)、在%操作符左侧放置一个需要进行格式化的字符串,这个字符串带有一个或多个嵌入的转换目标,都已%开头(eg:%d)

    2)、在%在操作符右侧放置一个(或多个,嵌入到元组中)对象,这些对象将会插入到左侧想让Python进行格式化字符串的一个或多个转换目标的位置上。

    <span style="color:#000000;">>>> exclamation = "Ni"
    >>> "The Knights who say %s !" % exclamation
    'The Knights who say Ni !'
    >>> "%d %s %d you" % (1,'spam',4)
    '1 spam 4 you'
    >>> "%s -- %s -- %s" % (42,3.14159,[1,2,3])  #所有左侧目标都是%s,表示把他们都转换成字符串(</span><span style="color:#FF0000;">除非作特殊格式化,一般记得用%s格式化代                                                                                    码就可)</span><span style="color:#000000;">
    '42 -- 3.14159 -- [1, 2, 3]'</span>
    
    注意:不止一个值待插入的时候应该在右侧用括号把他们括起来(也就是说把他们放到元组中)——%格式化表达式操作符在其右边期待一个单独的项或多个项的元组。

    由于字符串是不可变的,格式化总是返回新的字符串作为结果而不是对左侧字符串的修改,如果需要的华,可以分配一个变量名来保存结果。

    转换目标的通用结构:

    %[(name)[flags][width][.precision]] typecode

    >>> x = 1234
    >>> res = "integers:...%d...%-6d...%06d" % (x,x,x)  #罗列出左对齐(-),补零(0)标志位:%-6d :6位左对齐,%06d:6位补零
    >>> res
    'integers:...1234...1234  ...001234'
    >>> x = 1.23456789
    >>> x
    1.2345678899999999
    >>> '%-6.2f | %05.2f | %+06.1f' % (x,x,x)
    '1.23   | 01.23 | +001.2'
    

    基于字典的字符串格式化:

    字符串格式化的同时允许左边的转换目标来引用右边字典中的键提取对应的值:

    >>> "%(n)d,%(x)s" % {"n":1,"x":"spam"}
    '1,spam'
    

    上述例子中格式化字符串里面(n),(x)引用了右边字典中的键,并提取他们相应的值,生成类似HTML和XML的程序往往利用这一技术。可以建立一个数值字典,利用基于键的格式化表达式一次性替换。

    >>> reply = '''Greetings...
    ... Hello %(name)s!
    ... You age squared is %(age)s
    ... '''
    >>> values = {'name':'Bob' , 'age':40}
    >>> print(reply%values)
    Greetings...
    Hello Bob!
    You age squared is 40
    
    这样的小技巧也常与内置函数vars配合使用,这个函数返回的字典包含了所有在本函数调用时存在的变量


    2、字符串格式化方法调用:这是在Python 2.6 和Python 3.0 中曾加的技术,是Python独有的技术,和字符串格式化表达式功能有很大的重叠;

      字符串格式化调用方法使用字符串对象的format方法,使用主体字符串作为模板,并且接受任意多个表示将要根据模板替换值的参数。在主题字符串中,花括号通过位置或关键字指出替换目标及将要插入的参数。

    >>> template = '{0},{1} and {2}'     #by position
    >>> template.format('spam','ham','eggs')
    'spam,ham and eggs'
    >>> template = '{name},{age} and {food}'  #by keyword
    >>> template.format(name='Bob',age=40,food='eggs')
    'Bob,40 and eggs'
    >>> template = '{name},{0} and {food}'       #by both
    >>> template.format(40,name='Bob',food='eggs')
    'Bob,40 and eggs'
    
    字符串也可以是一个临时字符串常量:

    >>> '{name},{0} and {food}'.format(40,name='Bob',food='eggs')
    'Bob,40 and eggs'
    



    参考:Python学习手册

             http://www.jb51.net/article/47956.htm


    展开全文
  • 利用Python抓取和解析网页 .

    千次阅读 2013-10-16 19:20:03
    对搜索引擎、文件索引、文档转换、数据检索、站点备份或...本文将详细介绍如何利用Python抓取和解析网页。首先,我们介绍一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块,然后,我们论述如何使用Python

    对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文将详细介绍如何利用Python抓取和解析网页。首先,我们介绍一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块,然后,我们论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。最后,我们会给出一个规整HTML文件的格式标签的例子,通过这个例子您会发现使用python处理HTML文件的内容是非常简单的一件事情。

      一、解析URL

      通过Python所带的urlparse模块,我们能够轻松地把URL分解成元件,之后,还能将这些元件重新组装成一个URL。当我们处理HTML 文档的时候,这项功能是非常方便的。

     

    Python代码  收藏代码
    1. import urlparse  
    2.   
    3.   parsedTuple = urlparse.urlparse(  
    4.   
    5.   "http://www.google.com/search?  
    6.   
    7.   hl=en&q=urlparse&btnG=Google+Search")  
    8.   
    9.   unparsedURL = urlparse.urlunparse((URLscheme, \  
    10.   
    11.   URLlocation, URLpath, ''''''))  
    12.   
    13.   newURL = urlparse.urljoin(unparsedURL,  
    14.   
    15.   "/module-urllib2/request-objects.html")  

     函数urlparse(urlstring [, default_scheme [, allow_fragments]])的作用是将URL分解成不同的组成部分,它从urlstring中取得URL,并返回元组 (scheme, netloc, path, parameters, query, fragment)。注意,返回的这个元组非常有用,例如可以用来确定网络协议(HTTP、FTP等等 )、服务器地址、文件路径,等等。

     

      函数urlunparse(tuple)的作用是将URL的组件装配成一个URL,它接收元组(scheme, netloc, path, parameters, query, fragment)后,会重新组成一个具有正确格式的URL,以便供Python的其他HTML解析模块使用。

      函数urljoin(base, url [, allow_fragments]) 的作用是拼接URL,它以第一个参数作为其基地址,然后与第二个参数中的相对地址相结合组成一个绝对URL地址。函数urljoin在通过为URL基地址附加新的文件名的方式来处理同一位置处的若干文件的时候格外有用。需要注意的是,如果基地址并非以字符/结尾的话,那么URL基地址最右边部分就会被这个相对路径所替换。比如,URL的基地址为Http://www.testpage.com/pub,URL的相对地址为test.html,那么两者将合并成http://www.testpage.com/test.html,而非http://www.testpage.com/pub/test.html。如果希望在该路径中保留末端目录,应确保URL基地址以字符/结尾。

      下面是上面几个函数的详细一点的用法举例:

     

    Python代码  收藏代码
    1. import urlparse  
    2.   
    3.   URLscheme = "http"  
    4.   
    5.   URLlocation = "www.python.org"  
    6.   
    7.   URLpath = "lib/module-urlparse.html"  
    8.   
    9.   modList = ("urllib""urllib2", \  
    10.   
    11.   "httplib""cgilib")  
    12.   
    13.   #将地址解析成组件  
    14.   
    15.   print "用Google搜索python时地址栏中URL的解析结果"  
    16.   
    17.   parsedTuple = urlparse.urlparse(  
    18.   
    19.   "http://www.google.com/search?  
    20.   
    21.   hl=en&q=python&btnG=Google+Search")  
    22.   
    23.   print parsedTuple  
    24.   
    25.   #将组件反解析成URL  
    26.   
    27.   print "\反解析python文档页面的URL"  
    28.   
    29.   unparsedURL = urlparse.urlunparse( \  
    30.   
    31.   (URLscheme, URLlocation, URLpath, ''''''))  
    32.   
    33.   print "\t" + unparsedURL  
    34.   
    35.   #将路径和新文件组成一个新的URL  
    36.   
    37.   print "\n利用拼接方式添加更多python文档页面的URL"  
    38.   
    39.   for mod in modList:  
    40.   
    41.   newURL = urlparse.urljoin(unparsedURL, \  
    42.   
    43.   "module-%s.html" % (mod))  
    44.   
    45.   print "\t" + newURL  
    46.   
    47.   #通过为路径添加一个子路径来组成一个新的URL  
    48.   
    49.   print "\n通过拼接子路径来生成Python文档页面的URL"  
    50.   
    51.   newURL = urlparse.urljoin(unparsedURL,  
    52.   
    53.   "module-urllib2/request-objects.html")  
    54.   
    55.   print "\t" + newURL  

      上述代码的执行结果如下所示:

      用Google搜索python时地址栏中URL的解析结果

     

     

    Python代码  收藏代码
    1. ('http''www.google.com''/search''',  
    2.   
    3.  'hl=en&q=python&btnG=Google+Search''')  
    4.   
    5.  反解析python文档页面的URL  
    6.   
    7.  http://www.python.org/lib/module-urlparse.html  
    8.   
    9.  利用拼接方式添加更多python文档页面的URL  
    10.   
    11.  http://www.python.org/lib/module-urllib.html  
    12.   
    13.  http://www.python.org/lib/module-urllib2.html  
    14.   
    15.  http://www.python.org/lib/module-httplib.html  
    16.   
    17.  http://www.python.org/lib/module-cgilib.html  
    18.   
    19.  通过拼接子路径来生成Python文档页面的URL  
    20.   
    21.  http://www.python.org/lib/module-urllib2/request-objects.html  

     

     

       二、打开HTML文档

      上面介绍了如何解析页面的URL,现在开始讲解如何通过URL打开一个网页。实际上,Python所带的urllib和urllib2这两个模块为我们提供了从URL打开并获取数据的功能,当然,这包括HTML文档。

     

     

    Python代码  收藏代码
    1. import urllib  
    2.   
    3.  u = urllib.urlopen(webURL)  
    4.   
    5.  u = urllib.urlopen(localURL)  
    6.   
    7.  buffer = u.read()  
    8.   
    9.  print u.info()  
    10.   
    11.  print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )  

     

      若要通过urllib模块中的urlopen(url [,data])函数打开一个HTML文档,必须提供该文档的URL地址,包括文件名。函数urlopen不仅可以打开位于远程web服务器上的文件,而且可以打开一个本地文件,并返回一个类似文件的对象,我们可以通过该对象从HTML文档中读出数据。

     

      一旦打开了HTML文档,我们就可以像使用常规文件一样使用read([nbytes])、readline()和readlines()函数来对文件进行读操作。若要读取整个HTML文档的内容的话,您可以使用read()函数,该函数将文件内容作为字符串返回。

      打开一个地址之后,您可以使用geturl()函数取得被获取网页的真正的URL。这是很有用的,因为urlopen(或使用的opener对象)也许会伴随一个重定向。获取的网页URL也许和要求的网页URL不一样。

      另一个常用的函数是位于从urlopen返回的类文件对象中的info()函数,这个函数可以返回URL位置有关的元数据,比如内容长度、内容类型,等等。下面通过一个较为详细的例子来对这些函数进行说明。

     

     

    Python代码  收藏代码
    1. import urllib  
    2.   
    3.   webURL = "http://www.python.org"  
    4.   
    5.   localURL = "index.html"  
    6.   
    7.   #通过URL打开远程页面  
    8.   
    9.   u = urllib.urlopen(webURL)  
    10.   
    11.   buffer = u.read()  
    12.   
    13.   print u.info()  
    14.   
    15.   print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )  
    16.   
    17.   #通过URL打开本地页面  
    18.   
    19.   u = urllib.urlopen(localURL)  
    20.   
    21.   buffer = u.read()  
    22.   
    23.   print u.info()  
    24.   
    25.   print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )  

     

      上面代码的运行结果如下所示:

     

     

    Python代码  收藏代码
    1. Date: Fri, 26 Jun 2009 10:22:11 GMT  
    2.   
    3.  Server: Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_wsgi/2.3 Python/2.5.2  
    4.   
    5.  Last-Modified: Thu, 25 Jun 2009 09:44:54 GMT  
    6.   
    7.  ETag: "105800d-46e7-46d29136f7180"  
    8.   
    9.  Accept-Ranges: bytes  
    10.   
    11.  Content-Length: 18151  
    12.   
    13.  Connection: close  
    14.   
    15.  Content-Type: text/html  
    16.   
    17.  从http://www.python.org读取了18151 字节数据.  
    18.   
    19.  Content-Type: text/html  
    20.   
    21.  Content-Length: 865  
    22.   
    23.  Last-modified: Fri, 26 Jun 2009 10:16:10 GMT  
    24.   
    25.  从index.html读取了865 字节数据.  

     三、小结

      对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文中,我们介绍了一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块。在下篇中,我们将论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。

     

    展开全文
  • Pythonhtml解析(BeautifulSoup)

    万次阅读 2020-11-05 16:57:54
    BeautifulSoup支持不同的解析器,比如,对HTML解析,对XML解析,对HTML5解析。一般情况下,我们用的比较多的是 lxml 解析器。 BeautifulSoup安装  BeautifulSoup3 目前已经停止更新,推荐在现在的项目中使用...
  • 利用Python抓取和解析网页(一)

    千次阅读 2012-02-14 22:17:46
    利用Python抓取和解析网页(一) WebjxCom提示: 对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,...
  • import xmltodict def xml2dict(doc): #xml To dict convertedDict = xmltodict.parse(doc, encoding='utf-8') Bucket_lis = convertedDict["ListAllMyBucketsResult"]["Buckets"]["Bucket"] ...
  • 1、python中json字符串拼接由http://www.json.cn/wiki.html,可知json的基本含义,并知道json的基本组成为数组[]和对象{}对于json当然可以直接使用python库中的方法,但是我们首先手动拼接一下:项目中使用到是如下...
  • Python beautiful soup解析html获得数据

    万次阅读 2019-02-24 02:01:21
    1. 用beautiful soup解析网页的HTML的信息 https://blog.csdn.net/i_chaoren/article/details/63282877 1.1 BeautifulSoup的安装及介绍 官方给出的几点介绍: Beautiful Soup提供一些简单的、python式的函数用来...
  •  因为这些类型其实都是由一些成员共同组成的一个序列整体,所以把它们统称为序列,比如说一个字符串是由一些字符(尽管Python并没有显式的定义字符这个类型)组成的序列,那么“Hello”这个字符串的第一个字...
  • python的spilt()方法可以有效将1个字符串分隔开,并以列表的形式进行输出。以下是具体的使用方法: str1 = "Hello world, My name is 王怕怕升职'" str2 = str1.split() # 以空格为分隔符,全部分隔 str3 = str1....
  • python lxml库etree解析html

    万次阅读 2016-07-18 13:18:22
    一个常用的方法是使用正则表达式,进行匹配提取,这是一种通用的字符串匹配分析方式。但对于html页面来说并没有很好地利用其结构化的特点,python第三方库lxml中的etree提供了另一种更快速方便解析提取html页面数据...
  • java中字符串的精确匹配 在使用Java编程语言时,我们将继续讨论与建议的实践有关的系列文章,我们将讨论String性能调优。 我们将专注于如何有效地处理字符串创建, 字符串更改和字符串匹配操作。 此外,我们将提供...
  • Python中, 索引是从字符串头部算起的一个偏移量, 第一个字母的 偏移量为0。另一种方法是使用负索引, 从字符串结尾倒过来计算。 表达式fruit[-1]表示最后一个字母, fruit[-2]是倒数第二个字母。通过
  • 参考《python用BeautifulSoup库简单爬虫入门+案例(爬取妹子图)》中的载入内容: import requests from bs4 import BeautifulSoup headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.3...
  • split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串 语法 split()方法语法: str.split(str="", num=string.count(str)) 参数 str – 分隔符,默认为所有的空...
  • 导包2.xml转成element对象的方法(1)将字符串形式的xml内容解析成可以调用xpath语法的element对象的方法3. 将一个html文件转化成element对象的方法4. 如何将element对象转化成字符串的方法二、在python中如何使用...
  • Python 经典算法100及解析

    万次阅读 多人点赞 2019-06-10 19:01:26
    1:找出字符串s="aaabbbccceeefff111144444"中,字符出现次数最多的字符 (1)考虑去重,首先将字符串进行过滤去重,这样在根据这些字符进行循环查询时,将会减少循环次数,提升效率。但是本人写的代码较为臃肿,有...
  • python网络爬虫-复杂HTML解析

    万次阅读 2017-09-15 10:54:36
    复杂HTML解析,通过BeautifulSoup的find和findAll来进行复杂界面的解析,使用css的一些属性字段来进行数据定位
  • python用 BeautifulSoup 模块解析 HTML

    千次阅读 2018-08-24 18:39:33
    Beautiful Soup 是一个模块,用于从 HTML 页面中提取信息(用于这个目的时,它比正则表达式好很多)。BeautifulSoup 模块的名称是 bs4(表示 Beautiful Soup,第 4 版)。要安装它,需要在命令行中运行 pip install ...
  • Python中etree.HTML()函数解析

    千次阅读 2020-12-06 11:38:34
    etree.HTML()可以用来解析字符串格式的HTML文档对象,将传进去的字符串转变成_Element对象。作为_Element对象,可以方便的使用getparent()、remove()、xpath()等方法。 url = "https://dl.58.com/xiaoqu/150/" ...
  • python递归解析JSON

    2019-10-04 11:36:35
    2、正则表达式提取JSON字符串 3、递归打印JSON属性值 #!/usr/bin/python # -*- coding: UTF-8 -*- import os, sys, time import urllib.request, requests, bs4 import re, json, demjson import importlib # 设置...
  • Python XML解析

    2016-12-13 15:18:55
    Python XML解析 什么是XML? XML 指可扩展标记语言(eXtensible Markup Language)。 你可以通过本站学习XML教程 XML 被设计用来传输和存储数据。 XML是一套定义语义标记的规则,这些标记将文档...
  • Python学习之解析xml文件

    千次阅读 2015-05-30 16:02:59
    序抛开windows开发python的不快,毕竟没给配台机,只整了个hp商务本,虚拟机什么的还是再缓缓吧。Buddy看完成这么顺利,立刻又给了个开发任务,全当是在考察我吧,毕竟才来三周,妥妥地不能怠慢啊。根据testcase的...
  • 用一些简单的脚本,可以很容易地清理文档和其它大量的 HTML 文件。但是首先你需要解析它们。...致谢编译自 | https://opensource.com/article/18/1/parsing-html-python 作者 | Greg Pittman 译者 | Liang Chen
  • python中用xpath解析网页的基本方法

    万次阅读 多人点赞 2017-10-08 22:51:58
    目前爬虫解析网页的技术有:Json, 正则表达式,BeautifulSoup,PyQuery,XPath XPath 教程 官方文档: http://www.w3school.com.cn/xpath/index.asp 2. XPath简述2.1. 什么是XPath? XPath (XML Path Language) ...
  • python命令行解析模块argparse

    万次阅读 多人点赞 2017-08-06 09:12:30
    英文原文地址: ...https://docs.python.org/3.4/howto/argparse.html#id1 python标准库模块argparse用于解析命令行参数,编写用户友好的命令行界面,该模块还会自动生成帮助信息,并在所给参数无效时报错。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,045
精华内容 12,418
关键字:

利用python字符串解析html

python 订阅