通过上一节《Python Scrapy爬虫框架详解》的学习,您已经对 Scrapy 框架有了一个初步的认识,比如它的组件构成,配置文件,以及工作流程。本节将通过一个的简单爬虫项目对 Scrapy 框架做进一步介绍。
首先看一个简单的示例,比如把 城东书院首页的“title”抓取下来,如下所示:
- <html lang="zh-cn">
- <head>
- <meta charset="gb2312" />
- <meta name="baidu-site-verification" content="6B13HRSfYA" />
- <link rel="shortcut icon" href="/cpp/favicon.ico" />
- <title>城东书院:学习、工作、生活信息平台</title>
- ....
- </head>
在 CMD 命令行执行以下命令创建项目以及爬虫文件:
打开爬虫文件 title.py ,编写如下代码,其中一些代码 Scrapy 框架已经自动生成:
- import scrapy
- class TitleSpider(scrapy.Spider):
-
- name = 'title'
- #要抓取数据的网站域名
- allowed_domains = ['www.cdsy.xyz']
- #第一个抓取的url,初始url,被当做队列来处理
- start_urls = ['http://www.cdsy.xyz/']
-
- def parse(self,response):
-
- #.extract():提取文本内容,将列表中所有元素序列化为Unicode字符串
- #.extract_first():提取列表中第1个文本内容
- # 以下是我们自己编写的代码,而自动生成的代码不用改动
- result = response.xpath('/html/head/title/text()').extract_first()
- print('-' * 60 )
- print(result)
- print('-' * 60)
下面修改 settings 文件的配置项,如下所示:
为了省去终端敲命令的环节,您可以在项目中自定义一个运行文件 mian.py(注意:该文件与 scrapy.cfg 同目录),并编写如下代码:
- from scrapy import cmdline
- # 注意,cmdline.execute()是为了减少输入命令的操作,该方法的参数必须为列表。
- # 执行爬虫文件来启动项目
- cmdline.execute('scrapy crawl title'.split())
编写完成后,执行 main.py 文件,您会看到很多的输出内容,内容大致如下:
上述过程中,我们只在 title.py 中使用 Xpath 做了解析数据的操作,就拿到了我们想要的数据。由此可见 URL 入队出队, 发起 request 请求,返回 response 响应等操作都是由 Scrapy 框架自动完成的。
在 Scrapy 框架中,每个模块之间既紧密联系,但又相互独立,这样的设计减少了代码之间耦合度,是代码简洁易懂。
最后,我们使用 Scrapy 框架完成一个完整的案例:抓取猫眼电影 Top100 榜。
首先在 items.py 中定义要抓取的数据结构,如下所示:
- name = scrapy.Field()
- star = scrapy.Field()
- time = scrapy.Field()
接下来编写爬虫文件 maoyan.py 代码如下所示:
- import scrapy
- from Maoyan100.items import Maoyan100Item
-
- class Maoyan100Spider(scrapy.Spider):
- # name 指定爬虫文件名字
- name = 'maoyan'
- allowed_domains = ['maoyan.com'] # 网站域名
- start_urls = ['https://maoyan.com/board/4?offset=0'] # 第一个要抓取的url
- offset = 0 #查询字符串参数
-
- # response 为 start_urls中影响对象
- def parse(self,response):
- # 基准xpath,匹配电影信息的dd节点对象列表
- dd_list = response.xpath('//dl[@class="board-wrapper"]/dd')
- # 给items.py 中的类:Maoyan100Item()实例化
- item = Maoyan100Item()
- for dd in dd_list:
- item['name'] = dd.xpath('./a/@title').get().strip() # 1.6以后版本使用 原来用 extract_first()
- item['star'] = dd.xpath('.//p[@class="star"]/text()').get().strip()
- item['time'] = dd.xpath('.//p[@class="releasetime"]/text()').get().strip()
- yield item
- if self.offset < 90: # 判断条件
- self.offset += 10
- url = 'https://maoyan.com/board/4?offset=' + str(self.offset)
- # 把url交给secheduer入队列
- # response会自动传给 callback 回调的 parse()函数
- #Scrapy.request()向url发起请求,并将响应结果交给回调的解析函数
- yield scrapy.Request(url=url, callback=self.parse)
通过编写管道文件 pipelinse.py 文件实现数据的存储,将抓取的数据存放在 MySQL 数据库,这里需要提前建库、建表,因为前面章节已经创建过,此处不再赘述。代码编写如下:
- import pymysql
- from Maoyan100.settings import *
-
- class Maoyan100Pipeline(object):
- def process_item(self, item, spider):
- print(item['name'], item['star'], item['time'])
- return item # 多个管道有体现
-
-
- # 存入mysql数据库的管道
- class Maoyan100MysqlPipeline(object):
- #开始
- def open_spider(self, spider):
- # 爬虫项目启动,执行连接数据操作
- # 以下常量需要定义在settings配置文件中
- self.db = pymysql.connect(
- host=MYSQL_HOST,
- user=MYSQL_USER,
- password=MYSQL_PWD,
- database=MYSQL_DB,
- charset=MYSQL_CHARSET
- )
- self.cursor = self.db.cursor()
- # 向表中插入数据
- def process_item(self, item, spider):
- ins = 'insert into movieinfo values(%s,%s,%s)'
- L = [
- item['name'], item['star'], item['time']
- ]
- self.cursor.execute(ins, L)
- self.db.commit()
- return item
- # 结束存放数据,在项目最后一步执行
- def close_spider(self, spider):
- # close_spider()函数只在所有数据抓取完毕后执行一次,
- self.cursor.close()
- self.db.close()
- print('执行了close_spider方法,项目已经关闭')
下面定义项目启动文件 run.py, 代码如下:
- from scrapy import cmdline
- #执行爬虫文件 -o 指定输出文件的格式
- cmdline.execute('scrapy crawl maoyan -o maoyan.csv'.split()) #执行项目,并且将数据存csv文件格式
注意:指定 -o 参数,可以将数据以特定的文件格式保存,比如 csv、txt、josn 等。
最后修改配置文件,主要有修改以下内容:添加日志输出、激活管道 pipelines、定义数据库常量,以及其他一些常用选项,如下所示:
}
#在配置文件末尾添加mysql常用变量
MYSQL_HOST='localhost'
MYSQL_USER='root'
MYSQL_PWD='123456'
MYSQL_DB='maoyandb'
MYSQL_CHARSET='utf8'
最后执行 run.py 文件,日志文件 maoyan.log 内容大致如下:
{'name': '我不是药神', 'star': '主演:徐峥,周一围,王传君', 'time': '上映时间:2018-07-05'}
2021-04-09 19:38:13 [scrapy.core.scraper] DEBUG: Scraped from <200 https://maoyan.com/board/4?offset=0>
{'name': '肖申克的救赎',
'star': '主演:蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿',
...
maoyan.csv 文件大致如下: