文章目录
帮一个大一的小朋友做作业,看了一下Scrapy,这里也记录一下吧,有需要的可以参考一下。
1. 项目简介
Scrapy爬取豆瓣电影top250的代码网上有很多,之前没用过这个框架,也懒得细看了,这里借鉴了Scrapy实战 这篇文章的爬取方式。爬取的部分就不细说了,大家可以直接看代码,博客上也有很多讲解的,这里主要分享一下爬取到的数据如何存储。
先展示一下我的目录结构,files和picture文件夹备用来放置爬取的数据保存文件和图片,其他文件是新建Scrapy项目后自动生成的。
; 2. 代码解析
main.py文件是自建的,用来作为项目执行文件,可以在pycharm中直接运行,代码如下:
#!/usr/bin/env python
-*- encoding: utf-8 -*-
"""
@File : main
@Author : GrowingSnake
@Version : 1.0
@Desciption :
@Modify Time : 2021/6/8 17:22
"""
from scrapy.cmdline import execute
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
execute(['scrapy', 'crawl', 'moviespider'])
Scrapy给出的将数据保存为json文件和csv文件的方式
execute(['scrapy', 'crawl', 'moviespider', '-o', 'moviespider.json'])
execute(['scrapy', 'crawl', 'moviespider', '-o', 'moviespider.csv'])
其实,Scrapy给出了将数据保存为json文件和csv文件的方式,大家可以执行main文件中注释掉的的命令即可,但是这种方式不够灵活,仅作为最简单的保存方式,下面还会介绍其他方式。
items.py中包含了想要爬取的电影相关数据
-*- coding: utf-8 -*-
Define here the models for your scraped items
#
See documentation in:
https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class DoubanmovieItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 设置需要采集的项
# 电影排行
rank = scrapy.Field()
# 电影名称
title = scrapy.Field()
# 导演
director = scrapy.Field()
# 评分
score = scrapy.Field()
# 介绍
introduction = scrapy.Field()
# 电影海报图及地址
picture = scrapy.Field()
pass
moviespider.py包含了具体的xpath爬取规则,并且在爬取到电影海报图片地址后,这里我自己使用urllib库的request请求下载了电影海报,保存到picture文件夹下
-*- coding: utf-8 -*-
from urllib import request
import scrapy
from items import DoubanmovieItem
class BookspiderSpider(scrapy.Spider):
name = 'moviespider'
allowed_domains = ['douban.com']
start_urls = ['https://movie.douban.com/top250']
def parse(self, response):
# 获取xpath过滤起始位置
movie_item = response.xpath('//div[@class="item"]')
# 遍历起始位置选择器解析数据
for item in movie_item:
# 创建实体对象
movie = DoubanmovieItem()
# 获取电影排行
movie['rank'] = item.xpath('div[@class="pic"]/em/text()').extract()
# 获取电影名称
movie['title'] = item.xpath('div[@class="info"]/div[@class="hd"]/a/span[1]/text()').extract()
# 获取电影导演
movie['director'] = item.xpath('div[@class="info"]/div[@class="bd"]/p/text()').extract()
# 获取电影评分
movie['score'] = item.xpath(
'div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[2]/text()').extract()
# 获取电影介绍
movie['introduction'] = item.xpath('div[@class="info"]/div[@class="bd"]/p[2]/span/text()').extract()
# 获取电影海报图及地址
movie['picture'] = item.xpath('div[@class="pic"]/a/img/@src').extract()
# 保存图片到本地
try:
if movie['picture']:
# 创建新的Request对象,将url传入
req_img = request.Request(url=movie['picture'][0])
img_data = request.urlopen(req_img)
img_name = str(movie['title'][0]) + '.jpg'# 保存图片
with open('./picture/'+img_name, 'wb') as f:
f.write(img_data.read())
except Exception:
print('获取图片失败')
# 加入生成器
yield movie
next_page = response.css('span.next a::attr(href)').extract_first()
if next_page is not None:
yield response.follow(next_page, self.parse)
pipelines.py
这里我构建了3个Pipline,分别用于将爬取到的数据存储到mysql数据库,以及保存为json文件和csv文件
-*- coding: utf-8 -*-
Define your item pipelines here
#
Don't forget to add your pipeline to the ITEM_PIPELINES setting
See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import pymysql
from scrapy.exporters import JsonItemExporter, CsvItemExporter, JsonLinesItemExporter
class DoubanmoviePipeline(object):
"""
数据库pipline
"""
def __init__(self):
# 连接MySQL数据库
self.connect = pymysql.connect(host='localhost', user='数据库用户名', password='密码', db='数据库名', port=3306)
self.cursor = self.connect.cursor()
def process_item(self, item, spider):
print('电影排行:', item['rank'][0])
print('电影名称:', item['title'][0])
print(item['director'][0].strip().split('\xa0\xa0\xa0主演: ')[0])
print('评分:', item['score'][0])
if len(item['introduction']) > 0:
introduction = item['introduction'][0]
print('介绍:', item['introduction'][0])
else:
introduction = 0
print('电影海报图及地址:', item['picture'][0])
self.cursor.execute(
'insert into doubanmovie(id,name,director,score,introduction,picture) '
'VALUES ("{}","{}","{}","{}","{}","{}")'
.format(item['rank'][0], item['title'][0].strip(),
item['director'][0].strip().split('\xa0\xa0\xa0主演: ')[0], item['score'][0],
introduction, item['picture'][0]))
self.connect.commit()
return item
def close_spider(self, spider):
self.cursor.close()
# 关闭游标
self.connect.close()
class JsonPipeline(object):
"""
json存储pipline
"""
def __init__(self):
self.file = open('./files/movie.json', 'wb')
# self.exporter = JsonLinesItemExporter(self.file, encoding="utf-8", ensure_ascii=False)
self.exporter = JsonItemExporter(self.file, encoding="utf-8", ensure_ascii=False)
self.exporter.start_exporting()
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
def close_spider(self, spider):
self.exporter.finish_exporting()
self.file.close()
class CsvPipeline(object):
"""
csv存储pipline
"""
def __init__(self):
self.file = open('./files/booksdata.csv', 'wb')
self.exporter = CsvItemExporter(self.file, encoding='utf-8-sig')
self.exporter.start_exporting()
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
def close_spider(self, spider):
self.exporter.finish_exporting()
self.file.close()
注意:在构建好Pipline后,要注意在settings.py中配置自定义的Pipline
ITEM_PIPELINES = {
'doubanmovie.pipelines.DoubanmoviePipeline': 300,
'doubanmovie.pipelines.JsonPipeline': 200,
'doubanmovie.pipelines.CsvPipeline': 100
}
3. 总结
之前也没用过Scrapy,但是现在的框架都太完善了,一些基础问题都能很简便地通过框架实现,真的是方便。本来也是帮大一学生做的作业,就想跟新人们说一下,不要害怕代码,没有那么难搞,多动手多看,入门了就会好起来的。
Original: https://blog.csdn.net/nc514819873/article/details/117918051
Author: Growing_Snake
Title: Scrapy爬取豆瓣电影top250数据并保存mysql/json/csv
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/788778/
转载文章受原作者版权保护。转载请注明原作者出处!