1月16日学习内容整理:爬虫框架:Scrapy
@@@老师博客地址:::::
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:
- The Engine gets the initial Requests to crawl from the Spider.
- The Engine schedules the Requests in the Scheduler and asks for the next Requests to crawl.
- The Scheduler returns the next Requests to the Engine.
- The Engine sends the Requests to the Downloader, passing through the Downloader Middlewares (see
process_request()
). - 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()
). - 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()
). - 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()
). - The Engine sends processed items to Item Pipelines, then send processed Requests to the Scheduler and asks for possible next Requests to crawl.
- The process repeats (from step 1) until there are no more requests from the Scheduler.
Components:
- 引擎(EGINE)
引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。
- 调度器(SCHEDULER)
用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址 - 下载器(DOWLOADER)
用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的 - 爬虫(SPIDERS)
SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求 - 项目管道(ITEM PIPLINES)
在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作 - 下载器中间件(Downloader Middlewares)
位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response,你可用该中间件做以下几件事- process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);
- change received response before passing it to a spider;
- send a new Request instead of passing received response to a spider;
- pass response to a spider without fetching a web page;
- silently drop some requests.
- 爬虫中间件(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'
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相关推荐
- 3月16日学习内容整理:metaclass
1.首先我们要知道: 对象是由类创建的,而类是由type类创建的 所以创建类有两个方法: class Foo(object):pass# 类名,继承关系,属性 Foo = type('Foo',(ob ...
- 1月16日学习内容整理:存储库MongoDB之文档的增删改查操作补充
文档操作 一.查 1.比较运算 # SQL:=,!=,>,<,>=,<= # MongoDB:{key:value}代表什么等于什么,"$ne"," ...
- 1月17日学习内容整理:Scrapy框架补充之pipeline,去重规则
@@@老师博客::: 关于高性能和scrapy框架 http://www.cnblogs.com/wupeiqi/articles/6229292.html 关于scrapy-reids组件 http ...
- 10月25日学习内容整理:数据操作:增加更新删除,单表查询操作
>>\G是按行显示,必须是大写 >>插入数据:补充另一种插入记录的方法 -->insert into 表名1(字段1,字段2,...) select 字段1,字段2,.. ...
- 11月8日学习内容整理:js的引入方式,变量数据类型,运算符,流程控制,函数...
js是一门成熟的编程语言,专门用浏览器客户端执行的语言 一.js的引入方式 1.直接在body标签中使用script标签写js语言 2.通过script标签导入js文件,<script sr ...
- 9月7日学习内容整理:内置函数
一.内置函数 1.作用域相关: (1)globals() 查看全局作用域,显示所有的变量 (2)locals() 查看局部作用域,只会显示当前函数使用的变量 2.迭代器相关: (1)it ...
- 9月13日学习内容整理:异常处理
一.异常处理 1.排错:多行报错的时候,真正报错的是最下面:若报错的地方在别人的代码里,注意别人写的代码是不会报错的,还是找自己的错 2.特点:一旦发生异常,程序不会再向下执行 3.处理方法: (1) ...
- 2月1日学习内容整理:算法
1.概念 一个计算过程,解决问题的方法 2.时间复杂度和空间复杂度 时间复杂度:用来表示算法的运行效率 >>>一般来说,时间复杂度高的算法比时间复杂度低的算法运行效率高,,但这不是绝 ...
- 11月17日学习内容整理:jquery文档处理,事件细讲,动画
一.文档处理:下面举例中的B可以是标签也可以是选择器也可以是字符串 >>>添加到指定元素内部的后面 $(A).append(B) // 把B放到A内部元素的最后,A是父节点$(A). ...
最新文章
- mysql 密码 You must reset your password using ALTER USER statement before executing this statement....
- Android九宫图(draw9patch)
- 病毒(信息学奥赛一本通-T1396)
- 工信部:老年人拨打三大运营商客服享受一键呼入等服务
- linux ls 目录结构,linux 系统目录结构 ls命令 文件类型 alias命令
- Golang简单日志类
- XP时代的结束是阵痛还是真痛
- RabbitMQ的入门程序test测试代码
- set python3_python3学习之set集合
- GPUGraphicsGame tools
- 还记得2048怎么玩吗?快来玩会儿(摸鱼)吧
- matlab触发 ttl,请问如何用TTL信号触发单反相机拍摄
- Kubuntu下root登录
- MyDiskTest硬盘检测绿色版
- “三高“Mysql - Mysql备份概览
- scrollTo方法的平滑滚动
- UNION 和 UNION ALL的区别
- 屏幕左上角出现【最小化】按钮,鼠标无法点击
- 超级电容容量及放电时间计算方法
- Microsoft Project 2010 (Beta)下载
热门文章
- 【译】使用 CocoaPods 模块化iOS应用
- SQL查询语句精华总结
- 【elasticsearch】ES扩容后报错Can not be imported as a dangling index as index with same name
- Java——类的继承
- 9.Springcloud的Hystrix服务熔断和服务降级
- 软件测试--网络协议(三)
- MySQL基础2——表的约束
- 虚拟机服务器被攻击,Linux服务器被攻击用来挖矿了
- 360浏览器没有声音_你用的浏览器好用吗?该国产电脑浏览器,极速、安全,值得使用...
- 20%3cx 30 的c语言表达式是,判断题(指令正误)