網頁抓取與分析

網頁抓取與分析,第1张

概述7-1 網頁抓取分析:入門篇 Perl 在 Web 程式設計與應用的用途可以大略分為三方面: 用於 CGI(Common Gateway Interface)程式設計,亦即在伺服器端使用 Perl 程式來接收使用者由網頁中的表單(Forms)所填寫的資料,並回覆適當的訊息。 用於 Web Client Programming,亦即使用在用戶端的 Perl 程式,來抓取所需的網頁或其他網路上的資料 7-1 網頁抓取與分析:入門篇
Perl 在 Web 程式設計與應用的用途可以大略分為三方面: 用於 CGI(Common Gateway Interface)程式設計,亦即在伺服器端使用 Perl 程式來接收使用者由網頁中的表單(Forms)所填寫的資料,並回覆適當的訊息。 用於 Web ClIEnt Programming,亦即使用在用戶端的 Perl 程式,來抓取所需的網頁或其他網路上的資料。 用於資料處理,例如從網業中抽取有用的資訊。 本節將針對第二及第三點來說明。

在用戶端要用 Perl 程式來抓取所需的網頁,最主要有兩程式庫可供使用:

LWP library: 這是一組適用於 Perl 第五版的模組(Module),可以看成是專門用於 Web ClIEnt Programming 的應用程式介面(Application Program Interface,API),其程式介面較簡單,用此模組寫出來的程式碼也較為簡潔。 Socket library: 這是一組較低層次的應用程式介面,可以讓用戶端和伺服器建立 TCP/IP 連結,並進行各種通訊與溝通。Socket library 的功能較強大,但由於包含太多細節,因此學習門檻較高。 由於一般用戶只是要對 Web 伺服器抓取網頁而已,因此本節介紹就以 LWP library 為主。

LWP library 又稱為 libwww-perl-5,其主要作者(也是推動者)是 Gisle Aas,他是根據 Roy FIElding 在 Perl 4 所發展的 libwww library 來加以推廣、改良而得到的模組。和 LWP library 相關的各種資訊可在其網頁獲得:

http://www.linpro.no/lwp/
截至本書發梓為止,LWP library 的最新版本是 5.48,發行日期是 2000 年四月九號。目前在市面上以 LWP library 為基礎所寫的原文書有兩本: 由 Clinton Wang 所寫的 "Web Client Programming with Perl"。 由 Bill MIDdleton、Brian Deng 及 Chris Kemp 所寫的 "Web Programming With Perl5"。 舉一個最簡單的例子,如果要抓取清華大學資訊系的網頁,可以使用下列程式碼( lwp1.pl):

原始檔(lwp1.pl): (灰色區域按兩下即可拷貝)
use LWP::Simple;$doc = get 'http://www.cs.nthu.edu.tw';print($doc);

上述程式碼的第一列,代表此程式碼會用到 LWP library 中名稱為 Simple 的模組。第二列程式碼將清大資訊系的首頁抓回,並將資訊填入字串變數  doc doc。筆者相信,在所有抓取網頁的任何程式碼,不論使用任何語言,再也不可能會有比上述程式碼更簡潔的版本了!

事實上,若要抓取網頁並將其內容顯示在螢幕上,我們可以在 DOS 命令視窗下輸入下列單行的敘述:

perl -MLWP::Simple -e 'getprint "http://www.cs.nthu.edu.tw";'
此時 Perl 就會使用 LWP library 來捉取網頁,並將 HTML 原始檔顯示在螢幕上,讀者不妨一試!

若在取得網頁原始碼後,希望能刪除 HTML 的標籤(Tags),則可使用下列的程式碼(lwp2.pl):

原始檔(lwp2.pl): (灰色區域按兩下即可拷貝)
use LWP::Simple;foreach (get $ARGV[0]) {	s/<[^>]*>//g;	print;}

在上述範例中,ARGV[0] 代表由命令列輸入的第一個參數,因此以下是一個呼叫此範例程式的例子:

perl lwp2.pl http://neural.cs.nthu.edu.tw/jang
若在取得網頁原始碼後,希望能以 ASCII 檔案顯示,但盡量保留 HTML 的排版效果,則可使用下列的程式碼( lwp3.pl):

原始檔(lwp3.pl): (灰色區域按兩下即可拷貝)
use LWP::Simple;use HTML::Parse;print parse_HTML(get ($ARGV[0]))->format;

若希望能抽取網頁原始碼所包含的所有連結,可使用下列程式碼(tlink1.pl):

原始檔(tlink1.pl): (灰色區域按兩下即可拷貝)
use LWP::Simple;use HTML::Parse;use HTML::Element;$HTML = get $ARGV[0];$parsed_HTML = HTML::Parse::parse_HTML($HTML);for (@{ $parsed_HTML->extract_links() }) {	$link = $_->[0];	print "$link\n";}

我們可執行上述程式碼,如下:

perl tlink1.pl http://neural.cs.nthu.edu.tw/jang
執行後的結果如下:
sandBox/HTML/autoload.htm/jang/cgi-bin/rand_image.plgraphics/myname.jpggraphics/animgif/flare.gifgraphics/course.gifgraphics/research.gifhttp://neural.cs.nthu.edu.tw/jang/courses/cs4601/http://neural.cs.nthu.edu.tw/jang/courses/cs5652/http://www.cs.nthu.edu.tw/~jang/courses/cs3331/...
此 Perl 程式雖然已將各個連結印出,但有些是相對網址,有些則是絕對網址,非常不方便。以下程式碼( tlink2.pl)可以將所有連結的相對網址轉成絕對網址:

原始檔(tlink2.pl): (灰色區域按兩下即可拷貝)
use LWP::Simple;use HTML::Parse;use HTML::Element;use URI::URL;$HTML = get $ARGV[0];$parsed_HTML = HTML::Parse::parse_HTML($HTML);for (@{ $parsed_HTML->extract_links() }) {	$link = $_->[0];	$url = new URI::URL $link;	$full_url = $url->abs($ARGV[0]);	print "$full_url\n";}

我們可執行上述程式碼,如下:

perl tlink2.pl http://neural.cs.nthu.edu.tw/jang
執行後的結果如下:
http://neural.cs.nthu.edu.tw/sandBox/HTML/autoload.htmhttp://neural.cs.nthu.edu.tw/jang/cgi-bin/rand_image.plhttp://neural.cs.nthu.edu.tw/graphics/myname.jpghttp://neural.cs.nthu.edu.tw/graphics/animgif/flare.gifhttp://neural.cs.nthu.edu.tw/graphics/course.gifhttp://neural.cs.nthu.edu.tw/graphics/research.gifhttp://neural.cs.nthu.edu.tw/jang/courses/cs4601/http://neural.cs.nthu.edu.tw/jang/courses/cs5652/http://www.cs.nthu.edu.tw/~jang/courses/cs3331/...
很明顯地,所有的相對路徑已經被轉成絕對路徑。但是,其中有很多連結是連到一個影像檔(如*.jpg),並不是我們所想到的資訊,因此我們可用下列程式碼( tlink3.pl)來規範所想要的文字連結:

原始檔(tlink3.pl): (灰色區域按兩下即可拷貝)
use LWP::Simple;use HTML::Parse;use HTML::Element;use URI::URL;$HTML = get $ARGV[0];$parsed_HTML = HTML::Parse::parse_HTML($HTML);for (@{ $parsed_HTML->extract_links((“a”)) }) {	$link = $_->[0];	$url = new URI::URL $link;	$full_url = $url->abs($ARGV[0]);	print “$full_url\n”;}

我們可執行上述程式碼,如下:

perl tlink3.pl http://neural.cs.nthu.edu.tw/jang
執行後的結果如下:
http://neural.cs.nthu.edu.tw/sandBox/HTML/autoload.htmhttp://neural.cs.nthu.edu.tw/jang/courses/cs4601/http://neural.cs.nthu.edu.tw/jang/courses/cs5652/http://www.cs.nthu.edu.tw/~jang/courses/cs3331/http://neural.cs.nthu.edu.tw/jang/courses/cs3430/http://www.cs.nthu.edu.tw/~jang/mlbook/demohttp://www.cs.nthu.edu.tw/~jang/mlbookhttp://neural.cs.nthu.edu.tw/research/undergradhttp://anfis.cs.nthu.edu.tw/vod/http://140.114.119.1/~vm...

由此可見 tlink3.pl 已經可以抓取出網頁的連結,而且所有連結網址也都轉換為絕對網址。如果我們要實作一個 Web 的搜尋引擎,第一步驟就是要寫出一個 Web Robot,它的功能就是要能抓取網頁,並抽取每一個網頁的連結網址,然後再往下繼續抓取被連結網頁,如此依此類推。所以上述的範例程式,就是一個簡單 Web Robot 的雛形。


7-2 網頁抓取與分析:進階篇
在上節中,我們介紹了 LWP::Simple 的用法和範例。使用 LWP::Simple 來抓取網頁相當方便,但是它也有一些缺點: 在抓取網頁過程中,無法傳會狀態碼(Status Code)。常見的狀態碼有下列幾種:

狀態碼 說明
200 OK,一切正常
404 找不到所要求的網頁
408 等待伺服器回覆時間過久
500 伺服器內部發生錯誤

Perl 程式並不會在表頭(header)向伺服器表明自己的身份。 不支援代理伺服器(Proxy Server)。 因此,若要能夠取得要求網頁的狀態碼,就必須要使用較複雜的模組。以下的這個例子,可以先判斷是否抓取網頁成功,若成功,則印出網頁原始碼;若不成功,則印出錯誤訊息。程式碼( tstatus.pl)如下:

原始檔(tstatus.pl): (灰色區域按兩下即可拷貝)
use LWP::UserAgent;use http::Request;use http::Response;$ua = new LWP::UserAgent;				# 產生 UserAgent 物件$request = new http::Request('GET',$ARGV[0]);	# 產生 Request 物件$response = $ua->request($request);			# 開始抓取網頁,並將結果傳會 $responseif ($response->is_success) {			# 若抓取網頁成功,則印出 HTML 原始碼	print $response->content;} else {						# 若抓取網頁不成功,則印出錯誤訊息	print $response->error_as_HTML;}

下面這個範例(tproxy.pl),則使用了 http 代理伺服器來減少網路的流量:

原始檔(tproxy.pl): (灰色區域按兩下即可拷貝)
use LWP::UserAgent;use http::Request;use http::Response;$ua = new LWP::UserAgent;				# 產生 UserAgent 物件$ua->proxy('http','http://proxy.nthu.edu.tw/proxy.pac');	# 設定 http 的代理伺服器$ua->no_proxy('nthu.edu.tw');			# 在清大的網頁(nthu.edu.tw)不使用代理伺服器$request = new http::Request('GET',$ARGV[0]);	# 產生 Request 物件$response = $ua->request($request);			# 開始抓取網頁,並將結果傳會 $responseif ($response->is_success) {			# 若抓取網頁成功,則印出 HTML 原始碼	print $response->content;} else {						# 若抓取網頁不成功,則印出錯誤訊息	print $response->error_as_HTML;}

行文至此,讀者應該可以感受到用 Perl 來抓取網頁的便利性與彈性。稍微修改上述的範例程式,就可以產生許多不同的應用,以下是一些有用(或有趣)的應用範例:

自動留言程式:你可以寫一個 Perl 程式,自動尋找留言版,並自動留言,如「孫悟空到此一遊」等。 Web 統計資料:可以根據搜尋引擎的結果,來發掘對於某個問題的正反面答案。例如,如果你想知道那個程式語言最被大家喜愛,可參見:
http://www.lehigh.edu/~sol0/rules.html
(不看上述網頁,你大概可以猜到答案是什麼吧?) 驗證網頁的連結是否正確:我們只需抽取出此網頁的連結,再抓取所有連結網頁的表頭(不需抓取內文,以減輕網路流量),即可確認連結是否正確。 表明 User Agent 身份:在向伺服器送出的 Request 表頭中,Perl 程式碼可以表明自己的身份,此功能能讓伺服器記錄送出 request 的 UserAgent 的類別。 個人資訊代理程式(Agent):你可以寫一個 Perl 程式,定期自動抓取個人所需特定資訊,並即刻顯示再瀏覽器,例如某城市的氣溫、快遞包裹的傳送情況等。 Mirror 功能:建立一個 Mirror 站台,並用 Perl 程式在預定時段自動更新。 網羅新聞:即時抓取線上新聞,並根據新聞標題加以自動聚題(同一個主題的新聞放在一起)與分類(政治類、娛樂類等)。這是典型的「網頁加工業」,也是「知識管理」的一部份,可見太一信通公司的網羅新聞頁:
http://www.taiyi.com
全文搜尋引擎:你可以反覆抓取網頁,再根據資訊檢索(information RetrIEval)的各種演算法,建立反轉索引(Inverted Indexing),最後建立一個網頁的全文檢索搜尋引擎。典型的搜尋引擎可見中正大學的蓋世引擎:
http://gais.cs.ccu.edu.tw/
或美國的 Google 搜尋引擎:
http://www.google.com
总结

以上是内存溢出为你收集整理的網頁抓取與分析全部内容,希望文章能够帮你解决網頁抓取與分析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1284393.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存