python之万维网

15.1 屏幕抓取

屏幕抓取是程序下载网页并且提取信息的过程。

简单的屏幕抓取程序

from urllib import urlopen

import re

p = re.compile(‘<h3><a .*?><a .*? href="(.*?)">(.*?)</a>‘)

text = urlopen(‘http://python.org/community/jobs‘).read()

for url,name in p.findall(text):

print ‘%s (%s)‘ % (name,url)

上述这个已经可以用了,但是至少有3个缺点

1.正则表达式并不是完全可读的。对于更复杂的HTML代码和查询来说,表达式会变得乱七八糟并且不可维护。

2.程序对CDATA部分和字符实体之类的HTML特性是无法处理的。如果碰到了这类特性,程序很有可能会失败。

3.正则表达式被HTML源代码约束,而不是取决于更抽象的结构。这就意味着网页结构中很小的改变就会导致程序中断。

15.1.1 Tidy和XHTML解析

1.Tidy是什么

Tidy是用来修复不规范且随意的HTML的工具。它能以相当智能的方法修复一般的错误,做那些你不愿意做的事情。它也是可设置的,也可以打开或关闭各种修改选项。

Tidy不能修复HTML文件的所有问题,但是它会确保文件的格式是正确的,这样一来解析的时候就轻松多了。

2.获取Tidy库

可以从网上下载

3.在Python中使用命令行Tidy

如果正在使用UNIX或Linux系统的话,就不信要安装任何库,因为系统可能已经包括Tidy的命令行版本。

获得二进制版本后,可以使用subprocess模块运行Tidy程序。假设有个叫做messy.html的混乱的HTML文件,那么下面的程序会对该文件运行Tidy,然后打印结果:

from subprocess import Popen,PIPE

text = open(‘messy.html‘).read()

tidy = Popen(‘tidy‘,stdin=PIPE,stdout=PIPE,stderr=PIPE)

tidy.stdin.write(text)

tidy.stdin.close()

print tidy.stdout.read()

4.但为什么用XHTML

XHTML和旧版本的HTML之间的最主要区别是XHTML对于显式关闭所有元素要求更加严格。所以HTML中可能只用一个开始标签(<p>标签)结束一段然后开始下一段,而在XHTML中首先需要显示地关闭当前段落。这种行为让XHTML更容易解析,因为可以直接告诉程序什么时候进入或者离开各种元素。XHTML的另外一个好处是它是XML的一种,所以可以对它使用XML的工具,例如Xpath。

解析这类从Tidy中获得的表现良好的XHTML的方法是使用标准库模块HTMLParser。

5.使用HTMLParser

使用HTMLParser的意思是继承它,并且对handle_starttage或handle_data等事件处理方法进行覆盖。

如果要进行屏幕抓取,一般不需要实现所有的解析器回调,也可能不用创造整个文档的抽象表示法来查找自己需要的内容。如果只需要记录所需信息的最小部分,那么就足够了。

使用HTMLParser模块的屏幕抓取程序

from urllib import urlopen

from HTMLParser import HTMLPaeer

class Scraper(HTMLParser):

in_h3 = False

in_link = False

def handle_starttag(self,tag,attrs):

attrs = dict(attrs)

if tag == ‘h3‘:

self.in_h3 = True

if tag == ‘a‘ and ‘href‘ in attrs:

self.in_link = True

self.chunks = []

self.url = attrs[‘href‘]

def handle_data(self,data):

if self.in_link:

self.chunks.append(data)

def handle_endtag(self,tag):

if tag == ‘h3‘:

self.in_h3 = False

if tag == ‘a‘:

if self.in_h3 and self.in_link:

print ‘%s (%s)‘ % (‘‘.join(self.chunks),self.url)

self.in_link = False

text = urlopen(‘http://python.org/community/jobs‘).read()

parser = Scraper()

parser.feed(text)

parser.close()

首先,没有使用Tidy,因为网页中HTML已经足够规范了。使用了一些布尔状态变量以追踪是否已经位于h3元素和链接内。在事件处理程序中检查并且更新这些变量。handle_starttag的attrs参数是由(键,值)元组组成的列表,所以使用dict函数将它们转化为字典。

handle_data方法可能还得解释一下。它使用了在处理HTML和XML这类结构化标记的基于事件的解析工作时非常常见的技术。我没有假定只掉用handle_data就能获得所有需要的文本,而是假定会通过多次调用函数获得多个文本块。这样做的原因有几个:忽略了缓冲、字符实体和标记等----只需确保获得所有文本。然后在准备输出结果时,只是将所有的文本联结在一起。可以让文本调用feed方法以运行这个解析器,然后再调用close方法。

15.1.2 Beautiful Soup

Beautiful Soup是个小模块,用来解析和经常在网上看到的那些乱七八糟而且不规则的HTML。

下载和安装beautiful Soup:下载BeautifulSoup.py文件,然后将它放置在python路径中。如果需要的话,还能下载带有安装脚本和测试的tar档案文件。

使用beautiful Soup的屏幕抓取程序

from urllib import urlopen

from BeautifulSoup import BeautifulSoup

text = urlopen(‘http://python.org/community/jobs‘).read()

soup = BeautifulSoup(text)

jobs = set()

for header in soup(‘h3‘):

links = header(‘a‘,‘reference‘)

if not links:continue

link = links[0]

jobs.add(‘%s (%s)‘ % (link.string,link[‘href‘]))

print ‘\n‘.join(sorted(jobs,key=lambda s: s.lower()))

用HTML文本实例化BeautifulSoup类,然后使用各种方法提取处理后的解析树的各个部分。

15.2 使用CGI创建动态网页

CGI(通用网关接口)。CGI是网络服务器可以将查询传递到专门的程序中并且在网页上显示结果的标准机制。它是创建万维网应用程序而不用编写特殊用途的应用服务器的简单方法。

Python CGI程序设计的关键工具是cgi模块。

15.2.1 第一步:准备网络服务器

15.2.2 第二步:加入Pound Bang行

当把脚本放在正确位置后,需要在脚本的开始处增加pound bang行。

#!/usr/bin/env python

15.2.3 设置文件许可

设置权限

15.2.5 简单的CGI脚本

简单的CGI脚本

#!/usr/bin/env python

print ‘Content-type:text/plain‘

print

print ‘hello,world‘

text.plain 说明是普通文本,如果页面是HTML,这一行就是text/html

15.2.6  使用cgitb调试

调用回溯的CGI脚本

#!/usr/bin/env python

import cgitb;cgitb.enable()

print ‘Content-type: text/html‘

print

print 1/0

print ‘hello,world‘

可以通过浏览器访问下

15.2.7 使用cgi模块

输入时通过HTML表单提供给CGI脚本的键-值对,或称字段。可以使用cgi模块的FieldStorage类从CGI脚本中获取这些字段。当创建FieldStorage实例时,它会从请求中获取输入变量,然后通过类字典接口将它们提供给程序。FieldStorage的值可以通过普通的键查找方式访问,但是因为一些技术原因,FieldStorage的元素并不是真正所要的值。比如知道请求中包括名为name的值,就不应该像下面这么做:

form = cgi.FieldStorage()

name = form[‘name‘]

而应该这样做:

form = cgi.FieldStorage()

name = form[‘name‘].value

获取值得简单方式就是用getvalue方法,它类似于字典的get方法,但它会返回项目的value特性的值。

form = cgi.FieldStorage()

name = form.getvalue(‘name‘,‘Unknown‘)

在上面的代码,我提供了一个默认值unknown。如果不提供的话,就会将None作为默认值使用。

利用FieldStorage获取一个值得CGI脚本

#!/usr/bin/env python

import cgi

form = cgi.FieldStorage()

name = from.getvalue(‘name‘,‘world‘)

print ‘Content-type:text/plain‘

print

print ‘Hello,%s!‘ % name

CGI脚本的输入一般都是从已经提交的web表单中获得,但是也可以直接使用参数调用CGI程序。

15.2.8 简单的表单

从CGI脚本获取信息的方法有两种:GET方法和POST方法。

带有HTML表单的问候脚本

#!/usr/bin/env python

import cgi

form = cgi.FieldStorage()

name = from.getvalue(‘name‘,‘world‘)

print ""Content-type:text/html

<html>

<head>

<title>Greeting Page</title>

</head>

<body>

<h1>hello,%s1</h1>

<form action=‘simple3.cgi‘>

change name <input type=‘text‘ name=‘name‘/>

<input type=‘submit‘/>

</form>

</body>

</html>

""" % name

在脚本的开始处先获取CGI参数name。

15.3 mod_python

mod_python是apache的扩展模块。

15.3.1 安装mod_python

$./configure --with-apxs=/usr/local/apache/bin/apxs

$make

$make install

配置apache

LoadModule python_module libexec/mod_python.so

在.htaccess文件添加

<Directory /path/to/your/directory>

(add the directory here)

</Directory>

15.3.2 CGI处理程序

CGI处理程序在使用CGI的时候会模拟程序运行的环境。所以可以用mod_python运行程序,但是还可以使用gi和gitb模块把它当作CGI脚本来写。

如果要使用CGI处理程序,要将下面的代码放在CGI脚本所在目录中的.htaccess文件内

SetHandler mod_python

PythonHandler mod_python.cgihandler

需要调试信息的话,增加代码:

PythonDebug On

开发完之后,在去掉。

为了运行CGI脚本,可能需要脚本以.py结尾---尽管访问的时候还是用以.cgi结尾的URL,mod_python在查找满足请求的文件时会将.cgi转换为.py

15.3.3 PSP

PSP文档是HTML以及python代码的混合,python代码会包括在具有特殊用途的标签中。任何HTML会被转换为输出函数的调用。

只要把下面 的代码放在.htaccess文件中即可设置PSP页面:

AddHandler mod_python .psp

PythonHandler mod_python .psp

PSP标签有两类:一类用于语句,另外一类用于表达式。

带有少量随机数据的PSP例子

<%

from random import choice

adjectives = [‘beautiful‘,‘cruel‘]

%>

<html>

<head>

<title>hello</title>

</head>

<body>

<p>hello, <%=choice(adjectives)%> world. my name is Mr. Gumby.</p>

</body>

</html>

<% - 像这样 -%> 书写注释。

15.3.4 发布

要使用发布处理程序,需要下面代码放在.htaccess文件中。

AddHandler mod_python .py

PythonHandler mod_python.publisher

这样可以使用发布处理程序把所有以.py当作python脚本运行。

下面的函数已经可以发布处理程序了:

def index(req):

return "hello,world"

请求对象访问受到请求中德信息,以及设置自定义HTTP首部等。

使用mod_python发布处理程序进行验证

from sha import sha

__auth_realm__ = "A simple test"

def __auth__(req,user,pswd):

return user == "Gumby" and sha(pswd).hexdigest() == \

‘13hj3123012kllkjfl1‘

def __access__(req,user):

return True

def index(req,name="world"):

return "<html>hello,%s!</html>" % name

15.4 网络应用程序框架

15.5 web服务:正确分析

15.5.1 RSS

15.5.2 使用XML-RPC进行远程过程调用。

时间: 2024-10-24 01:55:31

python之万维网的相关文章

python基础教程_学习笔记24:网络编程、Python和万维网

网络编程 python是一个很强大的网络编程工具,首先,它有很多针对常见网络协议的库,在库顶部可以获得抽象层,这样可以集中精力在程序的逻辑处理上,而不是停留在网络实现的细节上:其次,python处理字节流的各种模式方面很擅长,因此可以轻松处理各种协议格式. 少数几个网络设计模块 socket模块 在网络编程中的一个基本组件就是套接字(socket).套接字主要是两个程序之间"信息通道".程序可能(通过网络连接)分布在不同的计算机上,通过套接字相互发送信息.在Python中的大多数的网络

Python学习笔记总结

1Python的数据结构: 1:序列:  列表(可改变) 元祖 (不可改变) 2:映射:字典 3:无序:集合 ASCII:八位   Unicode:16位 2Python的函数 abs:绝对值 match.sqrt:开方 match.ceil:上入 match.floor:下入 pow:幂 repr:字符串 str:字符串 round:四舍五入 help:帮助 input:输入 raw_input:原始输入 camtch.sqrt:负数开方 3Python的运行 (1)命令行运行程序:Pytho

Python+Requests接口测试教程(1):Fiddler抓包工具

本书涵盖内容:fiddler.http协议.json.requests+unittest+报告.bs4.数据相关(mysql/oracle/logging)等内容.刚买须知:本书是针对零基础入门接口测试和python+requests自动化的,首先本书确实写的比较基础,对基础内容也写的很详细,所以大神绕道. 为什么要先学fiddler? 学习接口测试必学http协议,如果直接先讲协议,我估计小伙伴们更懵,为了更好的理解协议,先从抓包开始.结合抓包工具讲http协议更容易学一些. 1.1 抓fir

Python之路【第十九篇】:爬虫

Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. Requests Python标准库中提供了:urllib.urllib2.httplib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务. import

Life is short, you need Python

今年四五月份的时候我打算学一门计算机语言. 计算机语言实在是很多,选哪一个? 其实这个选择就和去市场买菜类似,想明白了自己的需求才能做好决定.你想做什么饭,就去买什么菜.想做南瓜粥,就要去买南瓜,想要做番茄炒蛋,就得买西红柿鸡蛋. 因为我没有编程基础,所以就想要选择一个容易入门的,所以就选了python. 图片中衣服上印着“人生苦短,我用python”这句话的人正是python之父,Guido van Rossum(吉多•范罗苏姆). 1989年圣诞,Monty Python"s Flying

Python实现基于协程的异步爬虫

一.课程介绍 1. 课程来源 本课程核心部分来自<500 lines or less>项目,作者是来自 MongoDB 的工程师 A. Jesse Jiryu Davis 与 Python 之父 Guido van Rossum.项目代码使用 MIT 协议,项目文档使用 http://creativecommons.org/licenses/by/3.0/legalcode 协议. 课程内容在原文档基础上做了稍许修改,增加了部分原理介绍,步骤的拆解分析及源代码注释. 2. 内容简介 传统计算机

Python成长之路第一篇(2)-初识列表和元组

可以将列表和元组当成普通的"数组",他能保存任意数量任意类型的Python对象,和数组一样都是通过数字0索引访问元素,列表和元组可以存储不同类型的对象,列表和元组有几处重要区别.列表元素用([])包括,元素的个数和值可以改变,而元组用({})包括,不能更改.元组可以看成是只读的列表 一.初识列表 1.下面是一个正常的列表 >>> lis = ['xiaoyuan',25] 在序列中,可以包含其他的序列,也就是列表可以包含列表元组等 >>> lis =

python字符串编码

http://blog.csdn.net/pipisorry/article/details/44136297 文本,他们通常指显示在屏幕上的字符或者其他的记号:但是计算机不能直接处理这些字符和标记:它们只认识位(bit)和字节(byte).实际上,从屏幕上的每一块文本都是以某种字符编码(character encoding)的方式保存的.粗略地说就是,字符编码提供一种映射,使屏幕上显示的内容和内存.磁盘内存储的内容对应起来.有许多种不同的字符编码,有一些是为特定的语言,比如俄语.中文或者英语,

Python爬虫入门一之综述

首先爬虫是什么? 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 根据我的经验,要学习Python爬虫,我们要学习的共有以下几点: Python基础知识 Python中urllib和urllib2库的用法 Python正则表达式 Python爬虫框架Scrapy Python爬虫更高级的功能 1.Python基础学习 首先,我们要用Python写爬虫,肯定要了解Python的基础吧,万丈高楼平地起,