本文共 5075 字,大约阅读时间需要 16 分钟。
官网:
流程图如下:
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)# Linux平台pip3 install scrapy
# 查看帮助scrapy -hscrapy-hGlobal commands: # 全局命令 startproject # 创建项目,会在当前目录下创建项目文件夹 genspider # cd 进入项目目录,创建爬虫程序 scrapy genspider baidu_spider www.baidu.com # 就会在spider目录下生成 baidu_spider.py 文件 settings # 如果是在项目目录下,则得到的是该项目的配置 > scrapy settings --get=SPIDER_MODULES ['first_crawl.spiders'] runspider # 运行一个独立的python文件,不必创建项目 ROBOTSTXT_OBEY = False scrapy runspider baidu_spider.py的绝对路径 shell # scrapy shell url地址 在交互式调试,如选择器规则正确与否 scrapy shell https://www.baidu.com/ # 进入交互环境后,可执行命令: response.text # 文本内容 response.body # 二进制内容 view(response) # 打开浏览器查看响应页面,已下载到本地 response.css('a') # 查找所有a标签 response.xpath('//a') # 查找所有a标签 quit() # 退出交互环境 fetch # 独立于程单纯地爬取一个页面,可以拿到请求头 scrapy fetch https://www.baidu.com/ # 直接获取所有信息,类似shell但没有交互调试 view # 下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求 version # scrapy version 查看scrapy的版本 scrapy version # -v查看scrapy依赖库的版本Project-only commands: # 必须切到项目文件夹下才能执行 crawl # 运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY=False scrapy crawl baidu_spider # 此处爬虫名称为name属性对应的爬虫 check # 检测项目中有无语法错误 list # 列出项目中所包含的爬虫名 parse # scrapy parse url地址 --callback 回调函数,以此可以验证我们的回调函数是否正确 bench # scrapy bentch压力测试,检测每分钟能爬取的网页数# 官网链接 https://docs.scrapy.org/en/latest/topics/commands.html
project_name/ scrapy.cfg project_name/ __init__.py items.py pipelines.py settings.py spiders/ __init__.py 爬虫1.py 爬虫2.py 爬虫3.py
测试网址:
目标页面内容:Example website
进入交互环境测试选择器使用:
scrapy shell https://doc.scrapy.org/en/latest/_static/selectors-sample1.html# 进入交互环境# response.selector.css()或.xpath返回的是selector对象,再调用extract()和extract_first()从selector对象中解析出内容。
/
仅限于子标签:
# 查找目标页面所有a标签下的img子标签>>> response.xpath('//a/img').extract()['', '', '', '', ''] >>> response.css('a img').extract() # 返回对象列表>>> response.css('a img').extract_first() # 返回第一个标签对象''
//
在子孙标签中查找:
# 查找目标页面所有的div标签内容的所有img标签>>> response.xpath('//div//img').extract()['', '', '', '', '']
>>> response.css('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()['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 ']
# xpath获取a标签内的所有img的src属性>>> response.xpath('//a//img/@src').extract()['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']## css获取属性>>> response.css('img::attr(src)').extract()['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']
>>> response.xpath('//div').css('a').xpath('@href').extract_first()'image1.html'
>>> response.xpath("//div[@id='asas']").extract_first(default='not found')'not found'
# 查找所有包含[href='image2.html']的标签>>> response.xpath("//*[@href='image2.html']").extract_first()'Name: My image 2 '>>> response.css('#images [href="image2.html"]').extract_first()'Name: My image 2 '
>>> response.css('#images [href*="image2"]').extract_first()'Name: My image 2 '>>> response.xpath('//a[contains(@href,"image1")]').extract_first()'Name: My image 1 '>>> response.xpath('//*[contains(@href,"image1")]').extract_first()'Name: My image 1 '
# 先找到所有a标签的文本selecor对象,然后逐个用re进行匹配,直到找到匹配的>>> response.xpath('//a').re(".*My image 1 ")[0]'Name: My image 1 '
转载地址:http://buksi.baihongyu.com/