返回介绍

11.3 API 爬虫:爬取 MP3 资源信息

发布于 2024-01-26 22:39:51 字数 5278 浏览 0 评论 0 收藏 0

通过Wireshark对酷我听书的抓包,找到了四个酷我听书的API接口,如表11-4所示。

表11-4 API接口

通过上面可以看到,这几个API接口是逐层递进的关系,从前一个API接口的JSON响应中可以获取下一个API接口所需的ID。知道这层关系,下面我们写一个简单的API爬虫程序,功能是提取相声分类下郭德纲相声的曲目详细信息。

1.爬虫下载器

爬虫下载器代码和第6章的一样,不过需要将UserAgent改成手机浏览器的信息,下载下来的是JSON格式。代码如下:

  # coding:utf-8
  import requests
  class SpiderDownloader(object):
     def download(self,url):
       if url is None:
            return None
       user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, 
       like Gecko) Chrome/45.0.2454.93 Safari/537.36'
       headers={'User-Agent':user_agent}
       r = requests.get(url,headers=headers)
       if r.status_code==200:
            r.encoding='utf-8'
            return r.text
       return None

2.爬虫解析器

由于是爬取所有郭德纲的曲目信息,提前通过API接口知道了ID,所以直接爬取http://ts.kuwo.cn/service/getlist.v31.phpact=cat&id=50 这个链接下的数据即可。数据格式如图11-19所示。

解析器需要将JSON文件中list下所有的Name和ID信息提取出来,将提取出来的ID,再代入http://ts.kuwo.cn/service/getlist.v31.phpact=detail&id={id} 链接获取详细信息,并将其中曲目的ID、Name和Path提取出来,存储为HTML。解析器代码如下:

图11-19 数据格式

  # coding:utf-8
  import json
  class SpiderParser(object):
  
     def get_kw_cat(self, response):
       '''
       获取分类下的曲目
       :param response:
       :return:
       '''
       try:
            kw_json = json.loads(response, encoding="utf-8")
            cat_info = []
            if kw_json["sign"] is not None:
              if kw_json["list"] is not None:
                for data in kw_json["list"]:
                     id = data["Id"]
                     name= data["Name"]
                     cat_info.append({'id':id,'cat_name':name})
                return cat_info
       except Exception,e:
            print e
  
     def get_kw_detail(self,response):
       '''
       获取某一曲目的详细信息
       :param response:
       :return:
       '''
       detail_json = json.loads(response, encoding="utf-8")
       details=[]
       for data in detail_json["Chapters"]:
            if data is None:
              return
            else:
              try:
                file_path = data["Path"]
                name =data["Name"]
                file_id =str(data["Id"])
                details.append({'file_id':file_id,'name':name,'file_path': 
                file_path})
              except Exception,e:
                print e
       return details

3.数据存储器

数据存储器的代码和第7章分布式的代码差别不大,程序如下:

  # coding:utf-8
  import codecs
  class SpiderDataOutput(object):
     def __init__(self):
       self.filepath='kuwo.html'
       self.output_head(self.filepath)
  
     def output_head(self,path):
       '''
       将HTML头写进去
       :return:
       '''
       fout=codecs.open(path,'w',encoding='utf-8')
       fout.write("<html>")
       fout.write("<body>")
       fout.write("<table>")
       fout.close()
  
     def output_html(self,path,datas):
       '''
       将数据写入HTML文件中
       :param path: 文件路径
       :return:
       '''
       if datas==None:
            return
       fout=codecs.open(path,'a',encoding='utf-8')
  
       for data in datas:
            fout.write("<tr>")
            fout.write("<td>%s</td>"%data['file_id'])
            fout.write("<td>%s</td>"%data['name'])
            fout.write("<td>%s</td>"%data['file_path'])
            fout.write("</tr>")
       fout.close()
  
     def ouput_end(self,path):
       '''
       输出HTML结束
       :param path: 文件存储路径
       :return:
       '''
       fout=codecs.open(path,'a',encoding='utf-8')
       fout.write("</table>")
       fout.write("</body>")
       fout.write("</html>")
       fout.close()

4.爬虫调度器

爬虫调度器和第6章的调度器内容差不多。代码如下:

  class SpiderMan(object):
  
     def __init__(self):
       self.downloader = SpiderDownloader()
       self.parser = SpiderParser()
       self.output = SpiderDataOutput()
     def crawl(self,root_url):
       content = self.downloader.download(root_url)
       for info in self.parser.get_kw_cat(content):
            print info
            cat_name = info['cat_name']
            detail_url = 'http://ts.kuwo.cn/service/getlist.v31.phpact=detail&id=
            %s'%info['id']
            content = self.downloader.download(detail_url)
            details = self.parser.get_kw_detail(content)
            print detail_url
            self.output.output_html(self.output.filepath,details)
       self.output.ouput_end(self.output.filepath)
  
  if __name__ =="__main__":
     spider = SpiderMan()
     spider.crawl('http://ts.kuwo.cn/service/getlist.v31.phpact=cat&id=50')

以上就是API爬虫的所有内容,启动爬虫,数据就开始存储了,效果如图11-20所示。

图11-20 最终数据

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文