文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
11.3 API 爬虫:爬取 MP3 资源信息
通过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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论