0

Bash の特定のページからすべての URL を取得したい。

この問題はすでにここで解決されています: sed または awk のみを使用して html ページから URL を抽出する最も簡単な方法

ただし、秘訣は、相対リンクを絶対リンクに解析することです。したがって、http://example.com/次のようなリンクが含まれている場合:

<a href="/about.html">About us</a>
<script type="text/javascript" src="media/blah.js"></a>

結果を次の形式にしたい:

http://example.com/about.html
http://example.com/media/blah.js

依存関係をできるだけ少なくするにはどうすればよいですか?

4

3 に答える 3

7

簡単に言えば、簡単な解決策はありません。依存関係が少ないと見苦しいコードになり、逆もまた同様です。コードの堅牢性により、依存関係の要件が高くなります。

これを念頭に置いて、以下にいくつかの解決策を説明し、それぞれの長所と短所を提供してそれらを要約します.

アプローチ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"

長所:

  1. インストール済みであれば、ほとんどのシステムでそのまま使用できますwget
  2. ほとんどの場合、これで十分な解決策になります。

短所:

  1. チョムスキー階層の正規表現の下にある HTML 階層モデルが原因で、いくつかのエキゾチックなページで壊れる正規表現を備えています。
  2. ローカル ファイル システム内の場所を渡すことはできません。作業 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

長所:

  1. 本格的なパーサーを適切に使用しているため、HTML を処理する正しい方法です。
  2. エキゾチックな出力はうまく処理される可能性が非常に高いです。
  3. 少し変更を加えるだけで、このアプローチは URL だけでなく、ファイルに対しても機能します。
  4. わずかな変更で、独自のベース URL を指定できる場合もあります。

短所:

  1. Python が必要です。
  2. カスタムパッケージ付きの Python が必要です。
  3. 、など<img src>のタグと属性を手動で処理する必要があります(上記のスクリプトには示されていません)。<link src><script src>

アプローチ 3

の一部の機能を使用できますlynx。(これは、質問で提供した回答で言及されていました。)例:

lynx http://example.com/ -dump -listonly -nonumbers

長所:

  1. 非常に簡潔な使用法。
  2. あらゆる種類の HTML でうまく機能します。

短所:

  1. リンクスが必要です。
  2. ファイルからリンクを抽出することもできますが、ベース URL を制御することはできず、リンクになってしまいfile://localhost/ます。<base href="">HTMLにタグを手動で挿入するなどの醜いハックを使用して、これを修正できます。
于 2013-06-30T19:50:15.010 に答える
3

もう 1 つのオプションは、私のXidel (XQuery/Webscraper)です。

すべての通常のリンクの場合:

xidel http://example.com/ -e '//a/resolve-uri(@href)'

すべてのリンクとソースについて:

xidel http://example.com/ -e '(//@href, //@src)/resolve-uri(.)'

rr- の形式では:

長所:

  1. 非常に簡潔な使用法。

  2. あらゆる種類の HTML でうまく機能します。

  3. 本格的なパーサーを適切に使用しているため、HTML を処理する正しい方法です。

  4. ファイルと URL で機能します

  5. 独自のベース URL を指定できます。(とresolve-uri(@href, "baseurl"))

  6. Xidel 以外の依存関係なし (https URL もある場合は openssl を除く)

短所:

  1. どの標準リポジトリにも含まれていない Xidel が必要です
于 2013-06-30T21:26:47.390 に答える