如何从网页的源代码中提取 URL?
How can I extract URLs from the source code of a webpage?
我正在尝试为我在 Broadcastify 上找到的一些扫描仪设置流。问题是他们使用的 URLs 是动态的,并且一次只有几个小时是相同的。我想创建一个 shell 脚本,它可以简单地扫描访问流的页面(它确实有一个静态 URL)和 return 当前 URL流,然后可以将其馈送到音频播放器。
例如,现在 https://www.broadcastify.com/listen/feed/30185/web has a stream at http://audio12.broadcastify.com/kq2ydfr1jz98shw.mp3
的以下流
但是,该流 link 只会在短时间内有效。我需要像上面那样的 MP3 流。
我对 shell 脚本编写的经验很少,所以我想知道最好的方法是什么。具体来说,我的第一个问题是,如果我只是 "View page source" 并搜索 "mp3",则没有结果。我只能通过检查元素(F12 开发人员工具)找到 URL,例如,在 Chrome 中,转到应用程序 → 框架 → 媒体。我以为我可以在过去的音频播放器上做一个 "view frame source",但现在没有那个选项。
我想我可以使用 grep 如果我能够 CURL 源代码,但我不确定我需要什么 CURL 在这里,如果这有意义的话。
更新
感谢 mk12 的见解。基于此,这是我的 shell 脚本:
#!/bin/bash
curl "https://www.broadcastify.com/listen/feed//web" | grep webAuth > /var/tmp/broadcastifyauth.txt
pta=`cat /var/tmp/broadcastifyauth.txt | sed -i 's/$.ajaxSetup({ headers: { "webAuth": "//g' /var/tmp/broadcastifyauth.txt`
pta=`cat /var/tmp/broadcastifyauth.txt | sed -i 's/" }});//g' /var/tmp/broadcastifyauth.txt`
auth=`cat /var/tmp/broadcastifyauth.txt`
echo $auth
curl "https://www.broadcastify.com/listen/webpl.php?feedId=" --request POST --header "webAuth: $auth" --data 't=14' >/var/tmp/broadcastify.txt
pta=`cat /var/tmp/broadcastify.txt | grep -o 'http://[^"]*' > /var/tmp/broadcastify.b.txt`
pta=`cat /var/tmp/broadcastify.b.txt`
echo $pta
#pta=`cat /var/tmp/broadcastify.txt | sed -n '/<audio/s/^.*<audio width="300px" id="mePlayer_" src="\([^"]*\)".*//p' > /var/tmp/broadcastify.b.txt`
#ptb=`cat /var/tmp/broadcastify.b.txt`
#echo $ptb
这是它的输出:
root@na01:/etc/asterisk/scripts/music# ./broadcastify.sh 30185
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 9175 100 9175 0 0 51843 0 --:--:-- --:--:-- --:--:-- 52130
74f440ad812f0cc2192ab782e27608cc
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 946 0 942 100 4 3851 16 --:--:-- --:--:-- --:--:-- 3844
http://relay.broadcastify.com/b94hfrp5k1s0tvy.mp3?xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ
有效!
原始 HTML 文档中不存在 mp3 URL — 它是后来由 JavaScript 代码添加到 DOM 中的。这就是为什么您无法在 "View page source," 中找到它但可以在 "Inspect element."
中找到它的原因
如果你 运行 curl https://www.broadcastify.com/listen/feed/30185/web
,你会在中间某处看到以下内容:
<div id="fp" width="300px"></div>
<script>
$.ajaxSetup({ headers: { "webAuth": "74f440ad812f0cc2192ab782e27608cc" }});
$('#fp').load('/listen/webpl.php?feedId=30185',{t:14});
</script>
请特别注意,它将内容(使用 jQuery .load)加载到上面最初为空的 <div id="fp">
中。当您使用 "Inspect element" 查找音频播放器时,您会发现它位于 div.
中
在尝试使用 curl 重现此请求之前,我查看了开发人员工具的“网络”选项卡,看看浏览器做了什么。过滤 "listen," 我找到了 webpl.php
请求。以下是 "Headers" 选项卡中的相关信息:
- URL:
https://www.broadcastify.com/listen/webpl.php?feedId=30185
- 要求
- POST /listen/webpl.php HTTP/1.1
- 内容类型:application/x-www-form-urlencoded
- webAuth: 74f440ad812f0cc2192ab782e27608cc
- 查询字符串参数
- feedId: 30185
- 请求数据
- MIME 类型:application/x-www-form-urlencoded
- t: 14
让我们用 curl 重现这个请求:
curl 'https://www.broadcastify.com/listen/webpl.php?feedId=30185' \
--request POST \
--header 'webAuth: 74f440ad812f0cc2192ab782e27608cc' \
--data 't=14'
结果如下:
<script src="/scripts/me_4.2.9/mediaelement-and-player.min.js"></script>
<link rel="stylesheet" href="/scripts/me_4.2.9/mediaelementplayer.min.css"/>
<audio width="300px" id="mePlayer_30185" src="http://relay.broadcastify.com/9wzfd3hrpyctvqx.mp3?xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ" type="audio/mp3" controls="controls"
autoplay="true">
</audio>
<script>
$('audio').mediaelementplayer({
features: ['playpause', 'current', 'volume'],
error: function () {
alert("Feed has disconnected from the server. This could be due to a power outage, network connection problem, or server problem. Click OK to restart the player. If the player fails to connect then the feed might be down for an extended timeframe.");
location.reload();
}
});
</script>
<br />
<div class="c">If the feed does not automatically play, click or touch the play icon in the player above.</div>
<audio>
标签的 src
属性中有您的 mp3 link。如果我们尝试获取它:
$ curl http://relay.broadcastify.com/9wzfd3hrpyctvqx.mp3?xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ
Moved Temporarily. Redirecting to http://audio13.broadcastify.com/9wzfd3hrpyctvqx.mp3?nocache=2623053&xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ
如果您尝试访问 URL(或带有 -L
的原始访问,指示 curl 遵循重定向),mp3 流将开始打印到您的终端一堆废话
因此,您的 shell 脚本应该命中 /listen/webpl.php
端点,而不是尝试抓取网络播放器 HTML 页面。或者可能只是抓取页面以首先获取 webAuth 令牌。
更新
为了响应您使用 shell 脚本进行的更新,这里有一个简化的脚本,它执行相同的操作并且还删除了 "Moved Temporarily" 前缀以仅获取音频 url。请注意,不需要使用临时文件,$(...)
语法优于 `...`
语法:
#!/bin/bash
# I always start my scripts with this. See https://sipb.mit.edu/doc/safe-shell/
set -eufo pipefail
auth=$(curl -s "https://www.broadcastify.com/listen/feed//web" \
| grep webAuth \
| head -n 1 \
| sed 's/^.*"webAuth": "//;s/".*$//')
relay_url=$(curl -s "https://www.broadcastify.com/listen/webpl.php?feedId=" \
-H "webAuth: $auth" -d 't=14' \
| grep -o 'http://[^"]*')
audio_url=$(curl -s "$relay_url" | cut -d' ' -f5)
echo "$audio_url"
我正在尝试为我在 Broadcastify 上找到的一些扫描仪设置流。问题是他们使用的 URLs 是动态的,并且一次只有几个小时是相同的。我想创建一个 shell 脚本,它可以简单地扫描访问流的页面(它确实有一个静态 URL)和 return 当前 URL流,然后可以将其馈送到音频播放器。
例如,现在 https://www.broadcastify.com/listen/feed/30185/web has a stream at http://audio12.broadcastify.com/kq2ydfr1jz98shw.mp3
的以下流但是,该流 link 只会在短时间内有效。我需要像上面那样的 MP3 流。
我对 shell 脚本编写的经验很少,所以我想知道最好的方法是什么。具体来说,我的第一个问题是,如果我只是 "View page source" 并搜索 "mp3",则没有结果。我只能通过检查元素(F12 开发人员工具)找到 URL,例如,在 Chrome 中,转到应用程序 → 框架 → 媒体。我以为我可以在过去的音频播放器上做一个 "view frame source",但现在没有那个选项。
我想我可以使用 grep 如果我能够 CURL 源代码,但我不确定我需要什么 CURL 在这里,如果这有意义的话。
更新
感谢 mk12 的见解。基于此,这是我的 shell 脚本:
#!/bin/bash
curl "https://www.broadcastify.com/listen/feed//web" | grep webAuth > /var/tmp/broadcastifyauth.txt
pta=`cat /var/tmp/broadcastifyauth.txt | sed -i 's/$.ajaxSetup({ headers: { "webAuth": "//g' /var/tmp/broadcastifyauth.txt`
pta=`cat /var/tmp/broadcastifyauth.txt | sed -i 's/" }});//g' /var/tmp/broadcastifyauth.txt`
auth=`cat /var/tmp/broadcastifyauth.txt`
echo $auth
curl "https://www.broadcastify.com/listen/webpl.php?feedId=" --request POST --header "webAuth: $auth" --data 't=14' >/var/tmp/broadcastify.txt
pta=`cat /var/tmp/broadcastify.txt | grep -o 'http://[^"]*' > /var/tmp/broadcastify.b.txt`
pta=`cat /var/tmp/broadcastify.b.txt`
echo $pta
#pta=`cat /var/tmp/broadcastify.txt | sed -n '/<audio/s/^.*<audio width="300px" id="mePlayer_" src="\([^"]*\)".*//p' > /var/tmp/broadcastify.b.txt`
#ptb=`cat /var/tmp/broadcastify.b.txt`
#echo $ptb
这是它的输出:
root@na01:/etc/asterisk/scripts/music# ./broadcastify.sh 30185
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 9175 100 9175 0 0 51843 0 --:--:-- --:--:-- --:--:-- 52130
74f440ad812f0cc2192ab782e27608cc
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 946 0 942 100 4 3851 16 --:--:-- --:--:-- --:--:-- 3844
http://relay.broadcastify.com/b94hfrp5k1s0tvy.mp3?xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ
有效!
原始 HTML 文档中不存在 mp3 URL — 它是后来由 JavaScript 代码添加到 DOM 中的。这就是为什么您无法在 "View page source," 中找到它但可以在 "Inspect element."
中找到它的原因如果你 运行 curl https://www.broadcastify.com/listen/feed/30185/web
,你会在中间某处看到以下内容:
<div id="fp" width="300px"></div>
<script>
$.ajaxSetup({ headers: { "webAuth": "74f440ad812f0cc2192ab782e27608cc" }});
$('#fp').load('/listen/webpl.php?feedId=30185',{t:14});
</script>
请特别注意,它将内容(使用 jQuery .load)加载到上面最初为空的 <div id="fp">
中。当您使用 "Inspect element" 查找音频播放器时,您会发现它位于 div.
在尝试使用 curl 重现此请求之前,我查看了开发人员工具的“网络”选项卡,看看浏览器做了什么。过滤 "listen," 我找到了 webpl.php
请求。以下是 "Headers" 选项卡中的相关信息:
- URL:
https://www.broadcastify.com/listen/webpl.php?feedId=30185
- 要求
- POST /listen/webpl.php HTTP/1.1
- 内容类型:application/x-www-form-urlencoded
- webAuth: 74f440ad812f0cc2192ab782e27608cc
- 查询字符串参数
- feedId: 30185
- 请求数据
- MIME 类型:application/x-www-form-urlencoded
- t: 14
让我们用 curl 重现这个请求:
curl 'https://www.broadcastify.com/listen/webpl.php?feedId=30185' \
--request POST \
--header 'webAuth: 74f440ad812f0cc2192ab782e27608cc' \
--data 't=14'
结果如下:
<script src="/scripts/me_4.2.9/mediaelement-and-player.min.js"></script>
<link rel="stylesheet" href="/scripts/me_4.2.9/mediaelementplayer.min.css"/>
<audio width="300px" id="mePlayer_30185" src="http://relay.broadcastify.com/9wzfd3hrpyctvqx.mp3?xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ" type="audio/mp3" controls="controls"
autoplay="true">
</audio>
<script>
$('audio').mediaelementplayer({
features: ['playpause', 'current', 'volume'],
error: function () {
alert("Feed has disconnected from the server. This could be due to a power outage, network connection problem, or server problem. Click OK to restart the player. If the player fails to connect then the feed might be down for an extended timeframe.");
location.reload();
}
});
</script>
<br />
<div class="c">If the feed does not automatically play, click or touch the play icon in the player above.</div>
<audio>
标签的 src
属性中有您的 mp3 link。如果我们尝试获取它:
$ curl http://relay.broadcastify.com/9wzfd3hrpyctvqx.mp3?xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ
Moved Temporarily. Redirecting to http://audio13.broadcastify.com/9wzfd3hrpyctvqx.mp3?nocache=2623053&xan=DCJP4HvtwMoXdH9HvtwMJ5vv342DfleDptcoX3dH9H48vtwMJ
如果您尝试访问 URL(或带有 -L
的原始访问,指示 curl 遵循重定向),mp3 流将开始打印到您的终端一堆废话
因此,您的 shell 脚本应该命中 /listen/webpl.php
端点,而不是尝试抓取网络播放器 HTML 页面。或者可能只是抓取页面以首先获取 webAuth 令牌。
更新
为了响应您使用 shell 脚本进行的更新,这里有一个简化的脚本,它执行相同的操作并且还删除了 "Moved Temporarily" 前缀以仅获取音频 url。请注意,不需要使用临时文件,$(...)
语法优于 `...`
语法:
#!/bin/bash
# I always start my scripts with this. See https://sipb.mit.edu/doc/safe-shell/
set -eufo pipefail
auth=$(curl -s "https://www.broadcastify.com/listen/feed//web" \
| grep webAuth \
| head -n 1 \
| sed 's/^.*"webAuth": "//;s/".*$//')
relay_url=$(curl -s "https://www.broadcastify.com/listen/webpl.php?feedId=" \
-H "webAuth: $auth" -d 't=14' \
| grep -o 'http://[^"]*')
audio_url=$(curl -s "$relay_url" | cut -d' ' -f5)
echo "$audio_url"