Scrapy是什么?

Scrapy是一个由Python编写的开源协作爬虫框架,可以快速的从网站中提取需要的数据。Scrapy基础爬虫部分内部已经实现,只需编写采集规则即可,简单易用,扩展性强,多平台运行兼容性好。

详细笔者不做介绍,dddd(懂的都懂 哈哈)
scrapy官网: https://scrapy.org/
github地址:https://github.com/scrapy/scrapy

一、Scrapy安装

1.安装 lxml:pip3 install lxml。
2.安装pyOpenSSL:在官网下载wheel文件。
3.安装Twisted:在官网下载wheel文件。
4.安装PyWin32:在官网下载wheel文件
5.最后安装 scrapy,pip3 install scrapy
注意: 2、3、4如果采用pip3在线安装失败 可以采用下载后 pip install +文件路径/文件名进行安装 下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/

二、Scrapy基本使用

  • scrapy 创建项目
scrapy startproject projecname

得到一下目录

└─projecname
    │  scrapy.cfg                    #开发配置文件
    │
    └─projecname                     #工程模块
        │  items.py                  #获取定义模块 定义使用的字段
        │  middlewares.py       #中间件 定义中间件
        │  pipelines.py        #处理数据
        │  settings.py        #工程设置文件
        │  __init__.py        #空文件
        │
        ├─spiders            #爬虫目录,用于放置各种爬虫类文件
        │  │  __init__.py       #空文件
  • 新建一个爬虫
    在spiders文件夹下创建demo.py
import scrapy


class DemoSpider(scrapy.Spider):
    name = 'demo'
    start_urls = ['https://www.baidu.com']

    def parse(self, response):
        # 爬取百度首页热点和连接
        for hot in response.css("li.hotsearch-item"):
            title = hot.css(".title-content-title::text").get()
            href = hot.css("a::attr('href')").get()
            item = {'title': title,'href':href}
            print(item)
            yield item
        pass
  • 运行爬虫
scrapy crawl demo

pythonscrapy教程 python scrapy 简单教程_爬虫

一个简单的demo就完成了

三、Scrapy基本介绍

官网给出的数据流图和解释

pythonscrapy教程 python scrapy 简单教程_pythonscrapy教程_02


Scrapy 中的数据流由执行引擎控制,如下所示:

  1. 引擎获取最初的请求进行爬行。
  2. 引擎将请求发送至调度器。
  3. 调度器调度将请求发送引擎。
  4. 引擎将请求通过下载器中间件发送到下载器。
  5. 页面完成下载后, 下载器生成一个响应(带有该页面)通过下载器中间件将其发送到引擎。
  6. 该引擎接收来自响应,下载器将其发送到爬虫进行处理,其中通过爬虫中间件。
  7. 爬虫处理响应并返回项目和新的请求。
  8. 引擎发送处理好的数据,然后把处理的请求的调度,并请求下一个可能的爬虫请求。
  9. 该过程重复(从第 1 步开始),直到不再有来自Scheduler 的请求。

拿各个组件来讲可以理解为

  1. spider使用yeild将request发送给engine
  2. engine将request发送给scheduler
  3. scheduler,生成request交给engine
  4. engine拿到request,通过middleware发送给downloader
  5. downloader进行下载,在获取到response之后,又经过middleware发送给engine
  6. engine获取到response之后,返回给spider,spider的parse()方法对获取到的response进行处理,解析出items或者requests
  7. 将解析出来的items或者requests发送给engine
  8. engine获取到items或者requests,将items发送给ItemPipeline,将requests发送给scheduler(当只有调度器中不存在request时,程序才停止,及时请求失败scrapy也会重新进行请求)

简单整理一下各组件功能和实现情况

组件

功能

备注

Scrapy Engine

核心引擎 负责在不同模块和组件之间传递信号和数据

scrapy默认实现

Scheduler

请求调度器,存放来自引擎的请求,并在引擎请求时将它们排入队列

scrapy默认实现

Downloader

下载器,下载引擎发送过来的请求 并返回给引擎

scrapy默认实现

Spider

爬虫,编写请求,同时处理引擎发送过来的 response,后可以再次发送至引擎

需要自己实现

Item Pipeline

数据管道,处理引擎发送过来的数据,例如进行存储

需要自己实现

Middlewares

中间件,可实现过滤和拦截,默认是有 Downloader Middlewares和 Spider MiddlewaresSpider

非必要实现,根据需求实现

四、scrapy和常规使用和使用小技巧

小技巧

  • scrapy 使用item和ItemPipeline进行MySQL存储
    笔者这里使用的是Python3的PyMySQL,需要读者根据自身环境自行安装。

修改item.py和piplines.py,在item.py填写自己需要的字段,这里的item定义好的字段要在spider进行组装。

item.py

import scrapy

class DemoItem(scrapy.Item):
    # define the fields for your item here like:
    title = scrapy.Field()
    href = scrapy.Field()
    pass

piplines.py

import pymysql


class YunzexiaoPipeline:
    def __init__(self):
        self.conn = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            passwd='root',
            db='test',
            charset="utf8")
        self.cursor = self.conn.cursor()

    def process_item(self, item, spider):
        insert_sql = """
        insert into baidu(title,href)values (%s,%s)
        """
        # 插入数据 
        self.cursor.execute(insert_sql,(item['title'],item['href']))
        self.conn.commit()
        return item

    def __del__(self):
        #关闭操作游标
        self.cursor.close()
        #关闭数据库连接
        self.conn.close()

再次运行爬虫,pipelines会进行数据存储。

  • scrapy callbak 函数传参方法

借助cb_kwargs 进行传参

add_params = {'index': index}
 yield scrapy.Request(url, callback=self.page_content, cb_kwargs=add_params)

 # index 就是下传的参数 可以多个传参
 def page_content(self, response, index):
 	print(index)
 	pass
  • scrapy 运行不输出日志
scrpay crawl spider_name  -s LOG_FILE=all.log
  • scrapy 设置时间间隔和简单防爬
DOWNLOAD_DELAY = 2
RANDOMIZE_DOWNLOAD_DELAY = True
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'
COOKIES_ENABLED = True

或者设计随机请求间隔

from random import random
DOWNLOAD_DELAY = random()*5

随机请求头

# 1.在 settings 中添加
USER_AGENT_LIST=[
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]

# 2.在 middlewares 中添加中间件
# 引入部分
from settings import USER_AGENT_LIST
import random

class RandomUserAgentMiddleware(object):
    def process_request(self, request, spider):
        rand_use = random.choice(USER_AGENT_LIST)
        if rand_use:
            request.headers.setdefault('User-Agent', rand_use)
  • scrapy 解析返回内容技巧
  1. 使用css 进行解析 例如response.css(“li.hotsearch-item”):
  2. 使用Xpath进行解析
  3. 使用python的正则模块进行匹配