Scrapy爬虫基本使用和技巧

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
image

一个简单的demo就完成了

三、Scrapy基本介绍

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

image

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的正则模块进行匹配
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容