爬虫工作量由小到大的思维转变---<第十五章 Scrapy小案例爬‘豆瓣‘>

前言:

随便写个小案例,大概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来启动爬虫,看看结果是否符合你的预期。

你可能感兴趣的:(15天玩转高级python,scrapy,爬虫)