iT邦幫忙

0

[求教] 用Perl 抓取網頁Link 的一個疑問?

  • 分享至 

  • xImage
use LWP::Simple;
use HTML::Parse;
use HTML::Element;

$url ="http://靜態網頁";
$html = get($url);

$parsed_html = parse_html($html);
for (@{ $parsed_html->extract_links() })
{
        $link = $_->[0];
        print "$link\n";
}

若url 換成動態網頁

ex: http://www.softking.com.tw/soft/download.asp?fid3=23516

這個時候就沒有效果了

請IT幫幫忙 !

謝謝

看更多先前的討論...收起先前的討論...
powerop 的網頁,以wget的測試的過程有點誤差,
因所抓的網址是 clickcount.asp 而不是 download.asp,
而抓 clickcount.asp 的網頁,什麼參數都不加都可以抓。

用 Google 搜尋:
site:www.softking.com.tw/soft/download.asp?
基本上沒有幾筆且都是 「操作錯誤,網站瀏覽已被限制暫停!Q」的頁面。
而 site:www.softking.com.tw/soft/ 都已順利抓到 clickcount.asp 的頁面。
而 softking 的網頁的連結,都是 clickcount;
所以結論是 download.asp 好像是 softking 的舊連結,
可能只是作為因應網路上以前留下許多舊連結,
來做導到 新網址的作用 而已。
wget, curl, LWP,應都是只處理 HTML,
而不會去處理 javascript,
或者說視為 comments 之類。
而該網頁 http://www.softking.com.tw/soft/download.asp?fid3=23516
並沒有 <NOSCRIPT> 的內容,
所以就算是 Google 等 robots,
也只會抓到該頁,而不會再往 javascript 所指的 location 抓下去。
就算用 lynx, links 之類的 text-based browser,
對只有 javascript 的頁面而沒有透過 NOSCRIPT 提供連結的話,
也一樣只有一片空白。
所以,想要把 javascript 裡所導到其他的連結,
應與 cookies, referer 沒有關係,
在於去抓取該網頁的工具,有無去處理 javascript 的能力。
所以若要用 perl 來抓取之後的網頁或連結,
只能用事後諸葛的方式,擷取 javascript 裡 location 後面的字串,
視之為是一個連結,來做額外處理。
在 wget 的 FAQ 裡 3.6 Does Wget understand JavaScript?,是說 wget 應不認得 javascript,
但該 FAQ 網頁太久沒更新,所以也不大準,
而從 JavaScript Functionality For Wget
看起來是說要用 plugin 的方式,讓 wget 有一些可以認一些javascript;
但目前所用的 wget 應都還是不會認 javascript。

而powerop 的網頁測試,先抓 clickcount.asp 並存其 cookies 後,
之後再 load cookies 確實能夠把 download.asp 抓下。
我也很好奇,到底是 wget 認得 javascript 嗎?
自己再用 Firefox 測試,首先啟用 NoScript,並用 Add N Edit Cookies ,
把所有 softking 的 cookie 砍掉,
直接連 http://www.softking.com.tw/soft/download.asp?fid3=23516 ,
因沒啟動 Javascript 所以一片空白,再 reload 幾次也一樣。
再開個分頁到 http://www.softking.com.tw/,
再 reload 剛才的 download.asp ,也還是一樣,
再從 softking 隨便點一個 clickcount.asp 後,
再 reload 剛才的 download.asp ,就可以看到畫面了。

所以代表的是 當點 clickcount 時,在 cookie 中寫入了:
xx=xx (觀察一下 cookie 的變化,是寫了什麼值…)
而 download.asp 看到 cookie 有這個值就直接載入頁面,
若沒有該值,就以只有 javascript 的畫面畫面。

所以只要
wget --header "Cookie: xxx=xxx" http://www.softking.com.tw/soft/download.asp?fid3=23516
就可以抓到頁面了。

結論是:download.asp是靠 cookie 的檢查來決定直接秀出網頁,或畫出 javascript 的畫面。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
16
逮丸逮丸
iT邦大師 1 級 ‧ 2009-05-28 20:50:41
最佳解答

根據討論中的結論,再改寫原來的程式碼為:

&lt;pre class="c" name="code">
#use LWP::Simple;
use HTML::Parse;
use HTML::Element;
use LWP::UserAgent;

$ua = LWP::UserAgent->new;
$url ="http://www.softking.com.tw/soft/download.asp?fid3=23516";
$req = HTTP::Request->new(GET => $url);
$req->header(Cookie => 'download=download');

#$html = get($url);
$html = $ua->request($req);
#print $html->content, "\n";
$parsed_html = parse_html($html->content);
for (@{ $parsed_html->extract_links() })
{
        $link = $_->[0];
        print "$link\n";
}

就可以做到想要的結果了。

16
pcboy
iT邦大師 6 級 ‧ 2009-05-27 18:52:52

您的 $html 應該抓到下面部分

<SCRIPT LANGUAGE = "JavaScript">
<!--
{
alert("■ 網頁提示 ■\n\n◆您瀏覽器的功能 Cookies 未開啟,或您不可直接由此進入網頁\n\n◆將帶您回到該軟體的說明網頁,您再進入此網頁\n\n◆若您再進入網頁仍看到此訊息,表示您的 Cookies 功能真的該打開了");
window.parent.location.href="/soft/clickcount.asp?fid3=23516";
}
//-->
</Script>

parse_html 是否有能力抓出 /soft/clickcount.asp?fid3=23516 就很難說了

這是 parser 程式寫的好壞和功力的問題

20
powerop
iT邦研究生 4 級 ‧ 2009-05-28 01:15:26
看更多先前的回應...收起先前的回應...
pcboy iT邦大師 6 級 ‧ 2009-05-28 08:18:26 檢舉

實驗不對,發問者是說下面網址無效果
http://www.softking.com.tw/soft/download.asp?fid3=23516

結果實驗卻去直接測試它剖析不出來的網址
/soft/clickcount.asp?fid3=23516

pcboy iT邦大師 6 級 ‧ 2009-05-28 08:34:54 檢舉

修正網址,測試 mirror抓十層

測試(a)
wget -m --level=10 --cookies=on --keep-session-cookies --save-cookies=cookie.txt http://www.softking.com.tw/soft/download.asp?fid3=23516

測試(b)
wget -m --level=10 --referer=http://www.softking.com.tw/soft/download.asp?fid3=23516 --cookies=on --load-cookies=cookie.txt --keep-session-cookies --save-cookies=cookie.txt http://www.softking.com.tw/soft/download.asp?fid3=2351

只能抓到 download.asp@fid3=23516 檔案而已,表示無法從 download.asp?fid3=23516 中剖析出 clickcount.asp?fid3=23516" 繼續抓下去

lalelee iT邦新手 4 級 ‧ 2009-05-28 10:48:01 檢舉

謝謝您的費心實驗,我跟您一樣唯二的兩個程式語言工具就是sh and perl ,呵呵~

其實我的QBQ是這樣的,我在玩LWP::SIMPLE這個Package
我想試著寫出一個程式是類似wget可以抓取某網頁上所有的檔案,LWP裡面的getstore()已經可以將link存檔了,所以我只要能將網頁上的link通通parse出來就好了,只是沒想到會碰到http refer跟cookies的保護,您提供的方法可以讓我將下載的網頁抓出來,我做個實驗應該可以用RE將所有http link列出來

謝謝 保持聯絡

msn: lale.lee@msa.hinet.net

lalelee iT邦新手 4 級 ‧ 2009-05-28 22:10:42 檢舉

$req->header(Cookie => 'download=download');

這段不太了解,請問為何知道Cookie 該設'download=download' ??

謝謝

參閱 http://ithelp.ithome.com.tw/question/10021692?tab=opinion&oid=85801#85801
當清空 softking cookie後,點 download.asp 多兩個值,無效;而再點 clickcount.asp 又多了兩個值,才有效;就試這兩個值之中,哪一個有效,就找到了。

powerop iT邦研究生 4 級 ‧ 2009-05-31 00:13:25 檢舉

iT邦 這邊大家的回應都很精彩,我又 拋磚引玉 囉 :D
(嗚嗚,哪天才能拼到下一題最佳解答啊 XD)

0
Rohan Sharma
iT邦新手 5 級 ‧ 2023-11-16 18:04:13

Great post! I really enjoyed reading your insights and the way you presented your ideas was clear and engaging. Thank you for sharing your knowledge and perspective with us.Lean Six Sigma Black Belt certification

我要發表回答

立即登入回答