赞
踩
两个星期的考试周副本结束,今天放假。寝室就我一个人,闲来没事,写篇博客混混时间。好像现在csdn上爬虫主题比较火,我也来个听书网站的下载脚本吧。
(前两次投竟然审核没通过)
我挺喜欢听小说的,某雅,某人听书都充过会员,但爬他们网站的资源是可能有被禁的风险,思来想去还是爬个没有版权保护的听书网站,找了一会儿,发现有个叫(lian)(ting)网的还不错。网站底下有免责声明,资源来自网络比较丰富。
并且有电脑端和手机端两个网站,非常nice
可以看一下网站的爬虫声明:

只要不爬取上图所写的目录,应该就不用担心。

点击项对应的标签和属性

每本书对应链接应该是“https://m.ting55.com/”+href
进入选中的书籍页面,我们可以看到对应的每一集目录

每一集目录应该是“https://m.ting55.com/”+href
进入每一集后查看音频元素,大多为m4a和mp3格式,我们最终要找到每一集对应的音频文件地址
在类似的爬取音频视频网站时,最重要的就是找到音频视频对应的地址
这里我使用的是Microsoft edge(浏览器)+selenium+requests+lxml(代码里面有一些库是优化使用的)

这个网站比较贼,如果单纯用requests库时在返回每一集的响应时会将音频资源标签去掉,所以我们需要使用selenium来将标签完整的爬取。
其他的库就正常的pip下载
def get_url_response(url):#传入的参数url即你想听的书的url地址
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
Proxy={'http':'121.230.133.214:9999'}
a=requests.get(url,proxies=Proxy,headers=header)
return a
def get_bookname(a):
html=etree.HTML(a.text)
name=html.xpath('//*[@id="wrapper"]/div[3]/div/div/div[2]/div/div[2]/h1/text()')
return name
def get_page_url(reponse,start_page,stop_page):
html=etree.HTML(reponse.text)
page_url=[]
for i in range(start_page,stop_page+1):
page_url.append('https://m.ting55.com/'+html.xpath(f'/html/body/div[1]/div[3]/div/div/div[4]/div/ul/li[{i}]/a/@href')[0])
return page_url #获取的每个章节的url地址
@retry(stop_max_attempt_number=6) #假如该函数断开,重复尝试的次数 def get_audio_url(driver,page_url,name): # #声明代理 global num num=num+1 if (num==4): return print(page_url,"---第{}次".format(num)) driver.get(page_url) sleep(120) page_all=driver.find_element_by_xpath('/html/body/div[1]/section/h1').text audio_url=driver.find_element_by_xpath('//*[@id="player"]').get_attribute("src") print("开始爬取{}".format(name)) save(name,page_all,audio_url) num=0 def save(name,page,audio_url): path = f'D:/有声小说/{name}//' if not os.path.exists(path): os.makedirs(path) audio_content = requests.get(audio_url).content #audio_content=request.get(audio_url).content with open(path +page+ '.mp3', mode='wb') as f: f.write(audio_content) print('正在保存:', page) print("等待一会开始爬取下一章") # sleep(100)
if __name__ == '__main__': url='https://www.ting55.com/book/13864' # start=int(input("起始集:")) start=10 # stop=int(input("中止集:")) stop=100 proxy = Proxy({ 'proxyType': ProxyType.MANUAL, # #代理 ip 和端口 'httpProxy': '223.215.118.145:9999'}) # #配置对象 DesiredCapabilities dc=DesiredCapabilities.EDGE.copy() # #把代理 ip 加入配置对象 proxy.add_to_capabilities(dc) option=EdgeOptions() option.add_argument('headless') option.add_argument( 'user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36') option.add_experimental_option('excludeSwitches', ['enable-automation']) # driver=webdriver.Edge("D:/edgedriver_win64/9.1/msedgedriver.exe",capabilities=dc,options=option) driver = Edge("D:/edgedriver_win64/9.1/msedgedriver.exe",options = option) re=get_url_response(url) try: get_medio(driver,get_page_url(re,start,stop),get_bookname(re)) except Exception as e: print(e,"5小时后还在被封") driver.close() print("第{}到第{}已经爬取完成".format(start,stop)) driver.close()
import requests import os from lxml import etree # from selenium import webdriver from time import sleep from selenium.webdriver.common.proxy import Proxy from selenium.webdriver.common.proxy import ProxyType from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from retrying import retry from msedge.selenium_tools import EdgeOptions from msedge.selenium_tools import Edge num = 0 def get_url_response(url): header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'} Proxy={'http':'121.230.133.214:9999'} a=requests.get(url,proxies=Proxy,headers=header) return a def get_page_url(reponse,start_page,stop_page): html=etree.HTML(reponse.text) page_url=[] for i in range(start_page,stop_page+1): page_url.append('https://m.ting55.com/'+html.xpath(f'/html/body/div[1]/div[3]/div/div/div[4]/div/ul/li[{i}]/a/@href')[0]) return page_url def get_bookname(a): html=etree.HTML(a.text) name=html.xpath('//*[@id="wrapper"]/div[3]/div/div/div[2]/div/div[2]/h1/text()') return name @retry(stop_max_attempt_number=6)#假如该函数断开,重复尝试的次数 def get_audio_url(driver,page_url,name): # #声明代理 global num num=num+1 if (num==4): return print(page_url,"---第{}次".format(num)) driver.get(page_url) sleep(120)#每一集之间的爬取设置暂停2分钟 page_all=driver.find_element_by_xpath('/html/body/div[1]/section/h1').text audio_url=driver.find_element_by_xpath('//*[@id="player"]').get_attribute("src") print("开始爬取{}".format(name)) save(name,page_all,audio_url) num=0 def get_medio(driver,page,name): global num try_num=0 stop=0 for i in page: get_audio_url(driver,i,name) stop+=1 if(stop%4 == 0 and stop!=0): print("为防止爬取过快被限制,暂停10分钟") sleep(600) stop=0 #这个网站有访问限制,如果一定时间内访问过于频繁就会被封一个小时,所以我设置了上面的for循环每爬取四集就停十分钟 while (num>=4 and try_num<=2): print("开始等待一小时")# sleep(3600) print("等待时间结束,开始爬取") try_num=try_num+1 print("get_medio中{}的第{}次尝试".format(i,try_num)) num=0 get_audio_url(driver,i,name) #假如被封禁一个小时,这个while语句会自动等待一小时后再试着爬取,一直被禁则重复五次后异常退出 try_num=0 def save(name,page,audio_url): path = f'D:/有声小说/{name}//' if not os.path.exists(path): os.makedirs(path) audio_content = get_url_response(audio_url).content #audio_content=request.get(audio_url).content with open(path +page+ '.m4a', mode='wb') as f: f.write(audio_content) print('正在保存:', page) print("等待一会开始爬取下一章") # sleep(100) if __name__ == '__main__': url=input("恋听网中书籍url地址:") start=int(input("起始集:")) stop=int(input("中止集:")) proxy = Proxy({ 'proxyType': ProxyType.MANUAL, # #代理 ip 和端口 'httpProxy': '223.215.118.145:9999'}) # #配置对象 DesiredCapabilities dc=DesiredCapabilities.EDGE.copy() # #把代理 ip 加入配置对象 proxy.add_to_capabilities(dc) option=EdgeOptions() option.add_argument('headless') option.add_argument( 'user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36') option.add_experimental_option('excludeSwitches', ['enable-automation']) # driver=webdriver.Edge("D:/edgedriver_win64/9.1/msedgedriver.exe",capabilities=dc,options=option) driver = Edge("D:/edgedriver_win64/9.1/msedgedriver.exe",options = option) re=get_url_response(url) try: get_medio(driver,get_page_url(re,start,stop),get_bookname(re)) except Exception as e: print(e,"5小时后还在被封") driver.close() print("第{}到第{}已经爬取完成".format(start,stop)) driver.close()
这个脚本写的时间比较短,可能会有一些东西无法兼顾,比如防止被封禁的方法(我选择以降低速度来防止访问频繁被禁),其实可以做个代理ip池切换ip爬取。如果只是自己听小说我觉得应该够用了,建议晚上运行脚本,白天听。
觉得有帮助的朋友,能给个赞吗?求求了
本人原创,若要转载请私信通知即可
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。