当前位置:   article > 正文

【Python自查手册】之多协程爬虫Scrapy框架的用法_scrapy 协程

scrapy 协程

Scrapy结构

Scheduler(调度器)部门主要负责处理引擎发送过来的requests对象(即网页请求的相关信息集合,包括params,data,cookies,request headers…等),会把请求的url以有序的方式排列成队,并等待引擎来提取(功能上类似于gevent库的queue模块)。

Downloader(下载器)部门则是负责处理引擎发送过来的requests,进行网页爬取,并将返回的response(爬取到的内容)交给引擎。它对应的是爬虫流程【获取数据】这一步。

Spiders(爬虫)部门是公司的核心业务部门,主要任务是创建requests对象和接受引擎发送过来的response(Downloader部门爬取到的内容),从中解析并提取出有用的数据。它对应的是爬虫流程【解析数据】和【提取数据】这两步。

Item Pipeline(数据管道)部门则是公司的数据部门,只负责存储和处理Spiders部门提取到的有用数据。这个对应的是爬虫流程【存储数据】这一步。

Downloader Middlewares(下载中间件)的工作相当于下载器部门的秘书,比如会提前对引擎大boss发送的诸多requests做出处理。

Spider Middlewares(爬虫中间件)的工作则相当于爬虫部门的秘书,比如会提前接收并处理引擎大boss发送来的response,过滤掉一些重复无用的东西。

Scrapy工作原理

在这里插入图片描述

Scrapy中的程序全部都是异步模式,所有的请求或返回的响应都由引擎自动分配去处理;哪怕有某个请求出现异常,程序也会做异常处理,跳过报错的请求,继续往下运行程序

安装方法:
Windows:在终端输入命令:pip install scrapy
mac:在终端输入命令:pip3 install scrapy

创建项目

打开终端(windows:Win+R,输入cmd;mac:command+空格,搜索“终端”),然后跳转到你想要保存项目的目录下

再输入一行能帮我们创建Scrapy项目的命令:scrapy startproject douban,douban就是Scrapy项目的名字。按下enter键,一个Scrapy项目就创建成功了
在这里插入图片描述
在这里插入图片描述

编辑爬虫–top250.py

import scrapy
import bs4
from ..items import DoubanItem
# 需要引用DoubanItem,它在items里面。因为是items在top250.py的上一级目录,所以要用..items,这是一个固定用法。
class DoubanSpider(scrapy.Spider): #定义一个爬虫类DoubanSpider,DoubanSpider类继承自scrapy.Spider类
    name = 'douban' #name是定义爬虫的名字,这个名字是爬虫的唯一标识
    allowed_domains = ['book.douban.com'] # allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。如果网址的域名不在这个列表里,就会被过滤掉。
#为什么会有这个设置呢?当你在爬取大量数据时,经常是从一个URL开始爬取,然后关联爬取更多的网页。比如,假设我们今天的爬虫目标不是爬书籍信息,而是要爬豆瓣图书top250的书评。我们会先爬取书单,再找到每本书的URL,再进入每本书的详情页面去抓取评论。
#allowed_domains就限制了,我们这种关联爬取的URL,一定在book.douban.com这个域名之下,不会跳转到某个奇怪的广告页面。
    start_urls = [] #start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。在此,allowed_domains的设定对start_urls里的网址不会有影响。
    for x in range(3):
        url = 'https://book.douban.com/top250?start=' + str(x * 25)
        start_urls.append(url)

    def parse(self, response):
    #parse是Scrapy里默认处理response的一个方法,中文是解析。
        bs = bs4.BeautifulSoup(response.text,'html.parser')
        #用BeautifulSoup解析response。
        datas = bs.find_all('tr',class_="item")
        #用find_all提取<tr class="item">元素,这个元素里含有书籍信息。
        for data in  datas:
        #遍历data。
            item = DoubanItem()
            #实例化DoubanItem这个类。
            item['title'] = data.find_all('a')[1]['title']
            #提取出书名,并把这个数据放回DoubanItem类的title属性里。
            item['publish'] = data.find('p',class_='pl').text
            #提取出出版信息,并把这个数据放回DoubanItem类的publish里。
            item['score'] = data.find('span',class_='rating_nums').text
            #提取出评分,并把这个数据放回DoubanItem类的score属性里。
            print(item['title'])
            #打印书名。
            yield item
            #yield item是把获得的item传递给引擎。
            #每一次,当数据完成记录,它会离开spiders,来到Scrapy Engine(引擎),引擎将它送入Item Pipeline(数据管道)处理。这里,要用到yield语句。
            #yield语句可以简单理解为:它有点类似return,不过它和return不同的点在于,它不会结束函数,且能多次返回信息。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

定义数据–items.py

import scrapy
#导入了scrapy。目的是,我们等会所创建的类将直接继承scrapy中的scrapy.Item类。这样,有许多好用属性和方法,就能够直接使用。比如到后面,引擎能将item类的对象发给Item Pipeline(数据管道)处理。
class DoubanItem(scrapy.Item):
#定义一个类DoubanItem,它继承自scrapy.Item
    title = scrapy.Field() #scrapy.Field()这行代码实现的是,让数据能以类似字典的形式记录。打印出来的结果的确和字典非常相像,但它却并不是dict,它的数据类型是我们定义的DoubanItem,属于“自定义的Python字典”
    #定义书名的数据属性
    publish = scrapy.Field()
    #定义出版信息的数据属性
    score = scrapy.Field()
    #定义评分的数据属性
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

设置–settings.py

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' #把USER _AGENT的注释取消(删除#),然后替换掉user-agent的内容,就是修改了请求头。
# Obey robots.txt rules
ROBOTSTXT_OBEY = False #因为Scrapy是遵守robots协议的,如果是robots协议禁止爬取的内容,Scrapy也会默认不去爬取,所以把ROBOTSTXT_OBEY=True改成ROBOTSTXT_OBEY=False,就是把遵守robots协议换成无需遵从robots协议,这样Scrapy就能不受限制地运行。
  • 1
  • 2
  • 3
  • 4
'
运行

运行–main.py

#在最外层的大文件夹里新建一个main.py文件(与scrapy.cfg同级)。
from scrapy import cmdline
#在Scrapy中有一个可以控制终端命令的模块cmdline。导入了这个模块,我们就能操控终端。
cmdline.execute(['scrapy','crawl','douban'])
#在cmdline模块中,有一个execute方法能执行终端的命令行,不过这个方法需要传入列表的参数。我们想输入运行Scrapy的代码scrapy crawl douban,就需要写成['scrapy','crawl','douban']这样。
  • 1
  • 2
  • 3
  • 4
  • 5

爬取当当网2018销售排行榜

#items.py
import scrapy
class DangdangItem(scrapy.Item):
    name = scrapy.Field()
    author = scrapy.Field()
    price = scrapy.Field()
#bestsellers.py
import scrapy
import bs4
from ..items import DangdangItem
class DangdangSpider(scrapy.Spider):
    name = 'dangdang'
    allowed_domains = ['http://bang.dangdang.com']
    start_urls = []
    for x in range(1, 4):
        url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-year-2018-0-1-' + str(x)
        start_urls.append(url)

    def parse(self, response):
        soup = bs4.BeautifulSoup(response.text, 'html.parser')
        elements = soup.find('ul', class_="bang_list clearfix bang_list_mode").find_all('li')
        for element in elements:
            item = DangdangItem()
            item['name'] = element.find('div', class_="name").find('a')['title']
            item['author'] = element.find('div', class_="publisher_info").text
            item['price'] = element.find('div', class_="price").find('span', class_="price_n").text
            yield item
#main.py
from scrapy import cmdline
cmdline.execute(['scrapy','crawl','dangdang'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/825033
推荐阅读
相关标签
  

闽ICP备14008679号