scrapy库“5+2”框架图

 上面的图着实看不懂,总结一句话:scrapy框架是一个半成品,它已经把大多数功能实现了使用者只要对少数几个模块进行操作,如spider模块、Downloader模块、Item piplines模块

注:scrapy是使用命令行格式

>scrapy< <command> [options] [args]

                 scrapy常用命令

命令  说明 格式
startproject 创建一个新工程 scrapy startproject <name> [dir]
genspider 创建一个爬虫 scrapy genspider [options] <name> [domain]
settings 获得爬虫配置信息 scrapy settings [options]
crawl 运行一个爬虫 scrapy crawl <spider>
list 列出工程中所有的爬虫 scrapy list
shell 启动URL调试命令行    scrapy shell [URL]

基于常用命令的实例:

爬取:https://python123.io/ws/demo.html的HTML网页并存储

步骤1.建立一个scrapy爬虫工程
执行 scrapy startproject python123demo
生成的工程目录
    python3deom/-------------->外层目录
        scrapy.cfg------------>部署scrapy爬虫的配置文件,即放在服务器上并配置相应的操作接口
        python23deom/--------->scrapy框架的用户字定义python代码
        __int__.py------------>初始化脚本(继承类)
        items.pyItems--------->Items代码模板(基础类)
        middlewares.py-------->Middlewares代码模板(继承类)
        piplines.py----------->Piplines代码模板(继承类)
        settings.py----------->scrapy爬虫的配置文件
        spiders/-------------->spiders代码模板目录(继承类)
            __int__.py----------->初始文件,无需修改
            __pycache__/--------->缓存目录,无需修改
步骤2.在工程中产生一个scrapy爬虫
执行 cd python123deom
执行 scrapy genspider deom python123.io     生成一个名为demo的爬虫(在spiders/目录下生成一个deom.py文件)


如下:
# -*- coding: utf-8 -*-
import scrapy

#以面向对象编写的一个类,该类叫demospider,这个类必须是继承scrapy.spider这个类的子类
class DemoSpider(scrapy.Spider):
    name = 'demo'#变量name赋值为demo,即当前爬虫的名字叫demo
    allowed_domains = ['python123.io']#指最开始用户提交给命令行的域名,即这个爬虫只能爬取这个域名以下的相关链接
    start_urls = ['http://python123demo.io/']#以列表形式包含的一个或多个URL,就是scrapy框架所要爬取的初始页面

    def parse(self, response):#解析页面的方法(此处初始为空),parse()用于处理响应,解析内容形成字典,发现新的URL爬取请求
        pass

步骤3.配置产生的spider爬虫
# -*- coding: utf-8 -*-
import scrapy

#以面向对象编写的一个类,该类叫demospider,这个类必须是继承scrapy.spider这个类的子类
class DemoSpider(scrapy.Spider):
    name = 'demo'#变量name赋值为demo,即当前爬虫的名字叫demo
    #allowed_domains = ['python123demo.io']#指最开始用户提交给命令行的域名,即这个爬虫只能爬取这个域名以下的相关链接
    start_urls = ['http://python123demo.io/ws/demo.html']#以列表形式包含的一个或多个URL,就是scrapy框架所要爬取的初始页面

    def parse(self, response):#解析页面的方法(此处初始为空),parse()用于处理响应,解析内容形成字典,发现新的URL爬取请求
        fname = response.url.split("/")[-1]#定义一个名字将response的内容保存到一个html文件中,从响应的url链接中提取名字,作为保存为本地的文件名
        with open(fname,"wb")as f :#将返回的内容保存为文件
            f.write(response.body)
         self.log("Saved file %s."%name)

步骤4.运行爬虫,获取网页
执行 scrapy crawl demo
如下;
#以面向对象编写的一个类,该类叫demospider,这个类必须是继承scrapy.spider这个类的子类
class DemoSpider(scrapy.Spider):
    name = 'demo'#变量name赋值为demo,即当前爬虫的名字叫demo
    #allowed_domains = ['python123demo.io']#指最开始用户提交给命令行的域名,即这个爬虫只能爬取这个域名以下的相关链接
    start_urls = ['http://python123demo.io/ws/demo.html']#以列表形式包含的一个或多个URL,就是scrapy框架所要爬取的初始页面

    def parse(self, response):#解析页面的方法(此处初始为空),parse()用于处理响应,解析内容形成字典,发现新的URL爬取请求
        fname = response.url.split("/")[-1]#定义一个名字将response的内容保存到一个html文件中,从响应的url链接中提取名字,作为保存为本地的文件名
        with open(fname,"wb") as f :#将返回的内容保存为文件
            f.write(response.body)
        self.log("Saved file %s."% fname)

 ——————————————————————————————————-

yield关键字的使用:

 yield 等价于生成器

生成器是一个不断产生值的函数
生成器每次产生一个值(yield语句)函数被唤醒后再产生一个值

#输出小于5的平方值(生成器写法)
def gen(n):
    for i in range(n):
        yield i**2#生成器每次只返回一个值
for i in gen(5):
    print(i," ",end="")

#输出小于5的平方值(普通写法)
def square(n):
    ls = [i**2 for i in range(n)]#将所有遍历的所有值返回到列表中,存储空间占用相对较多
    return ls
for i in square(5):
    print(i," ",end="")

生成器相比一次列出所有内容的优势:
1.更节省存储空间
2.响应更迅速
3.使用更加灵活

  ——————————————————————————————————

scrapy爬虫的使用步骤:
步骤1.创建一个工程和spider模板
步骤2.编写一个spider
步骤3.编写Item Pipeline
步骤4.优化配置策略

 

 

scrapy爬虫的数据类型:    Request类
            Response类
            Item类
Requests类:
定义:Requests对象表示一个HTTP请求,由spider生成,由Downloader执行
使用:class scrapy.http.Request()

.url———->Request对应的请求url的地址
.method——->对应的请求方法,“GET”、“POST”
.headers——>字典型风格的请求头
.body———>请求内容主体,字符串类型
.meta———>用户添加的扩展信息,在scrapy内部模块间传递使用
.copy()——->复制该请求

Response类:
定义:Response对象表示一个HTML响应,由Downloader生成,由spider处理
使用:clss scrapy.http.Response()

.url——->Response对应的url地址
.start—–>HTML状态码,默认是200
.headers——->Respons对应的头部信息
.body——->Respons对应的内容信息,字符串类型
.flags——->一组标记
.request——->产生Reponse类型对应的reequest对象
.copy()——->复制该响应

Item类;
定义:Item对象表示一个从HTML页面中提取页面信息,由spider生成,由Pipeline处理。Item类似字典类型,可以照字典类型操作

 

===========================================================

实例:爬取股票数据

功能描述
   技术路线:scrapy
  目标:获取上交所和深交所所有股票的名称和交易信息
  输出:保存在文件中

数据网站的确定:
  获取股票列表:东方财富网:http://quote.eastmoney.com/stocklist.html
  获取个股信息:百度股票:https://gupiao.baidu.com/stock/
  单个股票:https://gupiao.baidu.com/stock/sz002439.thml

 

步骤1.创建一个工程和spider模板

 

步骤2.编写一个spider

#编写spider模板
# -*- coding: utf-8 -*-
import scrapy
import re

class StockSpider(scrapy.Spider):
    name = 'stock'
    start_urls = ['http://quote.eastmoney.com/stocklist.html']

    def parse(self, response):#解析页面的函数方法
        for href in response.css("a::attr(href)").extract():
            try:
                stock = re.findall(r"[s][hz]\d{6}",href)[0]#通过正则表达式获取东方财富网的股票代码
                url ="http://stockdata.stock.hexun.com/" + stock + ".shtml"#生成一个百度股票页面的对应链接
                yield scrapy.Request(url,callback=self.parse_stock)#将链接作为新的请求提交给scrapy框架,yield关键词将parse变成一个生成器
            except:
                continue

    def parse_stock(self,response):#从百度股票的单个页面中提取信息
        infoDict = {}
        stockInfo = response.css(".stock-bets")
        name = stockInfo.css(".bets-name").extract()[0]#获取股票名字
        keyList = stockInfo.cs("dt").extract(0)#获取dt标签
        valueList = stockInfo.css("dd").extract()#获取dd标签
        for i in range(len(keyList)):#将提取的信息保存在字典中
            key = re.findall(r">.*</dt>",keyList[i])[0][1:5]
            try:
                val = re.findall(r"\d+\.?.*</dd>",valueList[i])[0][0:-5]
            except:
                val = "--"
            infoDict[key]=val

        infoDict.update(
            {"股票名称":re.findall("\s.*\(",name)[0].split()[0] + \
                    re.findall("\>.*\<",name)[0][1:-1]})
            #提取的整个股票页面的相关信息
        yield infoDict

 

步骤3.编写Item Pipeline

#编写Item Pipeline
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


class BaidustocksPipeline(object):
    def process_item(self, item, spider):
        return item

class BaidustocksPipeline(object):
    def open_spider(self,spider):#指当爬虫被调用时对应的Pipeline启动的方法
        self.f = open("BaidustockInfo.txt","w")
        
    def close_spider(self,spider):#指一个函数关闭时对应的Pipeline方法
        self.f.close()
        
    def process_item(self,item,spider):#指对每一个item项进行处理时对应的方法
        try:
            line = str(dict(item)) + "\n"#将所有信息写到item中
            self.f.write(line)
        except:
            pass
        return item

设置settings.py文件

 

最后:scrapy crawl <文件名称>运行程序即可

 

版权声明:本文为defend009原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/defend009/p/12729280.html