今天,我听见一首不错的老歌,名字是《偏偏喜欢你》。陈百强大哥唱的,人如其名确实很强!我敬佩的粤语歌手之一。然后,我太难了,整了3个小时,对于我一个学了1个月爬虫的老司机来说真的很尴尬。不过,这次我没有用Selenium库爬取,如果用selenium会很快搞定,不会有问题。下面我们一起体验取经的感觉!!
完整代码:
#encoding = "utf-8"
#Author:"Mr.Pan_学狂"
#start time:2021/2/22/22:30
#finish time:2021/2/23/00:40
#requests库爬取 陈百强 《偏偏喜欢你》
from selenium import webdriver
from lxml import etree
import re
import requests
from urllib.request import urlretrieve
import time
import random
import os
url = 'https://haokan.baidu.com/v?vid=17139400655098661254&pd=bjh&fr=bjhauthor&type=video'
html = requests.get(url,headers=headers).text
#print(html)
#reg = r'<video class="" autoplay="" tabindex="2" mediatype="video" crossorigin="anonymous" src="(.*?)"</video>'video不存在,原因可能是JS的异步加载,网页是动态的。
reg = '"url":(.*?),"videoBps":352'
url = re.findall(reg,html)[0]
reg2 = '<h1 class="videoinfo-title">(.*?)</h1>'
video_name = re.findall(reg2,html)[0]
print(video_name)
print(url)
reg3 = '"(.*?)"'
url2 = re.findall(reg3,url)[0]#将url的引号处理掉!!因为直接用requests访问会进行引号嵌套出错!!
print(url2)#需要对url2进行处理,因为url2有反斜杠访问会出错!!
ls = []
for i in url2:
ls.append(i)
#print(ls)
while True:
if '\\' in ls:
ls.remove('\\')
else:
break
print(ls)
url3 = ''
for l in ls:
url3 += l
print('url3:',url3)
os.mkdir('E:/Example')
video = requests.get(url3,headers=headers)
with open(r'E:/Example/{}.mp4'.format(video_name),'wb+') as f:
f.write(video.content)
下面,我要讲故事了,首先还是老套路,话不多说一言不合就是干,上来就是各种爬虫需要的库。
我们先去这个视频的网址检查一下元素,如下图:
如果用selenium库爬取这个视频会非常简便,因为直接提取xpath就行了。不过,我们仅用requests和re(正则)提取会麻烦不少,因为会出现下面的状况,按照通常的套路,src是我们正则需要提取的内容。不过这里这个web页面跟我们开了一个小玩笑,因为这个video标签源代码里面不存在(我认为是JS加载出来的,动态的)。这样提取只能得到空列表,什么也没有。做到这里的时候相信大部分刚入门的同志会直接放弃,不要灰心我们还有希望!
的结果,只能是空列表,如下图:
不过,我仔细思考如果这个页面没有这个视频的链接,那肯定链接不过去视频,肯定在这个页面能找到,也就是视频的链接在页面源代码里面可以找到。所以,我直接在pycharm编辑器中按组合键Ctrl+F检查源代码里面是否存在mp4这个词,如下图:
我们会发现又四个mp4对应的链接,我挨个点进去看,发现其实四个都是一样指向视频的链接。然后,我们只要想办法提取其中一个链接就行了。我选择了videoBps的value是352的链接用正则表达式来提取,如下图:
运行结果:
哈哈哈哈哈哈,此处我真的是忍不住笑了。你是不是正高兴爬到链接了??却是无法访问的字符串。。。。求当时我的心里阴影面积S∈(-∞,+∞)。估计走到这一步,又有一些有一点爬虫经验的小伙伴当场放弃直接开哭。不过,我们要相信自己,坚信希望!
不急,我们的re库6着呢!分分钟给你搞定,运行又高效!如下图:
运行结果,如下图:
引号去除了,是不是很开心?哈哈哈哈哈哈,我又笑了。因为,还没有完哦,取经没有这么容易的。。这个链接你还是不能拿去给requests访问,因为存在转义符\,导致报错,内心当时直接崩溃!搞了半天最后就这样??就这??如下图:
淡定!我们不慌仔细观察会发现一个每个转义符\都在/前面,想办法用/替换转义符就行了,我试过了,没有用!!所以,又试了其它的方法,直到最后,我想到了拆散后重组的思想(有点像是分布式),我先把这个有问题的链接拆散再重组的时候不加入转义符就行了!顺着这个思路,我最后找到了出路,成功解决问题!!
说时迟那时快,只见我定义一个列表(容器),然后拆散后放进列表中,如下图:
从这个类似摩斯密码的图中,我们可以看出转义符\在列表(容器)中变成了\,有搞头!
接着,我们需要对列表(容器)内不需要的\使用列表的方法(函数)remove删除。如下图:
哈哈哈哈,终于要取到真经了,高兴!下面的操作就相对简单了,就是定义一个中间变量把列表元素(拆散的单个字符)组合起来,如下图:
结果,very nice!!
这就是最后我们需要的视频链接,散发着胜利的蓝光!!我们点进去看一下:
之后,我们还需要得到视频名称,我们用正则在原始的页面源代码中提取,如下图:
运行结果如下图:
现在,我们视频地址有了,视频名称也有了,可以使用os模块创建一个Example文件夹在E盘用于存放视频,然后开始套路的请求视频地址了,如下图:
大家可以看见我的E盘现在是没有Example文件夹(目录)的,如下图:
运行结果:
自动创建了Example文件夹(目录),并且将视频也放进去了,如下图:
我们点击播放一下,截个图,如下图:
为了陈百强大哥的经典歌曲,去取一次经又何妨??我们要相信自己,一切困难都会慢慢好起来的。
最后,感谢大家前来观看鄙人的文章,文中或有诸多不妥之处,还望指出和海涵。