B站视屏爬取

前几天写了一个上网爬取滑稽色图片(手动滑稽)的小爬虫,今天,突发奇想,想爬取视频看看。


以B站敖厂长的视频实验:

1.找到要爬取视频

B站视屏爬取_第1张图片


2.右键查看源码:

B站视屏爬取_第2张图片


与审查元素对比找到这里:EmbedPlayer('player', "//static.hdslb.com/play.swf", "cid=26379702&aid=16164197&pre_ad=0");猜测这里调用的js的函数是嵌入播放器到这个里面;


3.去找页面引用的js里找EmbedPlayer()函数,发现在这个https://static.hdslb.com/js/core-v5/page.arc.js文件里;


B站视屏爬取_第3张图片


虽然压缩了,但是网上有反压缩工具,轻松反压缩:


B站视屏爬取_第4张图片

4.读了下js代码,发现"cid=26379702&aid=16164197&pre_ad=0"参数,也就是视频的资源id信息被切好封装到g中,然后

通过swfobject.embedSWF向"//static.hdslb.com/play.swf"请求过去了。其实看到这个函数的调用形式就该猜到,我还是太菜了。

5.知道视频地址了,我就找过去(https://static.hdslb.com/play.swf?cid=26379702&aid=16164197&pre_ad=0)看看,果然


B站视屏爬取_第5张图片

6.接下来开始爬取,代码先不贴了,因为又走弯路了。这个url爬过来的是一个swf的壳,也就是播放器的样式的壳,即这个玩意儿:

https://static.hdslb.com/play.swf,我早该想到的。。。

B站视屏爬取_第6张图片

7.没有获取到视频数据,猜测是这个swf自己去向服务器请求的。但swf不可能查看源码,所以fiddler抓包去吧。


B站视屏爬取_第7张图片

成功抓到flv视频流,看看这个域名中的cn-hnjz,莫不是中国湖南株洲(我这边是湖南长沙),这可能是b站在湖南地区的服务器结点,这种大型网站毕竟都是分布式的。


8.接下来向着这个URL爬过啊!mmp,403 forbidden。。。

其实也就是Referer没加上,被拦了。


9.在请求的request报头上加上Referer: https://static.hdslb.com/play.swf?cid=26379702&aid=16164197&pre_ad=0,然后,爬过去!

B站视屏爬取_第8张图片

ok!下面是Java代码:


import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;


public class Main {


public static void main(String[] args) {
// TODO Auto-generated method stub

String urlstr="https://cn-hnjz-cu-v-02.acgvideo.com/vg1/6/8c/26379702-1-80.flv?expires=1510310100&platform=pc&ssig=-KvYiV9XoT1ggHN9ArX-zQ&oi=974402195&nfa=oHqC5M/eAoZsl45MAwqMEQ==&dynamic=1&hfa=2016823259&hfb=Yjk5ZmZjM2M1YzY4ZjAwYTMzMTIzYmIyNWY4ODJkNWI=";
File file=new File("D:/text/ccf/spider/webpage/swf/"+"aa.f
lv");
if(!file.exists()){
System.out.println("@创建文件:"+"aa.
flv");
try {
file.createNewFile();
} catch (IOException e) {
System.out.println("@创建文件异常:");
System.out.println("@"+e);
}
}
else
return;
//访问该URL,写入其HTML到对应文件中
try{
URL url = new URL(urlstr);
URLConnection con = url.openConnection();
con.setConnectTimeout(5*1000);
con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
con.setRequestProperty("Referer", "https://static.hdslb.com/play.swf?cid=26379702&aid=16164197&pre_ad=0");

BufferedInputStream is = new BufferedInputStream(con.getInputStream());
FileOutputStream fs = new FileOutputStream(file);

try{
byte[] bs = new byte[1024];
int len;
while ((len = is.read(bs)) != -1){
fs.write(bs, 0, len);
}
}
catch(Exception e){
System.out.println("@IO异常:");
System.out.println("@"+e);
}
finally{
is.close();
fs.close();
System.out.println("@文件写入结束。");
}

}
catch(Exception e){
System.out.println("@请求URL异常:");
System.out.println("@"+e);
}
}
}

好了,虽然一个视频爬取解决了,但在抓包获取视频url的哪一步上怎么让程序自己解决呢,批量爬取怎么实现,swf里的URL数据有没有办法读出来呢?下次再试试吧!

你可能感兴趣的:(计算机网络)