一、Scrapy框架简介

  1. 1. 下载页面
  2. 2. 解析
  3. 3. 并发
  4. 4. 深度

二、安装

  1. linux下安装
  2. pip3 install scrapy
  3.  
  4. windows下安装
  5. a.pip3 install wheel
  6. b.下载twistedpywin32 http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
  7. c.进入下载目录
  8. 执行pip3 install Twisted-18.7.0-cp36-cp36m-win_amd64.whl #cp36为适合python3.6
  9. 执行pip3 install pywin32-224-cp36-cp36m-win_amd64.whl
  10.   d.pip3 install scrapy
  11. e.下载并安装pywin32:https://sourceforge.net/projects/pywin32/files/ #找到适合本机python版本的64位

三、Scrapy整体架构图

  3.1 Scrapy使用Twisted异步网络库来处理网络通讯

  3.2 各个主要文件说明

  spiders(蜘蛛)文件夹:如ip138.com

  1. name #不能省略,最好不要修改
  2. starts_urls #起始url
  3. allowed_domains #爬取允许域名列表,起始url不受影响。网页中的外链受此限制

四、基本使用

  1. 1. 指定初始url
  2. 2. 解析器响应内容
  3. - 给调度器
  4. - itempipeline;用于做格式化;持久化
  5.  
  6. 基本步骤:
  7. a:scrapy startproject 项目名 #创建项目
  8. b:进入项目目录
  9. c:scrapy genspider baidu www.baidu.com #创建start_url
  10. d:打开项目名\spiders\baidu.py进行编辑
  11. e:scrapy crawl baidu #执行,加--nolog可以不显示日志,如果没有内容显示,可能此IP已经有防爬机制,可换个不知名ip试试

五、筛选器

  5.1  Selector介绍

  在scrapy中,可以使用Selector筛选器,代替BeautifulSoup

  在scrapy项目里的spiders文件里的baidu.py爬虫文件编辑,导入Selecotr模块

  1. from scrapy.selector import Selector

  5.2 Selector(response=response).xpath()基本用法

  1. // #表示子子孙孙,即所有
  2. .// #当前对象的子孙中
  3. / #儿子
  4. /div #儿子中的div标签
  5. //div[@id] #所有标签含有id的div标签
  6. /div[@id='i1'] #儿子中的div且id ='i1'的标签
  7. obj.extract() #列表中每一个对象转换成字符串 ==>返回的是列表
  8. obj.extract_first() #列表中每一各对象转换成字符串==>返回的是列表中第一个元素
  9. //div/text() #获取所有div标签里的文本==》返回的是列表,元素是对象
  10. //a/@href #获取所有a标签里的url==》返回的是列表,元素是对象
  11. //a[starts-with(@href,"link")] #获取所有a标签,并且href属性是以link开头的
  12. //a[re:test(@href,"/sitehome/p/\d+")]/@href #正则,获取所有a标签属性href符合/sitehome/p/数字的
  13. //div[@id='i1'][@href=''xx] #[][]且的意思,即所有含有id='i1'且href='xxx'的div标签
  14. //a[contains(@href, "link")] #所有href字段包含link字符串的a标签

  5.3 简单示例

  需求:在www.ip138.com网站里,打印如下a标签的文本内容和url地址

  在爬虫文件(baidu.py)里的parse类方法里编辑 

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from scrapy.selector import Selector
  4.  
  5. class BaiduSpider(scrapy.Spider):
  6. name = 'baidu'
  7. allowed_domains = ['ip138.com']
  8. start_urls = ['http://www.ip138.com/']
  9.  
  10. def parse(self, response):
  11. #请求该页面下所有a标签==》列表,每个元素都是对象
  12. #找到div标签里有class=mod-guide属性下的所有子孙a标签里文本内容
  13. text_obj_list = Selector(response=response).xpath('//div[@class="module mod-guide"]//a/text()')
  14.  
  15. # 找到div标签里有class=mod-guide属性下的所有子孙a标签里url
  16. url_obj_list = Selector(response=response).xpath('//div[@class="module mod-guide"]//a/@href')
  17.  
  18. #将列表中对象转化成列表中字符串
  19. text_str_list = text_obj_list.extract()
  20. url_str_list = url_obj_list.extract()
  21.  
  22. for a_text,a_url in zip(text_str_list,url_str_list):
  23. print(a_text,a_url)

代码

  如何运行代码?

  1. cmd窗口,进入项目目录,运行scrapy crawl baidu

  5.4 获取当前网页中的所有页码实例

  需求:获取博客园里的首页页码url

  

  在爬虫文件(ip138.py)里的parse类方法里编辑

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from scrapy.selector import Selector
  4.  
  5. class Ip138Spider(scrapy.Spider):
  6. name = 'ip138'
  7. allowed_domains = ['www.cnblogs.com']
  8. start_urls = ['https://www.cnblogs.com/']
  9.  
  10. urls_set = set()
  11.  
  12. def parse(self, response):
  13. # text_obj_list = Selector(response=response).xpath('//div[@class="module mod-guide"]//a/text()')
  14. # url_obj_list = Selector(response=response).xpath('//div[@class="module mod-guide"]//a/@href')
  15. #
  16. # text_str_list = text_obj_list.extract()
  17. # url_str_list = url_obj_list.extract()
  18. #
  19. # for text,url in zip(text_str_list,url_str_list):
  20. # print(text,url)
  21.  
  22. #获取当前页里的所有页码的url对象列表
  23. url_obj_list = Selector(response=response).xpath('//div[@class="pager"]/a/@href')
  24. ##或者2: starts-with(@属性,'值开头')
  25. #url_obj_list = Selector(response=response).xpath('//a[starts-with(@href,"/sitehome/p/")]/@href')
  26. ##或者3:正则表达式固定用法re:test(@属性值,"正则表达式")
  27. #url_obj_list = Selector(response=response).xpath('//a[re:test(@href,"/sitehome/p/\d+")]/@href')
  28.  
  29. #将对象列表转换成字符串列表
  30. url_str_list = url_obj_list.extract()
  31. for url in url_str_list:
  32. print(url)
  33.  
  34. #1.通过集合去除重复url
  35. #2.使用加密的MD5存储url,好处:加密和等长
  36. url_md5 = self.my_md5(url)
  37. if url_md5 not in self.urls_set:
  38. self.urls_set.add(url_md5)
  39. print(url_md5)
  40. else:
  41. print('%s已经存在'%url_md5)
  42.  
  43. def my_md5(self,url):
  44. import hashlib
  45. obj = hashlib.md5()
  46. obj.update(bytes(url,encoding='utf-8'))
  47. return obj.hexdigest()

代码

  5.5 获得当前网页里的页码自动请求爬取实例

  需求:自动爬取博客园的所有页码(基于5.4案例的基础)

  

  在爬虫文件(ip138.py)里的parse类方法里编辑

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from scrapy.selector import Selector
  4. from scrapy.http import Request
  5.  
  6. class Ip138Spider(scrapy.Spider):
  7. name = 'ip138'
  8. allowed_domains = ['www.cnblogs.com']
  9. start_urls = ['https://www.cnblogs.com/']
  10.  
  11. urls_set = set()
  12.  
  13. def parse(self, response):
  14.  
  15. #获取当前页里的所有页码的url对象列表
  16. url_obj_list = Selector(response=response).xpath('//div[@class="pager"]/a/@href')
  17. ##或者2: starts-with(@属性,'值开头')
  18. #url_obj_list = Selector(response=response).xpath('//a[starts-with(@href,"/sitehome/p/")]/@href')
  19. ##或者3:正则表达式固定用法re:test(@属性值,"正则表达式")
  20. #url_obj_list = Selector(response=response).xpath('//a[re:test(@href,"/sitehome/p/\d+")]/@href')
  21.  
  22. #将对象列表转换成字符串列表
  23. url_str_list = url_obj_list.extract()
  24. for url in url_str_list:
  25.  
  26. #1.通过集合去除重复url
  27. if url not in self.urls_set:
  28. #print(url)
  29. self.urls_set.add(url)
  30. #拼接完整的url地址
  31. full_url = self.start_urls[0] + url
  32. #将url页码传给调度器去请求,并将下载的结果交给parse方法,yield的作用是将请求放入调度器
  33. yield Request(url=full_url,callback=self.parse)
  34.  
  35. for url in self.urls_set:
  36. print(url)

代码

  在setting.py中结尾新增一行DEPTH_LIMIT=1来指定递归的层次,默认是0,所有层次

  实例中关键点概括

  1. @href #取属性值
  2. starts-with(@href,"xx") #属性href的值以xx开始
  3. re:test(@href,"/sitehome/p/\d+") #正则re:test固定搭配
  4. yield Request(url=full_url,callback=self.parse) #交给调度器

六、item,pipeline使用

  6.1 需求:将博客园的文章标题和url保存到一个文件a.txt文件里。

     各文件代码如下:

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from scrapy.selector import Selector
  4. from scrapy.http import Request
  5. from .. import items
  6.  
  7. class Ip138Spider(scrapy.Spider):
  8. name = 'ip138'
  9. allowed_domains = ['www.cnblogs.com']
  10. start_urls = ['https://www.cnblogs.com/']
  11.  
  12. urls_set = set()
  13.  
  14. def parse(self, response):
  15.  
  16. #获取当前页面里的标题和url==>返回字符串
  17. title_str_list = Selector(response=response).xpath('//a[@class="titlelnk"]/text()').extract()
  18. href_str_list = Selector(response=response).xpath('//a[@class="titlelnk"]/@href').extract()
  19.  
  20. for title_str,href_str in zip(title_str_list,href_str_list):
  21. #print(title_str,' ',href_str)
  22.  
  23. #此处的参数title,和href来自于items.py文件里类Cnblogs里的属性
  24. item_obj = items.Cnblogs(title=title_str,href=href_str)
  25.  
  26. #将item对象传递给pipelines
  27. yield item_obj
  28.  
  29. #获取当前页里的所有页码的url对象列表
  30. page_obj_list = Selector(response=response).xpath('//div[@class="pager"]/a/@href')
  31. ##或者2: starts-with(@属性,'值开头')
  32. #page_obj_list = Selector(response=response).xpath('//a[starts-with(@href,"/sitehome/p/")]/@href')
  33. ##或者3:正则表达式固定用法re:test(@属性值,"正则表达式")
  34. #page_obj_list = Selector(response=response).xpath('//a[re:test(@href,"/sitehome/p/\d+")]/@href')
  35.  
  36. #将对象列表转换成字符串列表
  37. page_str_list = page_obj_list.extract()
  38. for url in page_str_list:
  39.  
  40. #1.通过集合去除重复url
  41. if url not in self.urls_set:
  42. self.urls_set.add(url)
  43. print(url)
  44.  
  45. #拼接完整的url地址
  46. full_url = self.start_urls[0] + url
  47. #将url页码传给调度器去请求,并将下载的结果交给parse方法,yield的作用是将请求放入调度器
  48. yield Request(url=full_url,callback=self.parse)

ip138.py文件

  1. # -*- coding: utf-8 -*-
  2.  
  3. # Define here the models for your scraped items
  4. #
  5. # See documentation in:
  6. # https://doc.scrapy.org/en/latest/topics/items.html
  7.  
  8. import scrapy
  9.  
  10. class Cnblogs(scrapy.Item):
  11. # define the fields for your item here like:
  12. # name = scrapy.Field()
  13. title = scrapy.Field()
  14. href = scrapy.Field()

items.py文件

  1. # -*- coding: utf-8 -*-
  2.  
  3. # Define your item pipelines here
  4. #
  5. # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  6. # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
  7.  
  8. class Day0310Pipeline(object):
  9. def process_item(self, item, spider):
  10. content = "%s %s\n"%(item['title'],item['href'])
  11. f = open('a.json','a')
  12. f.write(content)
  13. f.close()
  14. # return item

pipelines.py文件

  1. ITEM_PIPELINES = {
  2. 'day0310.pipelines.Day0310Pipeline': 300,
  3. }

setting.py文件

  6.2 实例中关键点概括

  1. #items.py文件中
  2. class Cnblogs(scrapy.Item):
  3. title = scrapy.Field()
  4. href = scrapy.Field()
  5.  
  6. #ip138.py文件中
  7. from .. import items
  8. item_obj = items.Cnblogs(title=title_str,href=href_str) #此处的参数title,和href来自于items.py文件里类Cnblogs里的属性
  9.  
  10. yield item_obj #将item对象传递给pipelines
  11.  
  12. #pipelines.py文件中,可对收集到的数据进行存储
  13. class Day0310Pipeline(object):
  14. def process_item(self, item, spider): #item为ip138.py文件里的对象化的数据,spider为来自哪只蜘蛛对象
  15. content = "%s %s\n"%(item['title'],item['href'])
  16. f = open('a.json','a')
  17. f.write(content)
  18. f.close()
  19.  
  20. #setting.py文件中注册下pipelines的类
  21. ITEM_PIPELINES = {
  22. 'day0310.pipelines.Day0310Pipeline': 300,
  23. }
  24. 数字越高越优先

Scrapy爬虫框架学习的更多相关文章

  1. scrapy爬虫框架学习笔记(一)

    scrapy爬虫框架学习笔记(一) 1.安装scrapy pip install scrapy 2.新建工程: (1)打开命令行模式 (2)进入要新建工程的目录 (3)运行命令: scrapy sta ...

  2. Scrapy 爬虫框架学习笔记(未完,持续更新)

    Scrapy 爬虫框架 Scrapy 是一个用 Python 写的 Crawler Framework .它使用 Twisted 这个异步网络库来处理网络通信. Scrapy 框架的主要架构 根据它官 ...

  3. Python之Scrapy爬虫框架安装及简单使用

    题记:早已听闻python爬虫框架的大名.近些天学习了下其中的Scrapy爬虫框架,将自己理解的跟大家分享.有表述不当之处,望大神们斧正. 一.初窥Scrapy Scrapy是一个为了爬取网站数据,提 ...

  4. scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250

    scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250 前言 经过上一篇教程我们已经大致了解了Scrapy的基本情况,并写了一个简单的小demo.这次我会以爬取豆瓣电影TOP250为例进一步为大 ...

  5. Scrapy爬虫框架(实战篇)【Scrapy框架对接Splash抓取javaScript动态渲染页面】

    (1).前言 动态页面:HTML文档中的部分是由客户端运行JS脚本生成的,即服务器生成部分HTML文档内容,其余的再由客户端生成 静态页面:整个HTML文档是在服务器端生成的,即服务器生成好了,再发送 ...

  6. Scrapy爬虫框架中的两个流程

    下面对比了Scrapy爬虫框架中的两个流程—— ① Scrapy框架的基本运作流程:② Spider或其子类的几个方法的执行流程. 这两个流程是互相联系的,可对比学习. 1 ● Scrapy框架的基本 ...

  7. 安装scrapy 爬虫框架

    安装scrapy 爬虫框架 个人根据学习需要,在Windows搭建scrapy爬虫框架,搭建过程种遇到个别问题,共享出来作为记录. 1.安装python 2.7 1.1下载 下载地址 1.2配置环境变 ...

  8. scrapy爬虫框架教程(二)-- 爬取豆瓣电影

    前言 经过上一篇教程我们已经大致了解了Scrapy的基本情况,并写了一个简单的小demo.这次我会以爬取豆瓣电影TOP250为例进一步为大家讲解一个完整爬虫的流程. 工具和环境 语言:python 2 ...

  9. Python爬虫教程-31-创建 Scrapy 爬虫框架项目

    本篇是介绍在 Anaconda 环境下,创建 Scrapy 爬虫框架项目的步骤,且介绍比较详细 Python爬虫教程-31-创建 Scrapy 爬虫框架项目 首先说一下,本篇是在 Anaconda 环 ...

随机推荐

  1. MyBatis从入门到精通:第二章数据的创建与插入文件

    数据库表的创建: create table sys_user ( id bigint not null auto_increment, ), user_password ), user_email ) ...

  2. I/O:RandomAccessFile

    RandomAccessFile: /* 此类的实例支持对随机访问文件的读取和写入.随机访问文件的行为类似存储在文件系统中的一个 大型 byte 数组.存在指向该隐含数组的光标或索引,称为文件指针:输 ...

  3. 看MySQL的参数调优及数据库锁实践有这一篇足够了

    史上最强MySQL参数调优及数据库锁实践 1. 应用优化 1.2 减少对MySQL的访问 1.2.1 避免对数据进行重复检索 1.2.2 增加cache层 1.3 负载均衡 1.3.1 利用MySQL ...

  4. LiteIDE TARGETARGS -conf_path=E:/PokerServer/src/GameServer/conf/texas.xml -log_dir=E:/PokerServer/src/GameServer/main/log

    LiteIDE TARGETARGS -conf_path=E:/PokerServer/src/GameServer/conf/texas.xml -log_dir=E:/PokerServer/s ...

  5. 个人永久性免费-Excel催化剂功能第42波-任意字符指定长度随机函数

    日常做表过程中,难免会有一些构造数据的场景,构造数据最好是用随机的数据,如随机密码,随机英文字母.数字等.在Excel原生的随机函数Rand中,仅能处理数字的随机,且最终生成的结果也是数字类型.今天E ...

  6. 集群之间配置 SSH无密码登录

    集群之间配置 SSH无密码登录 配置 ssh (1)基本语法 ssh 另一台电脑的 ip 地址 (2)ssh 连接时出现 Host key verification failed 的解决方法 # ss ...

  7. [剑指offer] 3. 从头到尾打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 思路: 利用容器,遍历一遍加入到一个新容器里,然后反置输出. vector 用 reverse stack 则直接一个个出栈 ...

  8. Java EE.Servlet.处理请求

    Servlet的核心工作便是处理客户端提交的请求信息,生成动态响应信息返回客户端. 1.请求参数 POST方法一般用于更新服务器上的资源,当时用POST方法时,提交的数据包含在HTTP实体内,而GET ...

  9. laravel5.6 使用迁移创建表

    laravel 使用迁移创建表 创建迁移文件 --table 和 --create 选项可以用于指定表名以及该迁移是否要创建一个新的数据表.这些选项只需要简单放在上述迁移命令后面并指定表名: php ...

  10. 计时器(Chronometer)、标签(TabHost)

    计时器(Chronometer) 方法 描述 public Chronometer(Context context)[构造方法] 创建Chronometer对象 public long getBase ...