前言:
随便写个小案例,大概20分钟吧. 很快的...就是练手,随便练!
正文:
去爬豆瓣电影的信息,并对item进行去重和评分转换,然后将item保存到MySQL数据库中。³
首先,你需要在items.py中定义你要爬取的数据结构
# 导入scrapy模块
import scrapy
# 定义item类
class DoubanMovieItem(scrapy.Item):
# 电影名
name = scrapy.Field()
# 电影评分
score = scrapy.Field()
# 电影简介
intro = scrapy.Field()
然后,你需要在spiders目录下编写你的spider类,用来从网页中提取item
# 导入scrapy模块
import scrapy
# 导入item类
from douban_movie.items import DoubanMovieItem
# 定义spider类
class DoubanSpider(scrapy.Spider):
# 爬虫名
name = 'douban'
# 允许的域名
allowed_domains = ['movie.douban.com']
# 起始URL
start_urls = ['https://movie.douban.com/top250']
# 解析响应
def parse(self, response):
# 获取电影列表
movies = response.xpath('//div[@class="item"]')
# 遍历每部电影
for movie in movies:
# 创建item对象
item = DoubanMovieItem()
# 提取电影名
item['name'] = movie.xpath('.//span[@class="title"][1]/text()').get()
# 提取电影评分
item['score'] = movie.xpath('.//span[@class="rating_num"]/text()').get()
# 提取电影简介
item['intro'] = movie.xpath('.//p[2]/span/text()').get()
# 返回item
yield item
# 获取下一页的链接
next_url = response.xpath('//span[@class="next"]/a/@href')
# 如果有下一页
if next_url:
# 拼接完整的URL
next_url = response.urljoin(next_url.get())
# 生成新的请求
yield scrapy.Request(next_url, callback=self.parse)
接下来,你需要在pipelines.py中编写你的pipeline类,用来对item进行处理和保存
# 导入scrapy模块
import scrapy
# 导入item类
from douban_movie.items import DoubanMovieItem
# 导入MySQLdb模块
import MySQLdb
# 定义去重的pipeline类
class DuplicatesPipeline(object):
# 初始化方法
def __init__(self):
# 创建一个集合,用来存储已经爬取过的电影名
self.names_seen = set()
# 处理item的方法
def process_item(self, item, spider):
# 如果电影名已经在集合中
if item['name'] in self.names_seen:
# 抛出DropItem异常,丢弃该item
raise scrapy.exceptions.DropItem("Duplicate item found: %s" % item)
# 否则
else:
# 将电影名添加到集合中
self.names_seen.add(item['name'])
# 返回item
return item
# 定义评分转换的pipeline类
class ScorePipeline(object):
# 处理item的方法
def process_item(self, item, spider):
# 将评分转换为浮点数
item['score'] = float(item['score'])
# 返回item
return item
# 定义MySQL存储的pipeline类
class MySQLPipeline(object):
# 初始化方法
def __init__(self, host, user, password, database):
# 保存数据库配置
self.host = host
self.user = user
self.password = password
self.database = database
# 类方法,用来创建pipeline对象
@classmethod
def from_crawler(cls, crawler):
# 从settings中获取数据库配置
return cls(
host=crawler.settings.get('MYSQL_HOST'),
user=crawler.settings.get('MYSQL_USER'),
password=crawler.settings.get('MYSQL_PASSWORD'),
database=crawler.settings.get('MYSQL_DATABASE')
)
# 在爬虫开启时,创建数据库连接和游标
def open_spider(self, spider):
# 创建数据库连接
self.conn = MySQLdb.connect(self.host, self.user, self.password, self.database, charset='utf8')
# 创建游标
self.cursor = self.conn.cursor()
# 在爬虫关闭时,关闭数据库连接和游标
def close_spider(self, spider):
# 关闭游标
self.cursor.close()
# 关闭数据库连接
self.conn.close()
# 处理item的方法
def process_item(self, item, spider):
# 定义插入数据的SQL语句
sql = "insert into douban_movie(name, score, intro) values(%s, %s, %s)"
# 执行SQL语句
self.cursor.execute(sql, (item['name'], item['score'], item['intro']))
# 提交事务
self.conn.commit()
# 返回item
return item
最后,你需要在settings.py中配置你的pipelines
# 开启pipelines
ITEM_PIPELINES = {
'douban_movie.pipelines.DuplicatesPipeline': 100,
'douban_movie.pipelines.ScorePipeline': 200,
'douban_movie.pipelines.MySQLPipeline': 300,
}
# 配置MySQL数据库
MYSQL_HOST = 'localhost'
MYSQL_USER = 'root'
MYSQL_PASSWORD = '123456'
MYSQL_DATABASE = 'scrapy_db'
这样,你就完成了一个使用pipelines的scrapy爬虫项目。你可以运行scrapy crawl douban来启动爬虫,看看结果是否符合你的预期。