Scrapy框架 - 一个友好且成熟的框架


美人镇贴
  1. 安装 pip install scrapy

  1. 框架结构:
    引擎:
    负责信号数据的传递,起协调作用。 (自动实现)

    调度器
    会将request对象储存在任务队列中,引擎会从任务队列里提取任务,交给下载器。 (框架实现)

    spider爬虫文件:
    通过起始url发起request请求,解析响应结果,1. 提取新的url,2. 提取数据。 (手动实现)

    下载器
    接受引擎传递过来的请求,发起请求获取响应,最终将响应结果通过中间件引擎提交spider爬虫文件。 (框架实现)

    管道文件:
    将spider爬虫文件yeilditem数据,做过滤持久化。 (手动实现)

    下载中间件
    自定义下载组件(请求结果响应结果都会经过中间件)。 (特殊需求手动实现)

    spider爬虫中间件
    可以自定义requset请求,过滤response请求。 (特殊需求手动实现)

    还有代理中间件,cookie中间件,User-Agent中间件,selenium中间件等。


1.0 第一个scrapy项目?

创建爬虫文件
1. 进入spiders文件夹
2. scrapy genspider 爬虫名称 域名

Spider
    |- scrapy.cfg  #项目部署文件
    |- Spider  #该项目的python模块,可以在这里加入代码
        |- __init__.py                 
        |- items.py   #主要是将爬取的非结构性的数据源提取结构性数据
        |- middlewares.py   #中间件      
        |- pipelines.py  #将爬取的数据进行持久化存储
        |-  __pycache__  
        |-  settings.py   #配置文件
        |-  spiders   #放置spider代码的目录
            |-  __init__.py 
            |-  __pycache__

1.1 创建爬虫模块

import scrapy
class Spider(scrapy.Spider): #继承自scrapy.Spider类
    name = "Spider"  #爬虫名(必须唯一)
    allowed_domain = ["xxx.com"]  #允许的域名(就是这个爬虫爬取链接的范围)
    start_urls = ["http://xxx.com/xxx/xxx"]     #开始爬取的链接
    
    def parse(self, response):                     
        pass  #这里返回了请求网站的response

内部框架的py文件以及作用:

  1. spider文件夹下存放爬虫文件
  2. item.py :根据目标网站,定义需要的字段
  3. pipeline:做数据的过滤和持久化
  4. middleware:中间件
  5. settings.py:设置文件,在里面做User-Agent的配置,Headlers,激活管道文件等等
  6. scrapy.cfg:配置文件,一般情况下,作部署时会用到它

1.2 框架的操作步骤,很简单哟

step1:

分析目标网站,根据要提取的目标数据在items.py中创建字段

step2:

(1) 在爬虫文件中设置目标url
(2) 解析请求成功的响应结果,提取目标数据,赋值给item,提取url继续发起请求

step3:

(1) setting下激活管道
(2) 在管道文件中做数据的过滤和持久化


2.1 图片下载:

    第一种: 正常的发起请求,正常的获取二进制文件,保存
    第二种: 自定义图片管道,继承自ImagePipeline.py
       重写方法:

            def get_media_request,item,spider...
                # 获取图片地址,发起请求

            def item_completed(self,results,spider,item...)
                # 在results结果中,根据图片下载状态,获取图片本地路径
                # 将获取的路径赋值给item,然后将item返回给其他管道

2.2 scrapy shell 交互是终端的使用

 1. scrapy shell "http://hr.tencent.com/position.php?&start=0#a"       进入网站
 2. view(response)         查看响应
 3. response.css('td.l.square a::text')       查看a标签的文本信息
 4. response.css('td.l.square a::text').extract()        查看a标签的文本信息 只看文本
 5. response.css('td.l.square a::attr(href)').extract()           查看a标签的href属性

2.3 scrapy.Spider

    customer_settings:
        def star_requests():
            # 根据起始url,发起请求
        def parse(self,response):
            # 得到响应的回调函数

2.4 选择对象的四个基本的方法

  • xpath(query):传入XPath表达式查询,返回该表达式所对应的所有节点的选择器列表列表
  • css(查询):传入CSS表达式查询,返回该表达式所对应的所有节点的选择器列表列表
  • extract():序列化该节点为Unicode字符串并返回列表列表。
  • re(正则表达式):根据传入的正则表达式对数据进行提取,返回的Unicode字符串列表.regex可以是一个已编译的正则,也可以是一个将为re.compile(正则表达式)编译为正则表达式的字符串。

2.5 item(容器)

Scrapy提供Item类。 Item对象是用于收集所抓取的数据的简单容器。它们提供了一个类似字典的 API,具有用于声明其可用字段的方便的语法
在items.py文件输入

class SpiderItem(scrapt.Item):
    url = scrapy.Field()
    time = scrapy.Field()
    title = scrapy.Field()
    content = scrapy.Field()
如果需要扩展的话,这样的方法扩展
class newSpiderItem(SpiderItem):
    xxx = scrapy.Field()

2.6 Item Pipeline(item管道)

当item在Spider中被传递后,它将会传递到Item PipeLine,利用Item PipeLine来进行数据保存

示例代码:
from scrapy.exceptions import DropItem
class SpiderPipeline(object):
    def __init__(self):
        self.file = open('xxx.html','w')
    def process_item(self,item,spider):
        if item['title']:
            file = (dict(item)) + "\n"
            self.file.write(file)
            return item
        else:
            raise DropItem("没有找到标题"+title)

    class 自定义管道(object):


        def __init__(self):
            # 可以在这里设置参数(比如,创建数据库连接,打开文件等)

        def open_spider(self,spider):
            # 爬虫开启的时候会调用,可选方法

        @classmethod
        def from_crawler(cls,crawler):
            # crawler:包含了爬虫的核心组件
            # 可以获取setting的一些设置参数
            return cls(...)

        def process_item(self,item.spider):
            # 所有yield中的item都会经过这个方法
            # 在这里做数据持久化(PyMySQL,PyMongo)

            多个item时处理方法1 :
                if isinstance(item,类名):   # 类名不需要加引号
                    # 根据不同的item,做不同的判断
                elif isinstance(item,类名):   # 类名不需要加引号  
            多个item时处理方法2 :
                1. 在item对应的类中,定义一个方法,返回sql语句和要插入的数据
                2. 使用item调用这个方法,得到sql语句和要插入的数据
                3. 执行插入语句

            return item    # 如果要将item传递给下一个管道,必须要将item return 回去

        def close_spider(self.spider):
            # 爬虫结束时调用
            # 在这里关闭数据库链接,关闭文件等

之后在setting.py的ITEM_PIPELINES中进行激活

ITEM_PIPELINES = {
       'Spider.pipelines.spiderPipeline':299}

process_item()方法可以用来判断是来自于哪个爬虫,item是被爬取对象,spider是爬取该item的Spider

Dropitem是一个错误捕获

299是判断运行顺序,范围为0~1000,数字越低优先级越高


通用爬虫

通过下面的命令可以快速创建 CrawlSpider模板 的代码:

scrapy genspider -t crawl 爬虫文件 域名

LinkExtractor的参数:

allow:
    一般跟一个正则表达式 表示提取url                     重用!!!

deny: 
    同样是者正则表达式,符合表达式的链接(优先级比allow高)

allowed_domains: 
    必须在我设置的域名下提取链接

deny_domains:
    不会在deny_domains设置的域名下提取链接

restrict_xpath:
    提取链接的时候,通过xpath语法定位到某些标签,提取标签下符合规则的链接          重用!!!

attrs:
    可以指定要提取标签的某些属性

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

推荐阅读更多精彩内容