本节参考链接

https://blog.csdn.net/weixin_44627151/article/details/115775239 https://www.bilibili.com/video/BV1jt411Q7PD?from=search&seid=10299534250007155058&spm_id_from=333.337.0.0

简介

写一个爬虫,需要做很多的事情。比如:发送网络请求、数据解析、数据存储、反反爬虫机制(更换p代理、设置请求头等)、异步·请求……这些知识点前面已经讲得清楚,大家会发现我们是一个一个去写每个步骤,然后我们可以用函数封装起来,但是这些工作如果每次都要自己从零开始写的话,比较浪费时间。因此Scrapy把一些基础的东西封装好了,在他上面写爬虫可以变的更加的高效(抓取效率和开发效率)因此真正在公司里,一些上了量的爬虫,都是使用scrapy框架来解决

Scrapy框架原理

image.png

  1. 引擎(Scrapy)
  2. 用来处理整个系统的数据流处理, 触发事务(框架核心)
  3. 调度器(Scheduler)
  4. 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
  5. 下载器(Downloader)
  6. 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
  7. 爬虫(Spiders)
  8. 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
  9. 项目管道(Pipeline)
  10. 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据
  11. 下载器中间件(Downloader Middlewares)
  12. 位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应
  13. 爬虫中间件(Spider Middlewares)
  14. 介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出
  15. 调度中间件(Scheduler Middewares)
  16. 介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应

基本命令

  1. 全局命令
  2. scrapy sstartproject 创建项目
  3. genspider: scrapy genspider [-t template] <name> <domain>生成爬虫,-l 查看模板; -t 指定模板,name爬虫名,domain域名(爬取网站范围)
  4. settings 查看设置
  5. runspider 运行爬虫(运行一个独立的python文件,不必创建项目)
  6. shell scrapy shell [url]进入交互式命令行,可以方便调试
  7. spider=SPIDER 忽略爬虫自动检测,强制使用指定的爬虫
  8. -c 评估代码,打印结果并退出:
  9. $ scrapy shell --nolog http://www.example.com/ -c '(response.status, response.url)'
  10. (200, 'http://www.example.com/')
  11. 1
  12. 2
  13. no-redirect 拒绝重定向
  14. nolog 不打印日志
  15. response.status 查看响应码
  16. response.url
  17. response.text; response.body 响应文本;响应二进制
  18. view(response) 打开下载到本地的页面,方便分析页面(比如非静态元素)
  19. fetch 查看爬虫是如何获取页面的,常见选项如下:
  20. spider=SPIDER 忽略爬虫自动检测,强制使用指定的爬虫
  21. headers 查看响应头信息
  22. no-redirect 拒绝重定向
  23. view 同交互式命令中的view
  24. version
  25. 项目命令
  26. crawl : scrapy crawl <spider> 指定爬虫开始爬取(确保配置文件中ROBOTSTXT_OBEY = False
  27. check: scrapy check [-l] <spider>检查语法错误
  28. list 爬虫list
  29. edit 命令行模式编辑爬虫(没啥用)
  30. parse: scrapy parse <url> [options] 爬取并用指定的回掉函数解析(可以验证我们的回调函数是否正确)
  31. callback 或者 -c 指定回调函数
  32. bench 测试爬虫性能

scrapy startproject maitian # 创建一个爬虫项目 maitian

我利用Pycharm的终端和Scrapy命令创建了项目,结果如下

image.png

创建项目后,自动生成如下文件
image.png

  1. 1. scrapy startproject 项目名称
  2. - 在当前目录中创建中创建一个项目文件(类似于Django
  3. 2. scrapy genspider [-t template] <name> <domain>
  4. - 创建爬虫应用
  5. 如:
  6. scrapy genspider -t basic oldboy oldboy.com
  7. scrapy genspider -t xmlfeed autohome autohome.com.cn
  8. PS:
  9. 查看所有命令:scrapy gensipider -l
  10. 查看模板命令:scrapy gensipider -d 模板名称
  11. 3. scrapy list
  12. - 展示爬虫应用列表
  13. 4. scrapy crawl 爬虫应用名称
  14. - 运行单独爬虫应用
  15. scrapy crawl xxx --nolog
  16. 5.scrapy shell 进入shell
  17. 复制代码

问题1 :代码运行出错解决办法

大家在运行代码一定出现这个错误

ModuleNotFoundError: No module named ‘protego‘

不要去用pycharm去安装,而要用Anaconda去安装,安装后把protego文件夹复制到你运行Python文件的库里面,当然如果你本来用的就是Anaconda就不用了 参考链接:[https://blog.csdn.net/qq_43236333/article/details/115871163](https://blog.csdn.net/qq_43236333/article/details/115871163)

问题2 :创建爬虫文件的代码

image.png

  1. name:用于区别spider。该名字必须是唯一的,不能为不同的spider设定相同的名字
  2. statr_urls:它是spider在启动时进行爬取的入口URL列表。因此,第一个被获取到的页面的URL将是其中之一,后续的
  3. URL则从初始的URL的响应中主动提取
  4. parse():它是spider的一个方法。该方法负责解析返回的数据、提取数据(生成item)以及生成需要进一步处理的URLrequest对象
  1. import scrapy
  2. class ItcastSpider(scrapy.Spider):
  3. name = 'itcast' 爬虫名称
  4. allowed_domains = ['itcast.cn'] #允许的域名
  5. start_urls = ['http://itcast.cn/']
  6. def parse(self, response):
  7. pass
  8. #处理start_urls的相应

问题3:shell进入命令交互

如:scrapy shell URL --nolog # –-nolog不打印日志

image.png

问题4:shell命令的使用

  1. >>>response.xpath('//title/text()').extract_first()
  2. 重新下载页面
  3. >>>fetch URL
  4. 修改请求参数,比如讲默认的GET方法改为POST方法,然后用fetch直接请求request
  5. >>>requset = requset.replace(method='post')
  6. >>>fetch(request)
  7. exit() 即可退出scrapy shell 终端模式
  8. 还有其他的使用命令,上图明显

.extract_first()

image.png

.extract()用法
image.png

  1. import scrapy
  2. from maitian.items import MaitianItem
  3. class WebSpider(scrapy.Spider):
  4. name = 'web'
  5. allowed_domains = ['maitian.cn']
  6. start_urls = ['http://bj.maitian.cn/zfall/PG1']
  7. def parse(self, response):
  8. for web_itme in response.xpath("/html/body/section[2]/div[2]/div[2]/ul/li[3]/div[2]"):
  9. yield {
  10. 'title': web_itme.xpath("./h1/a/text()").extrace_first().strip(),
  11. 'price': web_itme.xpath("./div/ol/strong/span/text()").extrace_first().strip(),
  12. 'area': web_itme.xpath(".p[1]/span[1]/text()").extrace_first().strip()
  13. }
  14. next_page_url=response.xpath("//[@id="paging"]/a[@class="down_page"]/@href").extract_first()
  15. if next_page_url is not None:
  16. yield scrapy.Request(response.urljoin(next_page_url))
  1. # 分组(对抓取数据,进行有必要的分组)
  2. li_list = response.xpath("/html/body/div[10]/div/div[2]/ul/li")
  3. for li in li_list:
  4. item = {}
  5. item["name"] = li.xpath("./div[2]/h2/text()").extract_first()
  6. item["title"] = li.xpath("./div[2]/h2/span/text()").extract_first()
  7. print(item)

image.png