grep
私はWebページのすべてのリンクを取得し、目的のコンテンツを取得するために次のコマンドを使用しました。
curl $URL 2>&1 | grep -o -E 'href="([^"#]+)"' | cut -d'"' -f2 | egrep $CMP-[0-9].[0-9].[0-9]$ | cut -d'-' -f3
昨日まででも仲良くしていました。私はcurl
自分で実行してみて、それが返されるのを見ました。
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
コマンドが機能しないようにするアップデートはありますか?
編集1:
wget
私は問題に対する態度を変えたこの回答:
wget -q $URL -O - | grep -o -E 'href="([^"#]+)"' | cut -d'"' -f2 | egrep $CMP-[0-9].[0-9].[0-9]$ | cut -d'-' -f3
curl
しかし、なぜこの方法が突然動作を停止したのかはまだわかりません。
答え1
警告:正規表現を使用したHTMLの解析ほとんどの場合(すべてではない場合)はい悪いだからあなたの裁量に従って進めてください。
これにより、トリックを実行できます。
curl -f -L URL | grep -Eo "https?://\S+?\""
または
curl -f -L URL | grep -Eo '"(http|https)://[a-zA-Z0-9#~.*,/!?=+&_%:-]*"'
メモ:
これは、「全体」ではなくリンク、または基本的にリンク全体の一部のみが表示される「ハーフリンク」と呼ばれるリンクを考慮しない。これをどこで見たのか覚えていませんが、一部のWebサイトでは特定の/特定のHTMLタグの下に表示されます。編集する:ギルキノ「セミリンク」(正しい用語は相対リンク)で誤って説明したことに対する解決策を提供してください。
curl -Ls URL | grep -oP 'href="\K[^"]+'
- また、リンクの一部ではない項目(「文字」など)は「整理」されません。削除するには、sed などを作成または使用します。
curl -f -L URL | grep -Eo "https?://\S+?\"" | sed 's/&.*//'
最後に、これはリンクが表示される可能性のあるすべての方法を考慮しません。したがって、Webページの構造やHTMLに関する知識が必要です。上記の構造やWebページ自体の例を示すことができない、または表示できないことを考えると、より多くのHTML知識がないと、それに適用される回答を作成することは困難です。
PS:これは明らかでもそうではないかもしれませんが、カールは主に静的リンクに適しているため、動的に生成されたリンク/ URL(PHP、JSなど)を考慮しません。
PS(2):HTMLを解析するためのより良い方法を使用するには、次のより良い答えを使用する必要があります。ギルキノこれは、一般(完全など)およびより最適化されたHTML構文のサポートに適しています。
この場合のように、自分が何をしているのかわからない場合や、要件が非常に制限されている(リンクのみなど)でない限り、正規表現を使用してHTMLを解析することはお勧めできません。
答え2
正規表現を使用してHTMLを解析することに関する一般的な議論があります。これは悪い考えです。代わりに適切なパーサーを使用してください。
mech-dump
mech-dump --links --absolute --agent-alias='Linux Mozilla' <URL>
ソフトウェアパッケージwww-mechanize-perl
(Debianベースのディストリビューション)が付属しています.
(作家:アンディレスターack
、そしてより多く)
xidel
またはsaxon-lint
または道&ネットワークxidel
または、次の認識ツールsaxon-lint
:
xidel -se '//a/@href' <URL>
saxon-lint --html --xpath 'string-join(//a/@href, "^M")' <URL>
^M
はいControl+v Enter
xmlstarlet
:
curl -Ls <URL> |
xmlstarlet format -H - 2>/dev/null | # convert broken HTML to HTML
xmlstarlet sel -t -v '//a/@href' - # parse the stream with XPath expression
javascript
生成されたWebページ
あなたもXPath
できますpuppeteer
JavaScriptスクリプト
const puppeteer = require('puppeteer');
var base_url = 'https://stackoverflow.com';
(async () => {
const browser = await puppeteer.launch({
headless: true,
});
// viewportSize
await page.setViewport({'width': 1440, 'height': 900});
// UA
await page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0')
// open main URL
await page.goto(base_url, { waitUntil: 'networkidle2' });
const xpath_expression = '//a[@href]';
await page.waitForXPath(xpath_expression);
const links = await page.$x(xpath_expression);
const link_urls = await page.evaluate((...links) => {
return links.map(e => e.href);
}, ...links);
await browser.close();
link_urls.forEach((elt) => console.log(elt));
})();
使用法:
nodejs retrieve_all_links.js
答え3
-s
サイレントモードで使用されるカールのパラメータを使用できます。進行状況インジケータやエラーメッセージは表示されません。
答え4
問題は、カールが渡しSTDERR
ながら出力をに送信することです。|
STDOUT
ここの例をご覧ください。。
考えられる2つの解決策は次のとおりです。
STDERR
にパイプし、STDOUT
grepにパイプします。curl -v http://vimcasts.org/episodes/archive/ 2>&1 | grep archive
--stderr
フラグを使用し、引数としてハイフンを提供します。これはカールにそれを使用するように指示しますSTDOUT
。curl -v --stderr - http://vimcasts.org/episodes/archive/ | grep archive