【实验目的】

1.了解Scrapy框架
2.学习使用Scrapy爬取唐诗三百首

【实验原理】

Scrapy数据流是由执行的核心引擎(engine)控制,流程是这样的:
1、爬虫引擎获得初始请求开始抓取。
2、爬虫引擎开始请求调度程序,并准备对下一次的请求进行抓取。
3、爬虫调度器返回下一个请求给爬虫引擎。
4、引擎请求发送到下载器,通过下载中间件下载网络数据。
5、一旦下载器完成页面下载,将下载结果返回给爬虫引擎。
6、引擎将下载器的响应通过中间件返回给爬虫进行处理。
7、爬虫处理响应,并通过中间件返回处理后的items,以及新的请求给引擎。
8、引擎发送处理后的items到项目管道,然后把处理结果返回给调度器,调度器计划处理下一个请求抓取。
9、重复该过程(继续步骤1),直到爬取完所有的url请求。

【实验环境】

Linux Ubuntu 16.04
Python 3.5
PyCharm

【实验内容】

1.使用Scrapy框架爬取唐诗三百首中的一首古诗
2.使用Scrapy框架爬取唐诗三百首中的全部古诗

【实验步骤】

1.打开终端模拟器,创建一个目录/data,密码:zhangyu,创建一个名为poetry的Scrapy项目。

  1. sudo mkdir /data
  1. sudo chown -R zhangyu.zhangyu /data
  1. cd /data
  2. scrapy startproject poetry

3.3 Scrapy爬取唐诗三百首 - 图1

2.打开Pycharm,选择File中的Open。

3.3 Scrapy爬取唐诗三百首 - 图2
选择/data中的poetry。
3.3 Scrapy爬取唐诗三百首 - 图3

3.在终端模拟器中,切换到poetry目录中,创建Spider。

这里我们要爬取192.168.1.100:40000/gushi中的文章。

  1. cd /data/poetry
  2. scrapy genspider poetrylist 192.168.1.100:40000/gushi

3.3 Scrapy爬取唐诗三百首 - 图4
我们可以在Pycharm中看到我们创建的poetry已经显示出来了。
3.3 Scrapy爬取唐诗三百首 - 图5

4.接下来,我们进入setting.py文件,将其中的ROBOTSTXT_OBEY参数由True改为False。

3.3 Scrapy爬取唐诗三百首 - 图6

5.选择目标网站。我们选取唐诗三百首的任意一首古诗。

3.3 Scrapy爬取唐诗三百首 - 图7
进入该文章,我们要爬取的是该古诗的名称、作者、诗句、译文。
3.3 Scrapy爬取唐诗三百首 - 图8

6.首先,我们需要创建一个main文件用于Scrapy的调试。

3.3 Scrapy爬取唐诗三百首 - 图9
3.3 Scrapy爬取唐诗三百首 - 图10
main文件的内容为:

  1. # -*- coding: utf-8 -*-
  2. from scrapy.cmdline import execute
  3. import sys
  4. import os
  5. #print(os.path.dirname(os.path.abspath(__file__)))
  6. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  7. execute(["scrapy","crawl","poetrylist"])

7.下面编辑poetrylist.py文件,定制爬取规则。我们调用response的xpath选择器,将古诗的名称、作者、诗句、译文提取出来:

  1. def parse(self, response):
  2. poetry_tag1 = response.xpath('//div[@]/div[@]/div[@]')[0]
  3. # 股市名称
  4. poetry_name = poetry_tag1.xpath('//div[@]/h1/text()').extract()[0]
  5. #古诗作者
  6. poetry_author=poetry_tag1.xpath('//div[@]/p/a/text()').extract()[0]
  7. #古诗内容
  8. poetry_neirong=poetry_tag1.xpath('//div[@]/div[@]/text()').extract()[0]
  9. #古诗译文
  10. poetry_yiwen1=response.xpath('//div[@]/p')[0]

8.完整代码为:

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. class PoetrylistSpider(scrapy.Spider):
  4. name = 'poetrylist'
  5. allowed_domains = ['192.168.1.100:40000/gushi']
  6. start_urls = ['http://192.168.1.100:40000/gushi/detail/4809b5e7a16a/']
  7. def parse(self, response):
  8. poetry_tag1 = response.xpath('//div[@]/div[@]/div[@]')[0]
  9. #古诗名称
  10. poetry_name = poetry_tag1.xpath('//div[@]/h1/text()').extract()[0]
  11. #古诗作者
  12. poetry_author=poetry_tag1.xpath('//div[@]/p/a/text()').extract()[0]
  13. #古诗内容
  14. poetry_neirong=poetry_tag1.xpath('//div[@]/div[@]/text()').extract()[0]
  15. #古诗译文
  16. poetry_yiwen1=response.xpath('//div[@]/p')[0]
  17. poetry_yiwen=poetry_yiwen1.xpath('string(.)').extract()[0].replace("译文","")
  18. print("poetry_name:", poetry_name)
  19. print("poetry_author:", poetry_author)
  20. print("poetry_neirong:", poetry_neirong)
  21. print("poetry_yiwen:", poetry_yiwen)

9.在main文件中,右键运行Run ‘main’。可以在下面输出中看到古诗的名称、作者、诗句、译文被提取出来。

3.3 Scrapy爬取唐诗三百首 - 图11
至此,我们就爬取了唐诗三百首中的一首,但是在实际需求中,我们往往需要大量爬取数据,接下来我们开始爬取唐诗三百首中的所有古诗。

10.创建一个新的Scrapy工程,名为PAll。

  1. cd /data
  2. scrapy startproject PAll

3.3 Scrapy爬取唐诗三百首 - 图12

11.创建一个spider,名为PAll。

  1. cd /data/PAll
  2. scrapy genspider pall http://192.168.1.100:40000/gushi

3.3 Scrapy爬取唐诗三百首 - 图13
在pycharm中选择File=>Open。
3.3 Scrapy爬取唐诗三百首 - 图14
3.3 Scrapy爬取唐诗三百首 - 图15
3.3 Scrapy爬取唐诗三百首 - 图16

12.选择setting.py文件,将其中的ROBOTSTXT_OBEY参数由True改为False。

3.3 Scrapy爬取唐诗三百首 - 图17

13.创建allmain文件,allmain文件内容为:

  1. # -*- coding: utf-8 -*-
  2. from scrapy.cmdline import execute
  3. import sys
  4. import os
  5. #print(os.path.dirname(os.path.abspath(__file__)))
  6. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  7. execute(["scrapy","crawl","pall"])

14.编写pall.py文件,定制爬取规则,爬取所有古诗的名称、作者、诗句、译文被提取出来。

完整代码为:

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from urllib import parse
  4. class PallSpider(scrapy.Spider):
  5. name = 'pall'
  6. start_urls = ['http://192.168.1.100:40000/gushi/']
  7. def parse(self, response):
  8. post_urls = response.css(".main3 .left .sons .typecont>span a::attr(href)").extract()
  9. for post_url in post_urls:
  10. yield scrapy.Request(url=parse.urljoin(response.url, post_url), callback=self.parse_detail)
  11. def parse_detail(self, response):
  12. poetry_tag1 = response.css('.main3 .left .sons')[0]
  13. # 古诗名称
  14. poetry_name = poetry_tag1.css('.cont h1::text').extract()[0]
  15. # 古诗作者
  16. poetry_author = poetry_tag1.css('.cont p a::text').extract()[0]
  17. # 古诗内容
  18. poetry_neirong = poetry_tag1.css('.cont .contson::text').extract()[0]
  19. # 古诗译文
  20. poetry_yiwen1 = response.css('.contyishang p::text').extract()
  21. tag_list = [element for element in poetry_yiwen1 ]
  22. tags = "".join(tag_list)
  23. print("poetry_name:", poetry_name)
  24. print("poetry_author:", poetry_author)
  25. print("poetry_neirong:", poetry_neirong)
  26. print("poetry_yiwen:", tags)

其中:
爬取工作中,我们需要爬取的第一个url网址

  1. start_urls = ["http://192.168.1.100:40000/gushi/"]

获取古诗列表页中的古诗的url并交给scrapy下载后并进行解析

  1. urlpost_urls = response.css(".main3 .left .sons .typecont>span a::attr(href)").extract()
  2. for post_url in post_urls:
  3. yield scrapy.Request(url=parse.urljoin(response.url, post_url), callback=self.parse_detail)

15.最后,我们在allmain文件下,执行Run ‘allmain’,得到如下输出结果。

3.3 Scrapy爬取唐诗三百首 - 图18
至此,我们就完成了对所有古诗的爬取工作。