python selenium 下载 某听书网一部书籍
最近听书,喜马拉雅等收费,终于在某个网找到一部免费的,可以在线听。此网站没有app,手机提供网页方式。本来打算将就听了,结果发现手机网页太多黄色广告,加上最近在研究scrapy,就尝试爬一下。
按步骤说一下方法和遇到的困难及解决方案。
0.由于此网站播放页面,采用audio控件播放,每个链接是动态链接,经过多次研究好像是调用了一个加密了的js代码,动态生成客户端cookie。当访问服务器时,服务器检测此cookie,返回动态的音频链接。点击控件播放时候,根据cookie检测链接是否有效,如果无效返回一个几秒的音频提示错误。如果短时间手动刷新或者其他方式都无法获得有效链接。
1.scrapy失败
开始用scrapy爬网页后,调用urllib去下载。后来多次失败,发现了cookie。以为是scrapy的urllib没有带cookie导致的,就使用scrapy的filedownloadmiddleware去下载,还是失败。
后来又发现cookie不是服务器返回的。研究很久发现,cookie是客户端js生成的,scrapy无法调用,加上sojson.v5我无法破解,故放弃转selenium。
2.发现selenium可以调用chrome实现。遂开始:
1.初始化浏览器,设置默认保存文件夹
def init_chrome():# 自定义下载配置chromeOptions = webdriver.ChromeOptions()chromeOptions.add_argument(r"user-data-dir=C:\Users\Admin\AppData\Local\Google\Chrome\User Data")prefs = {"download.default_directory": download_path,'download.prompt_for_download': False, # 是否弹窗询问"download.directory_upgrade": False, # 还不清楚这个配置是干嘛的'profile.default_content_setting_values': {'images': 2,}, # 不加载图片"safebrowsing.enabled": False # 是否提示安全警告}chromeOptions.add_experimental_option("prefs", prefs)browser = webdriver.Chrome(r"D:\TOOLS\chromedriver_win32\chromedriver.exe", chrome_options=chromeOptions)return browser
2.主循环,先进来目录(因为点每集的链接都是js生成了cookie再去服务器访问的,所以不能直接进)。这里pages是我下载剩下页面的数据(尽管尽量模拟正常人的操作,结果还是会有失败的,后面会说)
browser.get("http://www.audio****.com/book/1040.html") # 进来目录print("sleep 10")time.sleep(10)pages = [17, 18, 19, 22, 23, 26, 30, 34, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92]retry = 0for page in pages:while retry < 5:goto_sub_page(browser, page) # 进来每集res = get_audio(browser, page) # 下载音频 return_listpage_from_subpage(browser) # 返回目录 if res:retry = 0breakelse:retry += 1print('refresh and try again:' + str(retry))retry = 0browser.close()
3.进来每集页面,也必须默认点击链接进入,否则cookie可能不对
def goto_sub_page(browser, page):sub_page = browser.find_element_by_xpath('//*[@id="wrapper"]/div/div/div/div[4]/div/ul/li[' + str(page) + ']/a')sub_page.click()print("goto sub page:" + str(page) + " and sleep 10")time.sleep(10)
4.下载音频
这里有几个坑要处理,
4.1不能直接使用audio的source链接去下载,因为没有客户端js代码生成的cookie,即使拿到链接下载也是无效文件
4.2为此必须使用audio去下载,研究很久发现audio无法直接下载,只有右键弹出菜单后选择另外文件,然后操作chrome存盘。
另外chrome即使设置了默认保存位置和下载不提示,还是会弹出保存文件的对话框。因为是链接不是同源的(url不是同一个服务器)。
后来考虑使用生成一个超链接,模拟click,结果发现也不行(a标签加了download属性就支持下载,但是还是要同源才行)
4.3 selenium可以控制audio弹出右键菜单,但是不支持发生按键,只有使用win32api模拟按键,按顺序发V另存,发送Enter控制chrome存盘。
def get_audio(browser, page):try:# if not os.path.exists("audio"):# os.mkdir("audio")if check_page_file_exist(page): # 如果文件已存在就跳过print("file exist ,goto next page")return Trueaudio_control = browser.find_element_by_tag_name("audio") # 找到audio控件audio_control.click()src_ontrol = browser.find_element_by_tag_name("source")file_url = src_ontrol.get_attribute("src")file_name = str(file_url).split('/')[-1]file_name = file_name.replace('.m4a', '.mp3')print("\nfile_name:")print(file_name)browser.execute_script("return arguments[0].play();", audio_control) # 模拟点击播放print("after play sleep 15")time.sleep(15)webdriver.ActionChains(browser).context_click(audio_control).perform() # 弹出audio右键菜单print("after right menu sleep 5")time.sleep(5)win32api.keybd_event(86, 0, 0) # 发生按键V和回车,让chrome存盘win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0)print("after send key V sleep 10")time.sleep(10)win32api.keybd_event(13, 0, 0)win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)print("after send key Enter sleep 10")print('wait 5min before next step')time.sleep(5 * 60)file_name = download_path + file_nametemp_file_name = file_name + ".crdownload" # 检查chrome下载是否结束new_file_name = download_path + str(page) + ".mp3"while os.path.exists(temp_file_name):print("wait for download finish")time.sleep(10)if os.path.exists(file_name): # 根据文件大小判断下载是否是有效文件size = os.path.getsize(file_name)if size < 15192:return Falseelse:os.rename(file_name, new_file_name)print('wait 14min before next page')time.sleep(14 * 60)print('go to next page')return Trueelse:return Falseexcept Exception as e:print(e)return False
5.另外一个坑,由于我在服务器上用远程桌面测试的,结果远程桌面一断,发送按键的功能就失效。后来编一个批处理,使用批处理来端口远程桌面才行。(三条语句是一个意思,只是防止有多个远程桌面的会话,一起处理了)
参考链接 解决Windows远程桌面断开后模拟按键失效,windows断开远程连接之后不渲染
@%windir%\System32\tscon.exe 0 /dest:console
@%windir%\System32\tscon.exe 1 /dest:console
@%windir%\System32\tscon.exe 2 /dest:console
6.即使采用上述手段,每集下载也尽量延时,还是有些页面下载报错音频(94集有20集),真是无语了,不知道这个网站的用户咋个正常使用下去啊。
上述解决方法参考了很多文章,由于当时忙解决问题,没有记录参考链接,实在抱歉,在此谢谢这些作者。
python selenium 下载 某听书网一部书籍相关推荐
- Python Tkinter实现一个听书神器
Python Tkinter实现一个听书神器 前提条件 相关介绍 Tkinter 组件 实验环境 听书神器 实现步骤 代码实现 输出结果 前提条件 熟悉Python 熟悉Tkinter 熟悉Pytts ...
- python selenium 下载文件_Python Selenium —— 文件上传、下载,其实很简单
很多selenium学习者被浏览器弹出的文件上传.下载框折磨的痛不欲生,今天博主就带你们轻松搞定上传和下载问题. 上传 上传弹框 文件上传是所有UI自动化测试都要面对的一个头疼问题,要处理这个问题,我 ...
- python selenium下载电子书
转载至:TTyb http://www.cnblogs.com/TTyb/p/5989152.html 妹纸推荐书籍<御伽草纸>,网上找了很久都找不到下载,估计是被Amazon版权了 ...
- python selenium下载_Python Selenium安装下载
本篇讲解Python Selenium如何安装,下载.本篇已假定你已经熟悉Python,并且已安装好Python和pip. 本篇及以后篇幅所讲代码都调试运行在Python3.6版本上通过. Pytho ...
- 【Python】PC端听书工具
一.准备 1.首先安装python3+,这里不多展开,具体操作百度.(比如:安装Python - 廖雪峰的官方网站) 2.安装pyttsx3.这是一个调用操作系统语音包的库,可离线使用. pip3 i ...
- python实现懒人听书
import tkinter as tk # 文件选择框的库 import tkinter.filedialog as tkf # 智能语音库 import pyttsx3# 2.实现选择书籍功能 d ...
- 从零开始用python处理excel视频_书榜 | 计算机书籍(6.29-7.5)销售排行榜
原标题:书榜 | 计算机书籍(6.29-7.5)销售排行榜 读书给人以快乐.给人以光彩.给人以才干. -- 培根 "书榜"栏目是脚本之家每周推出计算机书籍销量排行榜!数据来源于京东 ...
- 疯狂python讲义豆瓣评分_书榜 | 计算机书籍(9.9-9.15)销售排行榜
原标题:书榜 | 计算机书籍(9.9-9.15)销售排行榜 或作或辍,一曝十寒,则虽读书百年,吾未见其可也. -- 吴梦祥 "书榜"栏目是脚本之家每周推出计算机书籍销量排行榜!数据 ...
- python selenium下载对话框_Selenium+Python:下载文件(Firefox 和 Chrome)
引自 https://blog.csdn.net/Momorrine/article/details/79794146 1. 环境 操作系统 Win10 IDE Eclipse (Oxyg ...
最新文章
- Nature | 机器学习在药物研发中的应用
- 鸿蒙os内测版应用名称,鸿蒙OS2.0发布,只有两款机型可以申请内测
- Ubuntu下安装Python3.6并在终端输入Python就能显示Python3.6
- 杭电1232畅通工程
- Java 动态修改的数组——ArrayList
- Oracle 根据字符串的长度排序
- 解决zabbix的cannot allocate shared memory of size错误
- .htaccess的基本作用及相关语法介绍
- poj2513Colored Sticks(无向图的欧拉回路)
- 【英语学习】【Level 07】U06 First Time L2 A good food experience
- script标签中的crossorigin属性
- 如何让Activiti-Explorer使用sql server数据库
- codeproject
- 设计配色灵感|热情甜蜜色系配色方案
- Java连接数据库——JDBC的快速入门
- 教育教学微课题研究方案——实习调研论文
- Metro Studio——轻松创建Metro风格图标
- MySQL数据库对象
- C++ Builder开发AutoCAD应用程序的方法
- 电源设计2【DC/DC、PCB设计】