对于多线程我在这使用的是threading模块,反正挺好用的,这个模块是有大致格式的,比如下面的先定义一个myspider类,然后__init__函数,run函数了,这些都是必须的。
首先导入我们需要的模块 ,os是为了创建文件夹,redis是为了将视频链接导入redis来进行去重操作,redis需要提前打开,没安装的可以去搜索一下教程,安装好之后,先cmd进入redis下载的文件夹下,然后输入redis-server.exe redis.windows.conf就行了,能够看见一个很大的立方体。
import threading
import requests
import redis
import os
#初始化StrictRedis()函数
client = redis.StrictRedis()
然后找到需要抓取的视频的接口,通过浏览器的network功能可以看到,记住选上右上角的持续日志,别的浏览器可能是Preserver log,这个功能可以让你在网页接受到数据的时候,链接在依次出现在下面,非常好用,我选择的是火狐浏览器,用习惯了。从下面可以看到,在我点击播放按钮的时候,当播放一会后,下面就出现很多个mp2t类型的数据,好几百kb,也挺大的,猜想是视频的一部分,点进去之后,的确是这样,一个视频分为好多个ts,ts也是视频格式的一种,能直接打开观看。在视频播放完后,发现共有41个ts格式的文件,这些应该就是全部视频的内容了,我们所需要的就是把这41个ts全部抓取出来。
开始伪装浏览器
#视频的url的共同部分,但是不完整
Url = 'https://ycdncn01.weilekangnet.com:59666/data5/AC228D3093E44F58/BD672E9808DC5CEE/480p/0out480p'
#伪装浏览器
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4098.3 Safari/537.36'}
上面哪个Url,是不完整的,因为是41个,发现是在这个网址的后面添加数字0,1,2…40就是完整的。
#创建文件夹,如果存在就不创建
os.makedirs('短视频',exist_ok=True)
先创建一个文件夹保存视频,这个文件夹自动创建在pycharm软件或者py所在的文件下。
#引入父类 threading.Thread
class myspider(threading.Thread):
def __init__(self,name):
#引用父类主函数qw
threading.Thread.__init__(self)
self.name = name
#线程主要运行函数
def run(self) :
print('线程:'+self.name+'开始运行')
#运行爬虫函数
spider(self.name)
上面这个代码就是多线程的精髓了,格式是固定的,记住就行,只有self.name可以选择变换,run是多线程运行的函数,我们可以把爬虫函数spider放在里面进行调用,然后再去认真编写爬虫spider函数。
def spider(name):
#发现视频分为40个部分,类型为ts格式
for i in range(0, 41):
#组装视频的完整接口
a = Url + str(i) + '.ts'
# 将所有的url存放到redis的集合里面,进行去重,如果能够导入进去,说明这个url还没有爬取,那么就进行抓取
if client.sadd('URL_list', a):
#获取视频为字节型
video = requests.get(a,headers=headers).content
#给视频命名
names = a.split('/')[-1]
#下载进文件夹里面
with open(os.path.join('短视频',names),'wb') as f:
f.write(video)
爬虫函数,代码里面写的也很详细了,这里就不多说了。主要就是有一个os.path.join(‘A’,‘B’),A是文件夹的名字,B是保存后视频的名字。
#线程持续进行
over = []
#初始化线程操作,定义三个线程
for i in range(1,4):
#线程命名
threadname = myspider(i)
#线程开始执行
threadname.start()
#线程加入到持续运行列表里面
over.append(threadname)
#线程持续运行,并且主线程不结束,使用的是join方法
for i in over:
i.join()
#所有线程结束后,主线程结束
print('全部线程结束')
上面的就是最后的代码了,我分为了三个线程进行爬取,start()方法是启动线程,join()方法是让线程一直进行着,这些方法也都是必须有的。三个线程,三个start,三个join。
下面放上全部代码
import threading
import requests
import redis
import os
#初始化StrictRedis()函数
client = redis.StrictRedis()
#视频的url的共同部分,但是不完整
Url = 'https://ycdncn01.weilekangnet.com:59666/data5/AC228D3093E44F58/BD672E9808DC5CEE/480p/0out480p'
#伪装浏览器
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4098.3 Safari/537.36'}
#创建文件夹,如果存在就不创建
os.makedirs('短视频',exist_ok=True)
#引入父类 threading.Thread
class myspider(threading.Thread):
def __init__(self,name):
#引用父类主函数qw
threading.Thread.__init__(self)
self.name = name
#线程主要运行函数
def run(self) :
print('线程:'+self.name+'开始运行')
#运行爬虫函数
spider(self.name)
def spider(name):
#发现视频分为40个部分,类型为ts格式
for i in range(0, 41):
#组装视频的完整接口
a = Url + str(i) + '.ts'
# 将所有的url存放到redis的集合里面,进行去重,如果能够导入进去,说明这个url还没有爬取,那么就进行抓取
if client.sadd('URL_list', a):
#获取视频为字节型
video = requests.get(a,headers=headers).content
#给视频命名
names = a.split('/')[-1]
#下载进文件夹里面
with open(os.path.join('短视频',names),'wb') as f:
f.write(video)
#当一个线程找不到需要抓取的url时,线程结束
print('线程:'+name+'结束')
#线程持续进行
over = []
#初始化线程操作,定义三个线程
for i in range(1,4):
#线程命名
threadname = myspider(i)
#线程开始执行
threadname.start()
#线程加入到持续运行列表里面
over.append(threadname)
#线程持续运行,并且主线程不结束,使用的是join方法
for i in over:
i.join()
#所有线程结束后,主线程结束
print('全部线程结束')
然后是抓取之后的成果。
我抓取的视频是这个的 ,心血来潮为室友谋福利,删掉中间的星号,https://www.myeeoet64hly1zy.top:5998****0/index.php/vod/play/id/107644/sid/1/nid/1.html 😃
如果需要将所有的ts类合并成一个完整视频,可以去下载一个TS合并工具,在cmd里面输入cpoy /b 的方法合并后容易出现错误,打不开或者很卡。
软件很小,大约1M,百度也有使用教程,很简单。
一起学习,一起加油!
2019/12/30 --jiangzhan