python:爬虫-selenium,BeautifulSoup,urllib

前言:自学,第一个想到的就是爬虫 。前面用C#做了爬虫,可随意下载全职高手的有声小说的集数(ps:这有声小说在授权应用里收费的) 。想写个 的,以简洁语法著称,相信代码量不会比用C#实现多 。
我用的为开发工具,装它的时候就把环境一起安装了 。很方便,想要安装包,在VS里工具--环境窗口,在 [概述] 框中选择 [包(PyPI)] 输入想要安装的包名字,就会出现 让你选择 pip xxxx 命令安装包 。
此次爬虫用到的是,加上+ 可模拟谷歌或者火狐浏览器等运行网站,抓取网页数据,根据链接下载文件 。
这里准备工作麻烦一点的是的安装,.exe下载地址,选择对版本 。
对于任何爬虫网站不管它有多复杂,嵌入了多少,总是会有迹可循的 。所以这里需要一点点技巧,找到想要的关键链接 。爬虫网站:有声听书吧(人家改了域名,改了运行规则,那可就没招了,据我所研究这个网站经常变域名) 。这网站很多乱入广告,资源每一集的链接都不一样,其真正的播放资源就在这些网页中,这里我只做了爬取 全职高手有声小说的资源 。另外最后用将其打包成exe了 。
直接上代码吧:
# -*- coding: utf-8 -*-from selenium import webdriverfrom bs4 import BeautifulSoupfrom selenium.webdriver.chrome.options import Optionsfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.common.by import Byimport sysfrom urllib import requestfrom urllib.parse import quoteimport ospath = ""dir = ""downEPList = []chrome_options = Options()chrome_options.add_argument('--headless')chrome_options.add_argument('log-level=3') #控制台输出只显示错误信息和自定义的输入输出driver = webdriver.Chrome('chromedriver.exe',chrome_options=chrome_options) #将exe文件放在.py文件同目录下def getDriverHttp(url):driver.get(url)driver.switch_to.frame("play") # 最重要的一步.切换iframe,id=paly的iframe才是关键资源的所在地wait = WebDriverWait(driver,10).until(lambda x: x.find_elements_by_css_selector('audio[src*="180e.ysts8.com"]')) #因为嵌入的iframe有加载延迟,所以这里通过定时查找关键元素,让其完全渲染页面之后在跑下面的代码soup = BeautifulSoup(driver.page_source, "html.parser")return soupdef getVideoUrl(url):soup = getDriverHttp(url)miPlayer = soup.find('div',id='thisbody')url = miPlayer.find('audio').get('src') #爬取资源的下载链接return urldef download(counter,downPath):if downPath:ret1 = quote(downPath, safe=";/?:@&=+$-.,", encoding="utf-8") #链接有中文,所以这里必须要将链接进行解析print('第' + str(counter) + '集开始下载...')try:request.urlretrieve(ret1, dir +'\\'+ str(counter) + '.mp3') #资源的下载链接并不是固定不变的,会定时更新keyfsize = round(os.path.getsize(dir +'\\'+ str(counter) + '.mp3')/1024,1) #所以这里会进行判断,如果下载的资源大小小于某个值就视为链接失效,if fsize>10:print('第' + str(counter) + '集下载完毕')return Trueelse:path = getVideoUrl(u'https://www.ysts8.com/play_14810_49_1_1.html') #然后这里就会重新去拿取资源下载链接,并且根据此方法返回的bool值,将没下在成功的存入临时数据return Falseexcept Exception as e:print('第' + str(counter) + '集下载出错:',e)return Falseelse:print('第' + str(counter) + '集无法下载')return Falsedef intChangeToStr(counter):if counter < 10:return "00" + str(counter)elifcounter < 100:return "0" + str(counter)else:return str(counter)if __name__ == '__main__':print("一共1280集")print("请输入你要保存的目录:")dir = input()while True:if not os.path.exists(dir):print("您输入的目录不存在,请重新输入:")dir = input()else:breakprint("请输入你要从哪一集开始下载:")startIn = input()while True:if startIn.isdigit() and int(startIn) >= 0:breakelse:print("开始集数-请输入正整数:")startIn = input()print("请输入你要下载的集数:")numIn = input()while True:if numIn.isdigit() and int(numIn) >= 0:breakelse:print("下载集数-请输入正整数:")numIn = input()path = getVideoUrl(u'https://www.ysts8.com/play_14810_49_1_1.html') #这是第一集的播放地址counter = int(startIn)while counter