@@@老师博客地址:::::

http://www.cnblogs.com/linhaifeng/articles/7811861.html

一、介绍

Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。

Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。整体架构大致如下

The data flow in Scrapy is controlled by the execution engine, and goes like this:

  1. The Engine gets the initial Requests to crawl from the Spider.
  2. The Engine schedules the Requests in the Scheduler and asks for the next Requests to crawl.
  3. The Scheduler returns the next Requests to the Engine.
  4. The Engine sends the Requests to the Downloader, passing through the Downloader Middlewares (see process_request()).
  5. Once the page finishes downloading the Downloader generates a Response (with that page) and sends it to the Engine, passing through the Downloader Middlewares (see process_response()).
  6. The Engine receives the Response from the Downloader and sends it to the Spider for processing, passing through the Spider Middleware (see process_spider_input()).
  7. The Spider processes the Response and returns scraped items and new Requests (to follow) to the Engine, passing through the Spider Middleware (see process_spider_output()).
  8. The Engine sends processed items to Item Pipelines, then send processed Requests to the Scheduler and asks for possible next Requests to crawl.
  9. The process repeats (from step 1) until there are no more requests from the Scheduler.

Components:

  1. 引擎(EGINE)

    引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。

  2. 调度器(SCHEDULER)
    用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
  3. 下载器(DOWLOADER)
    用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的
  4. 爬虫(SPIDERS)
    SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求
  5. 项目管道(ITEM PIPLINES)
    在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作
  6. 下载器中间件(Downloader Middlewares)
    位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response,你可用该中间件做以下几件事

    1. process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);
    2. change received response before passing it to a spider;
    3. send a new Request instead of passing received response to a spider;
    4. pass response to a spider without fetching a web page;
    5. silently drop some requests.
  7. 爬虫中间件(Spider Middlewares)
    位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)

官网链接:https://docs.scrapy.org/en/latest/topics/architecture.html

二、安装

#Windows平台1、pip3 install wheel #安装后,便支持通过wheel文件安装软件,wheel文件官网:https://www.lfd.uci.edu/~gohlke/pythonlibs3、pip3 install lxml4、pip3 install pyopenssl5、下载并安装pywin32:https://sourceforge.net/projects/pywin32/files/pywin32/6、下载twisted的wheel文件:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted7、执行pip3 install 下载目录\Twisted-17.9.0-cp36-cp36m-win_amd64.whl8、pip3 install scrapy#Linux平台1、pip3 install scrapy

三、命令行工具

#1 查看帮助scrapy -hscrapy <command> -h#2 有两种命令:其中Project-only必须切到项目文件夹下才能执行,而Global的命令则不需要
    Global commands:startproject #创建项目genspider    #创建爬虫程序settings     #如果是在项目目录下,则得到的是该项目的配置runspider    #运行一个独立的python文件,不必创建项目shell        #scrapy shell url地址  在交互式调试,如选择器规则正确与否fetch        #独立于程单纯地爬取一个页面,可以拿到请求头view         #下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求version      #scrapy version 查看scrapy的版本,scrapy version -v查看scrapy依赖库的版本Project-only commands:crawl        #运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY = Falsecheck        #检测项目中有无语法错误list         #列出项目中所包含的爬虫名edit         #编辑器,一般不用parse        #scrapy parse url地址 --callback 回调函数  #以此可以验证我们的回调函数是否正确bench        #scrapy bentch压力测试#3 官网链接https://docs.scrapy.org/en/latest/topics/commands.html

#1、执行全局命令:请确保不在某个项目的目录下,排除受该项目配置的影响
scrapy startproject MyProjectcd MyProject
scrapy genspider baidu www.baidu.comscrapy settings --get XXX #如果切换到项目目录下,看到的则是该项目的配置

scrapy runspider baidu.pyscrapy shell https://www.baidu.comresponseresponse.statusresponse.bodyview(response)scrapy view https://www.taobao.com #如果页面显示内容不全,不全的内容则是ajax请求实现的,以此快速定位问题

scrapy fetch --nolog --headers https://www.taobao.comscrapy version #scrapy的版本

scrapy version -v #依赖库的版本#2、执行项目命令:切到项目目录下
scrapy crawl baidu
scrapy check
scrapy list
scrapy parse http://quotes.toscrape.com/ --callback parse
scrapy bench

示范用法

四、项目结构以及爬虫应用简介

project_name/scrapy.cfgproject_name/__init__.pyitems.pypipelines.pysettings.pyspiders/__init__.py爬虫1.py爬虫2.py爬虫3.py

文件说明:

  • scrapy.cfg  项目的主配置信息,用来部署scrapy时使用,爬虫相关的配置信息在settings.py文件中。
  • items.py    设置数据存储模板,用于结构化数据,如:Django的Model
  • pipelines    数据处理行为,如:一般结构化的数据持久化
  • settings.py 配置文件,如:递归的层数、并发数,延迟下载等。强调:配置文件的选项必须大写否则视为无效,正确写法USER_AGENT='xxxx'
  • spiders      爬虫目录,如:创建文件,编写爬虫规则

注意注意注意:一般创建爬虫文件时,以网站域名命名

import scrapyclass XiaoHuarSpider(scrapy.spiders.Spider):name = "xiaohuar"                            # 爬虫名称 *****allowed_domains = ["xiaohuar.com"]  # 允许的域名start_urls = ["http://www.xiaohuar.com/hua/",   # 其实URL
    ]def parse(self, response):# 访问起始URL并获取结果后的回调函数

爬虫1.py

import sys,os
sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')

关于Windows编码

五、Spiders

默认只能在cmd中执行爬虫,如果想在pycharm中执行需要做

#在项目目录下新建:entrypoint.py
from scrapy.cmdline import execute
execute(['scrapy', 'crawl', 'xiaohua'])

强调:配置文件的选项必须是大写,如X='1'

模版:CrawlSpider

https://docs.scrapy.org/en/latest/topics/spiders.html

六、Selectors

#1 //与/
#2 text
#3、extract与extract_first:从selector对象中解出内容
#4、属性:xpath的属性加前缀@
#4、嵌套查找
#5、设置默认值
#4、按照属性查找
#5、按照属性模糊查找
#6、正则表达式
#7、xpath相对路径
#8、带变量的xpath

response.selector.css()
response.selector.xpath()
可简写为
response.css()
response.xpath()#1 //与/
response.xpath('//body/a/')#
response.css('div a::text')>>> response.xpath('//body/a') #开头的//代表从整篇文档中寻找,body之后的/代表body的儿子
[]
>>> response.xpath('//body//a') #开头的//代表从整篇文档中寻找,body之后的//代表body的子子孙孙
[<Selector xpath='//body//a' data='<a href="image1.html">Name: My image 1 <'>, <Selector xpath='//body//a' data='<a href="image2.html">Name: My image 2 <'>, <Selector xpath='//body//a' data='<a href="
image3.html">Name: My image 3 <'>, <Selector xpath='//body//a' data='<a href="image4.html">Name: My image 4 <'>, <Selector xpath='//body//a' data='<a href="image5.html">Name: My image 5 <'>]#2 text
>>> response.xpath('//body//a/text()')
>>> response.css('body a::text')#3、extract与extract_first:从selector对象中解出内容
>>> response.xpath('//div/a/text()').extract()
['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 ']
>>> response.css('div a::text').extract()
['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 ']>>> response.xpath('//div/a/text()').extract_first()
'Name: My image 1 '
>>> response.css('div a::text').extract_first()
'Name: My image 1 '#4、属性:xpath的属性加前缀@
>>> response.xpath('//div/a/@href').extract_first()
'image1.html'
>>> response.css('div a::attr(href)').extract_first()
'image1.html'#4、嵌套查找
>>> response.xpath('//div').css('a').xpath('@href').extract_first()
'image1.html'#5、设置默认值
>>> response.xpath('//div[@id="xxx"]').extract_first(default="not found")
'not found'#4、按照属性查找
response.xpath('//div[@id="images"]/a[@href="image3.html"]/text()').extract()
response.css('#images a[@href="image3.html"]/text()').extract()#5、按照属性模糊查找
response.xpath('//a[contains(@href,"image")]/@href').extract()
response.css('a[href*="image"]::attr(href)').extract()response.xpath('//a[contains(@href,"image")]/img/@src').extract()
response.css('a[href*="imag"] img::attr(src)').extract()response.xpath('//*[@href="image1.html"]')
response.css('*[href="image1.html"]')#6、正则表达式
response.xpath('//a/text()').re(r'Name: (.*)')
response.xpath('//a/text()').re_first(r'Name: (.*)')#7、xpath相对路径
>>> res=response.xpath('//a[contains(@href,"3")]')[0]
>>> res.xpath('img')
[<Selector xpath='img' data='<img src="data:image3_thumb.jpg">'>]
>>> res.xpath('./img')
[<Selector xpath='./img' data='<img src="data:image3_thumb.jpg">'>]
>>> res.xpath('.//img')
[<Selector xpath='.//img' data='<img src="data:image3_thumb.jpg">'>]
>>> res.xpath('//img') #这就是从头开始扫描
[<Selector xpath='//img' data='<img src="data:image1_thumb.jpg">'>, <Selector xpath='//img' data='<img src="data:image2_thumb.jpg">'>, <Selector xpath='//img' data='<img src="data:image3_thumb.jpg">'>, <Selector xpa
th='//img' data='<img src="data:image4_thumb.jpg">'>, <Selector xpath='//img' data='<img src="data:image5_thumb.jpg">'>]#8、带变量的xpath
>>> response.xpath('//div[@id=$xxx]/a/text()',xxx='images').extract_first()
'Name: My image 1 '
>>> response.xpath('//div[count(a)=$yyy]/@id',yyy=5).extract_first() #求有5个a标签的div的id
'images'

View Code

https://docs.scrapy.org/en/latest/topics/selectors.html

七、Items

https://docs.scrapy.org/en/latest/topics/items.html

八、Item Pipeline

https://docs.scrapy.org/en/latest/topics/item-pipeline.html

九、Dowloader Middeware

https://docs.scrapy.org/en/latest/topics/downloader-middleware.html

十、Spider Middleware

https://docs.scrapy.org/en/latest/topics/spider-middleware.html

十一、 爬取亚马逊商品信息

1、
scrapy startproject Amazon
cd Amazon
scrapy genspider spider_goods www.amazon.cn2、settings.py
ROBOTSTXT_OBEY = False
#请求头
DEFAULT_REQUEST_HEADERS = {'Referer':'https://www.amazon.cn/','User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36'
}
#打开注释
HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_DIR = 'httpcache'
HTTPCACHE_IGNORE_HTTP_CODES = []
HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'3、items.py
class GoodsItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()#商品名字goods_name = scrapy.Field()#价钱goods_price = scrapy.Field()#配送方式delivery_method=scrapy.Field()4、spider_goods.py
# -*- coding: utf-8 -*-
import scrapyfrom Amazon.items import  GoodsItem
from scrapy.http import Request
from urllib.parse import urlencodeclass SpiderGoodsSpider(scrapy.Spider):name = 'spider_goods'allowed_domains = ['www.amazon.cn']# start_urls = ['http://www.amazon.cn/']def __int__(self,keyword=None,*args,**kwargs):super(SpiderGoodsSpider).__init__(*args,**kwargs)self.keyword=keyworddef start_requests(self):url='https://www.amazon.cn/s/ref=nb_sb_noss_1?'paramas={'__mk_zh_CN': '亚马逊网站','url': 'search - alias = aps','field-keywords': self.keyword}url=url+urlencode(paramas,encoding='utf-8')yield Request(url,callback=self.parse_index)def parse_index(self, response):print('解析索引页:%s' %response.url)urls=response.xpath('//*[contains(@id,"result_")]/div/div[3]/div[1]/a/@href').extract()for url in urls:yield Request(url,callback=self.parse_detail)next_url=response.urljoin(response.xpath('//*[@id="pagnNextLink"]/@href').extract_first())print('下一页的url',next_url)yield Request(next_url,callback=self.parse_index)def parse_detail(self,response):print('解析详情页:%s' %(response.url))item=GoodsItem()# 商品名字item['goods_name'] = response.xpath('//*[@id="productTitle"]/text()').extract_first().strip()# 价钱item['goods_price'] = response.xpath('//*[@id="priceblock_ourprice"]/text()').extract_first().strip()# 配送方式item['delivery_method'] = ''.join(response.xpath('//*[@id="ddmMerchantMessage"]//text()').extract())return item5、自定义pipelines
#sql.py
import pymysql
import settingsMYSQL_HOST=settings.MYSQL_HOST
MYSQL_PORT=settings.MYSQL_PORT
MYSQL_USER=settings.MYSQL_USER
MYSQL_PWD=settings.MYSQL_PWD
MYSQL_DB=settings.MYSQL_DBconn=pymysql.connect(host=MYSQL_HOST,port=int(MYSQL_PORT),user=MYSQL_USER,password=MYSQL_PWD,db=MYSQL_DB,charset='utf8'
)
cursor=conn.cursor()class Mysql(object):@staticmethoddef insert_tables_goods(goods_name,goods_price,deliver_mode):sql='insert into goods(goods_name,goods_price,delivery_method) values(%s,%s,%s)'cursor.execute(sql,args=(goods_name,goods_price,deliver_mode))conn.commit()@staticmethoddef is_repeat(goods_name):sql='select count(1) from goods where goods_name=%s'cursor.execute(sql,args=(goods_name,))if cursor.fetchone()[0] >= 1:return Trueif __name__ == '__main__':cursor.execute('select * from goods;')print(cursor.fetchall())#pipelines.py
from Amazon.mysqlpipelines.sql import Mysqlclass AmazonPipeline(object):def process_item(self, item, spider):goods_name=item['goods_name']goods_price=item['goods_price']delivery_mode=item['delivery_method']if not Mysql.is_repeat(goods_name):Mysql.insert_table_goods(goods_name,goods_price,delivery_mode)6、创建数据库表
create database amazon charset utf8;
create table goods(id int primary key auto_increment,goods_name char(30),goods_price char(20),delivery_method varchar(50)
);7、settings.py
MYSQL_HOST='localhost'
MYSQL_PORT='3306'
MYSQL_USER='root'
MYSQL_PWD='123'
MYSQL_DB='amazon'#数字代表优先级程度(1-1000随意设置,数值越低,组件的优先级越高)
ITEM_PIPELINES = {'Amazon.mysqlpipelines.pipelines.mazonPipeline': 1,
}#8、在项目目录下新建:entrypoint.py
from scrapy.cmdline import execute
execute(['scrapy', 'crawl', 'spider_goods','-a','keyword=iphone8'])

View Code

https://pan.baidu.com/s/1boCEBT1

转载于:https://www.cnblogs.com/wanghl1011/articles/8298646.html

1月16日学习内容整理:爬虫框架:Scrapy相关推荐

  1. 3月16日学习内容整理:metaclass

    1.首先我们要知道: 对象是由类创建的,而类是由type类创建的 所以创建类有两个方法: class Foo(object):pass# 类名,继承关系,属性 Foo = type('Foo',(ob ...

  2. 1月16日学习内容整理:存储库MongoDB之文档的增删改查操作补充

    文档操作 一.查 1.比较运算 # SQL:=,!=,>,<,>=,<= # MongoDB:{key:value}代表什么等于什么,"$ne"," ...

  3. 1月17日学习内容整理:Scrapy框架补充之pipeline,去重规则

    @@@老师博客::: 关于高性能和scrapy框架 http://www.cnblogs.com/wupeiqi/articles/6229292.html 关于scrapy-reids组件 http ...

  4. 10月25日学习内容整理:数据操作:增加更新删除,单表查询操作

    >>\G是按行显示,必须是大写 >>插入数据:补充另一种插入记录的方法 -->insert into 表名1(字段1,字段2,...) select 字段1,字段2,.. ...

  5. 11月8日学习内容整理:js的引入方式,变量数据类型,运算符,流程控制,函数...

    js是一门成熟的编程语言,专门用浏览器客户端执行的语言 一.js的引入方式 1.直接在body标签中使用script标签写js语言 2.通过script标签导入js文件,<script   sr ...

  6. 9月7日学习内容整理:内置函数

    一.内置函数 1.作用域相关: (1)globals()   查看全局作用域,显示所有的变量 (2)locals()      查看局部作用域,只会显示当前函数使用的变量 2.迭代器相关: (1)it ...

  7. 9月13日学习内容整理:异常处理

    一.异常处理 1.排错:多行报错的时候,真正报错的是最下面:若报错的地方在别人的代码里,注意别人写的代码是不会报错的,还是找自己的错 2.特点:一旦发生异常,程序不会再向下执行 3.处理方法: (1) ...

  8. 2月1日学习内容整理:算法

    1.概念 一个计算过程,解决问题的方法 2.时间复杂度和空间复杂度 时间复杂度:用来表示算法的运行效率 >>>一般来说,时间复杂度高的算法比时间复杂度低的算法运行效率高,,但这不是绝 ...

  9. 11月17日学习内容整理:jquery文档处理,事件细讲,动画

    一.文档处理:下面举例中的B可以是标签也可以是选择器也可以是字符串 >>>添加到指定元素内部的后面 $(A).append(B) // 把B放到A内部元素的最后,A是父节点$(A). ...

最新文章

  1. mysql 密码 You must reset your password using ALTER USER statement before executing this statement....
  2. Android九宫图(draw9patch)
  3. 病毒(信息学奥赛一本通-T1396)
  4. 工信部:老年人拨打三大运营商客服享受一键呼入等服务
  5. linux ls 目录结构,linux 系统目录结构 ls命令 文件类型 alias命令
  6. Golang简单日志类
  7. XP时代的结束是阵痛还是真痛
  8. RabbitMQ的入门程序test测试代码
  9. set python3_python3学习之set集合
  10. GPUGraphicsGame tools
  11. 还记得2048怎么玩吗?快来玩会儿(摸鱼)吧
  12. matlab触发 ttl,请问如何用TTL信号触发单反相机拍摄
  13. Kubuntu下root登录
  14. MyDiskTest硬盘检测绿色版
  15. “三高“Mysql - Mysql备份概览
  16. scrollTo方法的平滑滚动
  17. UNION 和 UNION ALL的区别
  18. 屏幕左上角出现【最小化】按钮,鼠标无法点击
  19. 超级电容容量及放电时间计算方法
  20. Microsoft Project 2010 (Beta)下载

热门文章

  1. 【译】使用 CocoaPods 模块化iOS应用
  2. SQL查询语句精华总结
  3. 【elasticsearch】ES扩容后报错Can not be imported as a dangling index as index with same name
  4. Java——类的继承
  5. 9.Springcloud的Hystrix服务熔断和服务降级
  6. 软件测试--网络协议(三)
  7. MySQL基础2——表的约束
  8. 虚拟机服务器被攻击,Linux服务器被攻击用来挖矿了
  9. 360浏览器没有声音_你用的浏览器好用吗?该国产电脑浏览器,极速、安全,值得使用...
  10. 20%3cx 30 的c语言表达式是,判断题(指令正误)