scrapy 爬取懒人听书资源

2018-11-05  本文已影响0人  昵称不再更新

目标站点分析

懒人听书-https://www.lrts.me/index,进入主页以后搜索黑暗森林,找到对应资源点击进入黑暗森林

微信截图_20181105215543.png

可以看到,url中跟的29320是该资源对应的id,如果要爬其他资源,对应的更改这个id就好了,点击第一集后跳到下面的页面并开始播放

微信截图_20181105215928.png
中途做了部分测试,发现上图中的资源其实是通过ajax请求的。如果我们把js禁用,页面就会发生变化,没有数据,如下:
微信截图_20181105220223.png
该请求通过控制台可以查看,ttps://www.lrts.me/ajax/playlist/2/29320/1,该请求返回的数据中就包含了mp3资源链接 微信截图_20181105220615.png

有了以上的分析,下面就可以使用scrapy爬取数据了

使用scrapy爬取数据

spider的思路是先获取资源总数,懒人听书默认分页是10页,然后计算有多少页,根据页数通过上面分析的异步url去请求包含mp3资源的页面。然后使用pipeline去下载即可。代码就比较简单了

spider

class SantiSpider(scrapy.Spider):
    name = 'santi'
    allowed_domains = ['www.lrts.me']
    start_urls = ['https://www.lrts.me/book/29320/']

    # start_urls = ['https://www.lrts.me/ajax/playlist/2/29320/1']

    def parse(self, response):
        total_count = response.xpath('/html/body/div[1]/div[1]/section[1]/div[2]/ul[3]/li[1]/text()').extract_first()
        total_page = (int(total_count) // 10) + 1 if total_count else 0
        base_download_url = 'https://www.lrts.me/ajax/playlist/2/29320/{}'
        for page in range(total_page):
            start = page * 10 + 1
            url = base_download_url.format(start)
            yield scrapy.Request(url=url, callback=self.parse_download)

    def parse_download(self, response):
        lis = response.css('.section li')
        for li in lis:
            item = SantiItem()
            res_url = li.css('div.column1.nowrap > input[type="hidden"]:nth-child(3)::attr(value)').extract_first()
            item['file_urls'] = [res_url]
            res_num = li.css('div.column1.nowrap > div > span::text').extract_first()
            item['res_num'] = res_num
            yield item

item

class SantiItem(scrapy.Item):
    file_urls = scrapy.Field()
    total_count = scrapy.Field()
    res_num = scrapy.Field()

pipeline

因为要改文件名,所以使用自定义的pipeline,重写file_path方法

class MyfilesPipeline(FilesPipeline):

    def get_media_requests(self, item, info):
        for url in item["file_urls"]:
            yield scrapy.Request(url,meta={'item':item})

    def file_path(self, request, response=None, info=None):
        return '三体2黑暗森林_第'+request.meta['item']['res_num']+'集.mp3'

上一篇下一篇

猜你喜欢

热点阅读