利用 AJAX 与正则表达式批量采集优酷专辑视频信息
解决传统服务端脚本采集速度慢、资源消耗大的问题,本文介绍如何利用 JavaScript 结合 AJAX 技术实现异步批量采集优酷专辑中的视频数据。通过客户端本地执行网络请求与正则匹配,可显著降低延迟并提升吞吐量。
核心思路与技术优势
传统的 VB.NET 或类似服务端采集方案在生成网络连接和处理正则匹配时存在较大开销,单页面采集通常需 1 秒左右。相比之下,使用 JavaScript 在浏览器端进行 AJAX 异步请求,可以将计算负载转移至用户终端。这种方案的优势在于:
- 低延迟:纯客户端脚本执行,无需等待服务器响应循环,单页采集时间缩短至 0.3~0.5 秒(取决于硬件配置)。
- 异步并发:利用 XMLHttpRequest 的非阻塞特性,实现不间断的数据流式获取。
- 轻量级:无需依赖复杂的后端框架,直接操作 DOM 和 HTML 源码即可提取结构化信息。
准备工作
由于涉及跨域请求限制,本代码需在支持 IE7 及以上版本的 Internet Explorer 环境测试,或通过本地修改允许跨域的浏览器插件/设置下运行。代码结构包含一个完整的 HTML 界面,输入控件用于指定专辑 URL,文本框用于显示结果,按钮用于控制流程。
关键操作顺序
第1步:定义全局状态与回调函数
首先初始化 XMLHttp 请求对象以及用于追踪当前播放列表 ID、已采集数量和暂停状态的变量。定义 wrt 函数用于将结果追加到显示区域,确保历史日志不被覆盖。
第2步:解析专辑 ID 并构建请求 URL
通过正则表达式从用户输入的完整专辑链接中提取出唯一的专辑标识符 listid。根据优酷的页面命名规则,构造分页 URL。例如,若专辑 ID 为 2350764,则第一页请求地址为 v.youku.com/v_playlist/f[listid]o1p1.html。
第3步:发起 AJAX GET 请求
使用 new XMLHttpRequest() 创建请求实例。设置 onreadystatechange 事件监听器指向回调函数。调用 open("GET", url, true) 建立异步连接,并通过 send(null) 发送请求。注意兼容性处理,旧版 IE 可能需要使用 ActiveXObject("Msxml2.XMLHTTP")。
第4步:解析返回的 HTML 内容
当请求状态为 4 (完成) 且 HTTP 状态码为 200 时,执行以下提取逻辑:
- 提取视频 ID:使用正则
/var\s+videoId\s*=\s*"(\d+)"\s*;/匹配 JavaScript 变量赋值语句,捕获数字部分。 - 提取视频标题:使用正则
/<title>(.+) - (.+) - 视频 - 优酷视频 - 在线观看<\/title>/匹配页面标题标签,捕获第二个分组作为视频名称。
第5步:判断是否继续循环
检查新提取的视频 ID 是否与上一个不同,以防重复采集同一视频。如果未触发暂停且仍有下一页(通过递增 nowid),则递归调用开始函数进入下一页;否则终止采集流程。
完整代码实现
以下是优化后的核心逻辑封装,保留了原有的作者声明及功能完整性。请注意,现代浏览器对同源策略有更严格的限制,实际部署时可能需要进行 CORS 头处理或使用油猴等用户脚本管理器注入。
<!--
夜闻香原创,转载请保留此信息,万分感谢!
博客: http://clso.cnblogs.com
主页: http://cleclso.cn
QQ:315514678 E-mail:clso#qq.com
欢迎技术交流! -->
<html>
<head>
<title>JavaScipt AJAX & 正则表达式 test</title>
<script type="text/javascript" language="javascript">
function wrt(s){
subret.value = s + "\n" + subret.value;
}
var objRequest; //定义一个XML请求对象
var previd = "", nowid = 0, listid = "", iscancel = false; //其他变量
function getlid(){
var listid_match = weburl.value.match(/playlist_show\/.*(?=id_(\d+)).*\.html$/i);
if(!listid_match){
return null;
} else {
return listid_match[1];
}
}
function retweb(){
if(objRequest.readyState == 4 && objRequest.status == 200){
// 获得回调
var webstr = objRequest.responseText;
// 提取视频ID
var vid_match = webstr.match(/var\s+videoId\s*=\s*"(\d+)"\s*;/);
var vid = vid_match ? vid_match[1] : null;
// 提取视频标题
var title_match = webstr.match(/<title>(.+) - (.+) - 视频 - 优酷视频 - 在线观看( - )?<\/title>/);
var vtitle = title_match ? title_match[2] : "未知标题";
if(vid) wrt(nowid + ":" + vtitle + "=" + vid);
if(previd == vid) return; //防止重复
previd = vid;
nowid += 1;
// 开始新循环
if(iscancel) return;
tstart();
} else {
// alert("回调失败!");
return;
}
}
function getweb(u){
objRequest = new XMLHttpRequest(); //兼容IE5&6: new ActiveXObject("Msxml2.XMLHTTP");
objRequest.onreadystatechange = retweb; //异步回调方法
objRequest.open("GET", u, true);
objRequest.send(null);
}
function tstart(){
if(listid==""){
listid=getlid();
}
url = "http://v.youku.com/v_playlist/f" + listid + "o1p" + nowid + ".html";
getweb(url);
}
</script>
</head>
<body>
<input type="text" id="weburl" value="http://www.youku.com/playlist_show/id_2350764.html" style="width:640" /><br />
<textarea id="subret" readonly="readonly" style="width:640; height:360;">#star</textarea>
<br/>
<input type=button value="开始提取专辑" onclick="if(iscancel)iscancel=false;tstart();" />
<input type=button value="清除文本" onclick="subret.value='';nowid =0;preid='';listid='';" />
<input type=button value="暂停" onclick="iscancel=true;" />
</body>
</html>
注意事项与局限
该方案依赖于优酷前端页面的静态 HTML 结构。随着网站改版,正则表达式的匹配规则可能需要调整。此外,由于是纯客户端脚本,其稳定性受限于浏览器的兼容性设置和网络环境的波动。对于生产环境的大规模数据采集,建议使用专门的爬取框架如 Selenium 或 Scrapy 以获得更好的稳定性和反爬应对能力。
以上就是利用 AJAX 与正则表达式批量采集优酷专辑视频及信息的详细内容,更多关于 JavaScript 网页抓取的技术资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









