经验大分享:python爬取喜马拉雅节目生成RSSFeed

简介: 经验大分享:python爬取喜马拉雅节目生成RSSFeed

记录于:2020年12月03日

用了N年的手机在经历N次掉落之后终于扛不住了,后背都张嘴了,估计再摔一次电池都能飞出来。

换了手机,由于之前有听喜马拉雅的习惯,但是手机里自带有播客软件,强迫症逼着我不能下载喜马拉雅app。

找了几天没发现喜马拉雅提供的有RSS订阅(后来想了一下,别人怎么可能提供这个功能,O(∩_∩)O哈哈~),网上也没有相关服务。

苦啊,后来还是下载了喜马拉雅app,但是实在受不了,就索性自己捣鼓一个轮子。

诉求很简单,就是想将喜马拉雅的节目搬到播客软件,用原生的app听第三方的数据,这个需求好恶心啊,还好不是产品经理提的。

好吧,开始吧。

其实写爬虫,重要的不是代码实现,而是刚开始对需要爬取的数据的分析,分析怎么爬取,怎么得到自己的数据,只要这个流程明白了。代码实现就很简单了。

在这之前需要知道什么是RSS

分析

浏览器打开喜马拉雅,找到想听的节目,比如:郭德纲

这样就有了爬取项目啦,对着这个页面开始分析,我需要标题,作者,图片三个元素,打开浏览器F12,找到这三个元素的定位,这样只需要相应的代码就能抓取信息了,这些信息就足够生成RSS中的 元素啦。

重要的是 元素,播客播的就是这个元素中的信息。

其实就是要拿到页面上的 【播放列表】,还是F12找到 【播放列表】的定位,有了定位,就可以抓取出这个列表,并获取这个列表中每个元素的链接,通过此链接就可以进去详情页。

点开详情页,离实现越来越近了。

我需要标题,描述,及播放源这三个元素来构成 元素。

标题和描述很好获取,还是老套路F12定位就可以了,播放源就需要观察了,打开F12,观察详情页有哪些请求,看是否有某些请求得到声音源数据,

通过发现: 这个请求,会响应数据播放数据

这就能拿到播放数据啦。这样一来,第一页的所有播放数据都能拿到了。

由于当前是列表页,所以少不了分页,我们只需要找出当前页面是否存在下一页,且找到下一页的链接,发起请求然后重复步骤,这样就能拿到整个列表页。

有了上面的一通分析,就知道了如何去编写代码实现这个功能啦。

编码

按照上面的流程,进行编码

1.构建Channel对象

2.构建Item对象

3.生成RSS(在同级目录下会生成一个xml文件)

import requests

from bs4 import BeautifulSoup

import datetime

##################################

##### 公用对象,存储/生成 ######

##################################

# rss channel

class channel(object):

def init(self, title, author, image):

self.title = title

self.author = author

self.image = image

# rss item

class item(object):

def init(self, title, pubDate, description,enclosure):

self.title = title

self.pubDate = pubDate

self.description = description

self.enclosure = enclosure

##################################

##### 爬取数据,存储 ######

##################################

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'

}

# 开始页 - 郭德纲21年相声精选

mainUrl = ""

# 播放地址

playV1 = "/revision/play/v1/audio?id={}&ptype=1"

# gmt时间格式化

GMTFORMAT = '%a, %d %b %Y %H:%M:%S GMT'

# 网址

ximalaya = mainUrl【:mainUrl.index('/',8)】

# 所有播放项

items = 【】

# 构建Channel对象

def getChannel():

r = requests.get(mainUrl,//代码效果参考:http://www.zidongmutanji.com/bxxx/134036.html

headers=headers)

soup = BeautifulSoup(r.text, 'html.parser')

title = soup.find('h1', attrs={'class': 'title vA'}).text

author = soup.find('a',attrs={'class':'nick-name gK'}).text

image = "http:" + soup.find('img', attrs={'class': 'img vA'})【'src'】.split('!')【0】

return channel(title, author, image)

# 构建Item对象

def getItem(listPageUrl):

print('======> 正在爬取列表页',listPageUrl)

r = requests.get(listPageUrl, headers=headers)

soup = BeautifulSoup(r.text, 'html.parser')

# 获取所有播放列表项详情

soundList = soup.findall('div', attrs={'class': 'text lF'})

for sound in soundList:

getDetails(ximalaya + sound.a【'href'】)

# 进入下一页

pageNext = soup.find('li', attrs={'class': 'page-next page-item WJ_'})

if pageNext:

getItem(ximalaya + pageNext.a【'href'】)

# 进入详情页

def getDetails(detailPageUrl):

print("======> 正在爬取详情页",detailPageUrl)

r = requests.get(detailPageUrl, headers=headers)

soup = BeautifulSoup(r.text, 'html.parser')

# 标题

title = soup.find('h1', attrs={'class': 'title-wrapper _uv'}).text

# 发布时间

pubDate = soup.find('span', attrs={'class': 'time _uv'}).text

# 声音简介

description = ""

if soup.find('article'):

description = soup.find('article').text

# 播放源

playUrl = ximalaya + playV1.format(detailPageUrl.split('/')【-1】);

r = requests.get(playUrl, headers=headers)

enclosure = r.json()【'data'】【'src'】

items.append( item(title,datetime.datetime.strptime(pubDate, '%Y-%m-%d %H:%M:%S').strftime(GMT_FORMAT),description,enclosure) )

##################################

##### 生成RSS ######

##################################

def createRSS(channel):

rss_text = r' ' \

r' ' \

r' {}' \

r' {}' \

r' ' \

.format(channel.title, channel.author, channel.image)

for item in items:

rss_text += r' ' \

r' {}' \

r' ' \

r' ' \

r' '\

.format(item.title, item.description, item.enclosure)

rss_text += r' '

print('======> 生成RSS')

print(rss_text)

#写入文件

with open(mainUrl.split('/')【-2】+'.xml', 'w' ,encoding='utf-8') as f:

f.write(rss_text)

if name=="main":

channel = getChannel()

getItem(mainUrl)

createRSS(channel)

将生成后的xml放到服务器,就可以尽情享用了。

成果

易中天老师讲的真的好

后续

本文编写于2020年12月3日,后续官方可能会对页面进行更改,请求进行更改等,会导致以上爬虫失效,所以需要知道如何进行分析,才能知道如何爬取。

以上代码只作为学习探讨,请问恶意使用!

相关文章
|
16天前
|
存储 XML 数据处理
Python网络实践:去哪儿旅游数据爬取指南
Python网络实践:去哪儿旅游数据爬取指南
|
20天前
|
数据采集 JSON 算法
使用Python爬取华为市场APP应用进行分析
这个网站也是作者最近接触到的一个APP应用市场类网站。讲实话,还是蛮适合新手朋友去动手学习的。毕竟爬虫领域要想进步,还是需要多实战、多分析!该网站中的一些小细节也是能够锻炼分析能力的,也有反爬虫处理。甚至是下载APP的话在Web端是无法拿到APK下载的直链,需要去APP端接口数据获取
|
1天前
|
Python
技术经验解读:【Python】torrentParser1.04增加获得磁力链URI功能
技术经验解读:【Python】torrentParser1.04增加获得磁力链URI功能
|
1天前
|
Shell Python
技术经验解读:使用python脚本传递参数:(三种方式可收藏)
技术经验解读:使用python脚本传递参数:(三种方式可收藏)
|
1天前
|
程序员 API 计算机视觉
技术经验解读:【python自动化】02.pywin32库自动操作键鼠(保姆级代码注释)
技术经验解读:【python自动化】02.pywin32库自动操作键鼠(保姆级代码注释)
|
1天前
|
数据安全/隐私保护 Python
经验大分享:python练习:从番号到封面
经验大分享:python练习:从番号到封面
|
1天前
|
存储 Java 索引
经验大分享:Python数据类型总结
经验大分享:Python数据类型总结
|
1天前
|
数据采集 JavaScript 数据安全/隐私保护
经验大分享:python爬虫
经验大分享:python爬虫
|
1天前
|
存储 Java 索引
经验大分享:Python数据类型总结
经验大分享:Python数据类型总结
|
1天前
|
数据安全/隐私保护 Python
经验大分享:python练习:从番号到封面
经验大分享:python练习:从番号到封面