簡単に言えば、簡単な解決策はありません。依存関係が少ないと見苦しいコードになり、逆もまた同様です。コードの堅牢性により、依存関係の要件が高くなります。
これを念頭に置いて、以下にいくつかの解決策を説明し、それぞれの長所と短所を提供してそれらを要約します.
アプローチ1
wget
の-k
オプションをいくつかの正規表現と一緒に使用できます(その方法で HTML を解析する方法の詳細を参照してください)。
Linux のマニュアルから:
-k
--convert-links
After the download is complete, convert the links in the document to
make them suitable for local viewing.
(...)
The links to files that have not been downloaded by Wget will be
changed to include host name and absolute path of the location they
point to.
Example: if the downloaded file /foo/doc.html links to /bar/img.gif
(or to ../bar/img.gif), then the link in doc.html will be modified to
point to http://hostname/bar/img.gif.
スクリプト例:
#wget needs a file in order for -k to work
tmpfil=$(mktemp);
#-k - convert links
#-q - suppress output
#-O - redirect output to given file
wget http://example.com -k -q -O "$tmpfil";
#-o - print only matching parts
#you could use any other popular regex here
grep -o "http://[^'\"<>]*" "$tmpfil"
#remove unnecessary file
rm "$tmpfil"
長所:
- インストール済みであれば、ほとんどのシステムでそのまま使用できます
wget
。
- ほとんどの場合、これで十分な解決策になります。
短所:
- チョムスキー階層の正規表現の下にある HTML 階層モデルが原因で、いくつかのエキゾチックなページで壊れる正規表現を備えています。
- ローカル ファイル システム内の場所を渡すことはできません。作業 URL を渡す必要があります。
アプローチ 2
Python を BeautifulSoup と一緒に使用できます。スクリプト例:
#!/usr/bin/python
import sys
import urllib
import urlparse
import BeautifulSoup
if len(sys.argv) <= 1:
print >>sys.stderr, 'Missing URL argument'
sys.exit(1)
content = urllib.urlopen(sys.argv[1]).read()
soup = BeautifulSoup.BeautifulSoup(content)
for anchor in soup.findAll('a', href=True):
print urlparse.urljoin(sys.argv[1], anchor.get('href'))
その後:
dummy:~$ ./test.py http://example.com
長所:
- 本格的なパーサーを適切に使用しているため、HTML を処理する正しい方法です。
- エキゾチックな出力はうまく処理される可能性が非常に高いです。
- 少し変更を加えるだけで、このアプローチは URL だけでなく、ファイルに対しても機能します。
- わずかな変更で、独自のベース URL を指定できる場合もあります。
短所:
- Python が必要です。
- カスタムパッケージ付きの Python が必要です。
- 、など
<img src>
のタグと属性を手動で処理する必要があります(上記のスクリプトには示されていません)。<link src>
<script src>
アプローチ 3
の一部の機能を使用できますlynx
。(これは、質問で提供した回答で言及されていました。)例:
lynx http://example.com/ -dump -listonly -nonumbers
長所:
- 非常に簡潔な使用法。
- あらゆる種類の HTML でうまく機能します。
短所:
- リンクスが必要です。
- ファイルからリンクを抽出することもできますが、ベース URL を制御することはできず、リンクになってしまい
file://localhost/
ます。<base href="">
HTMLにタグを手動で挿入するなどの醜いハックを使用して、これを修正できます。