Python爬虫实战(5)Scrapy框架的运用

前言

  • 蛋肥学习了Scrapy框架,打算实践一下,利用Scrapy来爬取一下最美应用推荐APP的数据,并储存到MySQL数据库中。

准备

爬取时间:2021/02/04
系统环境:Windows 10
所用工具:Jupyter Notebook\Python 3.0
涉及的库:scrapy\requests\json\lxml\pymysql

获取基础数据

最美应用
http://zuimeia.com/apps/?page=1&platform=2
参考资料
scrapy保存到mysql数据库
小提示
scrapy的多线程机制导致抓回来的数据是无序的。

创建项目

#cmd里依次执行代码,创建scrapy项目
cd C:\Users\Archer\Desktop
scrapy startproject appSpider

定义目标字段

#对项目文件夹里的items.py做以下修改
import scrapy
class appspiderItem(scrapy.Item):
    app_name = scrapy.Field()  #名称
    app_intro = scrapy.Field()  #描述
    app_like = scrapy.Field()  #喜爱数
    app_time = scrapy.Field()  #发布时间
    app_link = scrapy.Field()  #详情链接
    app_content = scrapy.Field()  #推荐内容

创建爬虫器

#cmd里依次执行代码,创建爬虫器
cd C:\Users\Archer\Desktop\appSpider
scrapy genspider app zuimeia.com

修改爬虫器

#对项目文件夹里的app.py做以下修改
import scrapy
import requests
import json
from lxml import etree
from appSpider.items import appspiderItem

class AppSpider(scrapy.Spider):
    name = 'app'
    allowed_domains = ['zuimeia.com']
    start_urls = ['http://zuimeia.com/apps/?page=1&platform=2']
    headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"}
    url_head="http://zuimeia.com/apps/?page="
    url_end="&platform=2"
    #从start_requests开始发送请求
    def start_requests(self):
        for i in range(1,11):
            url=self.url_head+str(i)+self.url_end
            yield scrapy.Request(url=url,callback=self.parse, headers=self.headers)
    #获取推荐页面的相关数据
    def parse(self, response):
        html=etree.HTML(response.text)
        app_name=html.xpath('//a[@class="app-title"]/h1/text()')
        app_intro=html.xpath('//a[@class="quote-text"]/text()')
        app_time=html.xpath('//span[@class="pub-time"]/text()')
        app_link=html.xpath('//a[@class="app-title"]/@href')
        #因喜爱数是动态加载的,通过Network找到实际url,单独进行解析
        app_id=html.xpath('//a[@class="app-title"]/@data')
        app_like=[]
        for i in range(len(app_id)):
            like_link="http://zuimeia.com/apps/up/?ids="+str(app_id[i])
            r=requests.get(like_link,headers=self.headers,timeout=10)
            json_string=r.text
            json_data=json.loads(json_string)
            like=json_data["data"][0].get(str(app_id[i]))
            app_like.append(like)
        #将数据封装到appspiderItem
        for i in range(len(app_name)):
            item=appspiderItem()
            item["app_name"]=app_name[i]
            item["app_intro"]=app_intro[i]
            item["app_time"]=app_time[i]
            item["app_link"]=app_link[i]
            item["app_like"]=app_like[i]
            yield scrapy.Request(url="http://zuimeia.com"+app_link[i],meta={"item":item},callback=self.parse2)
    def parse2(self, response):
        item=response.meta["item"]
        #提取内容
        html=etree.HTML(response.text)
        text=html.xpath('//*[@id="article_content"]/p/text()')
        app_content=""
        for i in range(len(text)):
            app_content=app_content+text[i]
        item["app_content"]=app_content
        yield item

创建数据库

#在Workbench里创建数据库
CREATE DATABASE app;
USE app;
CREATE TABLE zuimeiapp(
id INT NOT NULL AUTO_INCREMENT,
app_name VARCHAR(50) NOT NULL,
app_intro VARCHAR(500) NOT NULL,
app_like VARCHAR(50) NOT NULL,
app_time VARCHAR(50) NOT NULL,
app_link VARCHAR(100) NOT NULL,
app_content VARCHAR(5000) NOT NULL,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(id)
);

修改存储文件

#对项目文件夹里的pipelines.py做以下修改,因数据量较少,用同步操作
from itemadapter import ItemAdapter
import pymysql
 
class AppspiderPipeline():
    def __init__(self):
        #打开数据库链接
        self.conn=pymysql.connect("localhost","root","password","app",charset='utf8')
        #获取操作游标
        self.cursor=self.conn.cursor()

    def process_item(self,item,spider):
        #SQL插入语句
        sql="""INSERT INTO zuimeiapp(app_name,app_intro,app_like,app_time,app_link,app_content) VALUES(%s,%s,%s,%s,%s,%s);"""
        try:
            #执行语句
            self.cursor.execute(sql,(item["app_name"],item["app_intro"],item["app_like"],item["app_time"],item["app_link"],item["app_content"]))
            #提交到数据库执行
            self.conn.commit()
        except:
            #如果出错就回滚
            self.conn.rollback()

    def close_spider(self,spider):
        #关闭数据库
        self.cursor.close()
        self.conn.close()

修改设置文件

#对项目文件夹里的settings.py以下内容取消注释
ITEM_PIPELINES = {
    'appSpider.pipelines.AppspiderPipeline': 300,
}

运行爬虫

#cmd里依次执行代码,运行爬虫
cd C:\Users\Archer\Desktop\appSpider
scrapy crawl app

大功告成

数据库里的部分数据

总结

  • scrapy的多线程机制可使抓取速度变快。
  • 根据数据量的多少,可以选择同步或异步操作将数据写入数据库。

你可能感兴趣的:(Python爬虫实战(5)Scrapy框架的运用)