最近听书,喜马拉雅等收费,终于在某个网找到一部免费的,可以在线听。此网站没有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 下载 某听书网一部书籍相关推荐

  1. Python Tkinter实现一个听书神器

    Python Tkinter实现一个听书神器 前提条件 相关介绍 Tkinter 组件 实验环境 听书神器 实现步骤 代码实现 输出结果 前提条件 熟悉Python 熟悉Tkinter 熟悉Pytts ...

  2. python selenium 下载文件_Python Selenium —— 文件上传、下载,其实很简单

    很多selenium学习者被浏览器弹出的文件上传.下载框折磨的痛不欲生,今天博主就带你们轻松搞定上传和下载问题. 上传 上传弹框 文件上传是所有UI自动化测试都要面对的一个头疼问题,要处理这个问题,我 ...

  3. python selenium下载电子书

    转载至:TTyb    http://www.cnblogs.com/TTyb/p/5989152.html 妹纸推荐书籍<御伽草纸>,网上找了很久都找不到下载,估计是被Amazon版权了 ...

  4. python selenium下载_Python Selenium安装下载

    本篇讲解Python Selenium如何安装,下载.本篇已假定你已经熟悉Python,并且已安装好Python和pip. 本篇及以后篇幅所讲代码都调试运行在Python3.6版本上通过. Pytho ...

  5. 【Python】PC端听书工具

    一.准备 1.首先安装python3+,这里不多展开,具体操作百度.(比如:安装Python - 廖雪峰的官方网站) 2.安装pyttsx3.这是一个调用操作系统语音包的库,可离线使用. pip3 i ...

  6. python实现懒人听书

    import tkinter as tk # 文件选择框的库 import tkinter.filedialog as tkf # 智能语音库 import pyttsx3# 2.实现选择书籍功能 d ...

  7. 从零开始用python处理excel视频_书榜 | 计算机书籍(6.29-7.5)销售排行榜

    原标题:书榜 | 计算机书籍(6.29-7.5)销售排行榜 读书给人以快乐.给人以光彩.给人以才干. -- 培根 "书榜"栏目是脚本之家每周推出计算机书籍销量排行榜!数据来源于京东 ...

  8. 疯狂python讲义豆瓣评分_书榜 | 计算机书籍(9.9-9.15)销售排行榜

    原标题:书榜 | 计算机书籍(9.9-9.15)销售排行榜 或作或辍,一曝十寒,则虽读书百年,吾未见其可也. -- 吴梦祥 "书榜"栏目是脚本之家每周推出计算机书籍销量排行榜!数据 ...

  9. python selenium下载对话框_Selenium+Python:下载文件(Firefox 和 Chrome)

    引自  https://blog.csdn.net/Momorrine/article/details/79794146 1.      环境 操作系统 Win10 IDE Eclipse (Oxyg ...

最新文章

  1. Nature | 机器学习在药物研发中的应用
  2. 鸿蒙os内测版应用名称,鸿蒙OS2.0发布,只有两款机型可以申请内测
  3. Ubuntu下安装Python3.6并在终端输入Python就能显示Python3.6
  4. 杭电1232畅通工程
  5. Java 动态修改的数组——ArrayList
  6. Oracle 根据字符串的长度排序
  7. 解决zabbix的cannot allocate shared memory of size错误
  8. .htaccess的基本作用及相关语法介绍
  9. poj2513Colored Sticks(无向图的欧拉回路)
  10. 【英语学习】【Level 07】U06 First Time L2 A good food experience
  11. script标签中的crossorigin属性
  12. 如何让Activiti-Explorer使用sql server数据库
  13. codeproject
  14. 设计配色灵感|热情甜蜜色系配色方案
  15. Java连接数据库——JDBC的快速入门
  16. 教育教学微课题研究方案——实习调研论文
  17. Metro Studio——轻松创建Metro风格图标
  18. MySQL数据库对象
  19. C++ Builder开发AutoCAD应用程序的方法
  20. 电源设计2【DC/DC、PCB设计】

热门文章

  1. 简单学习:repo入门
  2. 性能测试实战(八):逻辑控制器
  3. Cassandra教程(4)---- 节点间交互(gossip)
  4. wx.TextCtrl设置字体颜色
  5. 基于 session 的登陆
  6. java enum类默认常量是什么_Java枚举类型enum的详解及使用
  7. 计算机组装安装与维护作业,计算机组装和维护作业.doc
  8. 343、弱电智能化工程如何跳纤?需要注意哪些问题
  9. 关键字驱动实现web自动化
  10. 计算机程序设计员理论二