zoukankan      html  css  js  c++  java
  • Python爬虫入门教程 29-100 手机APP数据抓取 pyspider

    1. 手机APP数据----写在前面

    继续练习pyspider的使用,最近搜索了一些这个框架的一些使用技巧,发现文档竟然挺难理解的,不过使用起来暂时没有障碍,估摸着,要在写个5篇左右关于这个框架的教程。今天教程中增加了图片的处理,你可以重点学习一下。

    2. 手机APP数据----页面分析

    咱要爬取的网站是 http://www.liqucn.com/rj/new/ 这个网站我看了一下,有大概20000页,每页数据是9个,数据量大概在180000左右,可以抓取下来,后面做数据分析使用,也可以练习优化数据库。

    在这里插入图片描述

    网站基本没有反爬措施,上去爬就可以,略微控制一下并发,毕竟不要给别人服务器太大的压力。

    页面经过分析之后,可以看到它是基于URL进行的分页,这就简单了,我们先通过首页获取总页码,然后批量生成所有页码即可

    http://www.liqucn.com/rj/new/?page=1
    http://www.liqucn.com/rj/new/?page=2
    http://www.liqucn.com/rj/new/?page=3
    http://www.liqucn.com/rj/new/?page=4
    

    获取总页码的代码

    class Handler(BaseHandler):
        crawl_config = {
        }
    
        @every(minutes=24 * 60)
        def on_start(self):
            self.crawl('http://www.liqucn.com/rj/new/?page=1', callback=self.index_page)
    
        @config(age=10 * 24 * 60 * 60)
        def index_page(self, response):
            # 获取最后一页的页码
            totle = int(response.doc(".current").text())
            for page in range(1,totle+1):
                self.crawl('http://www.liqucn.com/rj/new/?page={}'.format(page), callback=self.detail_page)
    
    

    然后copy一段官方中文翻译,过来,时刻提醒自己

    代码简单分析:
    
    def on_start(self) 方法是入口代码。当在web控制台点击run按钮时会执行此方法。
    
    self.crawl(url, callback=self.index_page)这个方法是调用API生成一个新的爬取任务,
    			这个任务被添加到待抓取队列。
    def index_page(self, response) 这个方法获取一个Response对象。 
    			response.doc是pyquery对象的一个扩展方法。pyquery是一个类似于jQuery的对象选择器。
    
    def detail_page(self, response)返回一个结果集对象。
    			这个结果默认会被添加到resultdb数据库(如果启动时没有指定数据库默认调用sqlite数据库)。你也可以重写
    			on_result(self,result)方法来指定保存位置。
    
    更多知识:
    @every(minutes=24*60, seconds=0) 这个设置是告诉scheduler(调度器)on_start方法每天执行一次。
    @config(age=10 * 24 * 60 * 60) 这个设置告诉scheduler(调度器)这个request(请求)过期时间是10天,
    	10天内再遇到这个请求直接忽略。这个参数也可以在self.crawl(url, age=10*24*60*60) 和 crawl_config中设置。
    @config(priority=2) 这个是优先级设置。数字越大越先执行。
    

    分页数据已经添加到待爬取队列中去了,下面开始分析爬取到的数据,这个在detail_page函数实现

        @config(priority=2)
        def detail_page(self, response):
            docs = response.doc(".tip_blist li").items()
            dicts = []
            for item in docs:
                title = item(".tip_list>span>a").text()
                pubdate = item(".tip_list>i:eq(0)").text()
                info = item(".tip_list>i:eq(1)").text()
                # 手机类型
                category = info.split(":")[1]
                size = info.split("/")
                if len(size) == 2:
                    size = size[1]
                else:
                    size = "0MB"
                app_type = item("p").text()
                mobile_type = item("h3>a").text()
                # 保存数据
                
                # 建立图片下载渠道
                
                img_url = item(".tip_list>a>img").attr("src")
                # 获取文件名字
                filename = img_url[img_url.rindex("/")+1:]
                # 添加软件logo图片下载地址
                self.crawl(img_url,callback=self.save_img,save={"filename":filename},validate_cert=False)
                dicts.append({
                    "title":title,
                    "pubdate":pubdate,
                    "category":category,
                    "size":size,
                    "app_type":app_type,
                    "mobile_type":mobile_type
                    
                    })
            return dicts
    

    数据已经集中返回,我们重写on_result来保存数据到mongodb中,在编写以前,先把链接mongodb的相关内容编写完毕

    import os
    
    import pymongo
    import pandas as pd
    import numpy as np
    import time
    import json
    
    DATABASE_IP = '127.0.0.1'
    DATABASE_PORT = 27017
    DATABASE_NAME = 'sun'
    client = pymongo.MongoClient(DATABASE_IP,DATABASE_PORT)
    db = client.sun
    db.authenticate("dba", "dba")
    collection = db.liqu  # 准备插入数据
    
    

    数据存储

        def on_result(self,result):
            if result:
                self.save_to_mongo(result)            
     
        def save_to_mongo(self,result):
            df = pd.DataFrame(result)
            #print(df)
            content = json.loads(df.T.to_json()).values()
            if collection.insert_many(content):
                print('存储到 mongondb 成功')
    

    获取到的数据,如下表所示。到此为止,咱已经完成大部分的工作了,最后把图片下载完善一下,就收工啦!

    在这里插入图片描述

    3. 手机APP数据----图片存储

    图片下载,其实就是保存网络图片到一个地址即可

        def save_img(self,response):
            content = response.content
            file_name = response.save["filename"]
            #创建文件夹(如果不存在)
            if not os.path.exists(DIR_PATH):                         
                os.makedirs(DIR_PATH) 
                
            file_path = DIR_PATH + "/" + file_name
            
            with open(file_path,"wb" ) as f:
                f.write(content)
    

    到此为止,任务完成,保存之后,调整爬虫的抓取速度,点击run,数据跑起来~~~~

  • 相关阅读:
    Serialize and Deserialize Binary Tree
    sliding window substring problem汇总贴
    10. Regular Expression Matching
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第七章 链接
    程序员如何写一份合格的简历?(附简历模版)
    9个提高代码运行效率的小技巧你知道几个?
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第六章 存储器层次结构
    24张图7000字详解计算机中的高速缓存
    《深入理解计算机系统》(CSAPP)实验四 —— Attack Lab
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第五章 优化程序性能
  • 原文地址:https://www.cnblogs.com/happymeng/p/10307026.html
Copyright © 2011-2022 走看看