python之全球資訊網

來源:互聯網
上載者:User

標籤:python   原始碼   import   運算式   全球資訊網   

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.Regex並不是完全可讀的。對於更複雜的HTML代碼和查詢來說,運算式會變得亂七八糟並且不可維護。

2.程式對CDATA部分和字元實體之類的HTML特性是無法處理的。如果碰到了這類特性,程式很有可能會失敗。

3.Regex被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進行遠端程序呼叫。


本文出自 “linux_oracle” 部落格,請務必保留此出處http://pankuo.blog.51cto.com/8651697/1661449

python之全球資訊網

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.