思路:
1、豆瓣电影TOP250 url=https://movie.douban.com/top250
2、使用crawlspider获取250个电影详情页url
3、使用xpath解析数据:获取电影标题、导演、演员、简介、热门第一评论、评论人数等详细信息
4、保存250部电影海报图片
一、准备工作
创建一个scrapy project:
scrapy startproject DBMOVIE
创建spider file
scrapy genspider -t crawl douban douban.com
二、构建框架
(1)items.py / 定义item
import scrapy
class DbmovieItem(scrapy.Item):
Rank = scrapy.Field()
Title =scrapy.Field()
Attr =scrapy.Field()
Actor =scrapy.Field()
Type_ = scrapy.Field()
Rating_num =scrapy.Field()
Time_ =scrapy.Field()
Short =scrapy.Field()
Image_url = scrapy.Field()
Hot_comment = scrapy.Field()
(2) spider.py
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
import time
from DBMOVIE.items import DbmovieItem
class DoubanSpider(CrawlSpider):
name = 'douban'
allowed_domains = ['douban.com']
#豆瓣电影top250共有10页,将每页的url都加入start_url列表中
base_urls = 'https://movie.douban.com/top250?start={}&filter='
start_urls =[]
#设置index用来查看爬取进度,可不要
index = 0
for i in range(10):
url = base_urls.format(i*25)
start_urls.append(url)
#设置crawl爬取规则,获取每页中的25个详情页url
#CrawlSpider框架获取url有去重功能
rules = (
Rule(LinkExtractor(allow='subject/'), callback='parse_item', follow=False),
)
def parse_item(self, response):
self.index +=1
#导入item
item = DbmovieItem()
#获取排名,得到的数据顺序是随机的,后续可以使用排名重新排序
item['Rank'] = response.xpath('//*[@id="content"]/div[1]/span[1]/text()').extract_first()[3:]
#电影名称
item['Title'] = response.xpath('//*[@id="content"]/h1/span[1]/text()').extract_first()
#导演
item['Attr'] = response.xpath('//*[@id="info"]/span[1]/span[2]/a/text()').extract_first()
#演员,演员有多个,在多个同级标签中,使用join将获取到的列表中多个导演名字连成一个完整字符串
item['Actor'] = ','.join(response.xpath('//*[@id="info"]/span[@class="actor"]/span[2]/a/text()').extract())
#电影类别
item['Type_'] = ','.join(response.xpath('//*[@id="info"]/span[@property="v:genre"]/text()').extract())
#电影评论人数
item['Rating_num'] = response.xpath('//*[@id="interest_sectl"]//a[@class="rating_people"]/span/text()').extract_first()
#上映时间
item['Time_'] = ','.join(response.xpath('//*[@id="info"]/span[@property="v:initialReleaseDate"]/text()').extract())
#简介
item['Short'] = (((''.join(response.xpath('//*[@id="link-report"]//span[1]/text()').extract())).replace('\n','')).strip()).replace(' ','')
#图片url,后面用来下载图片
item['Image_url'] = response.xpath('//*[@id="mainpic"]/a/img/@src').extract_first()
#热评第一个
item['Hot_comment'] = (response.xpath('//*[@id="hot-comments"]/div[1]/div/p/span/text()').extract_first().strip()).replace('\t','')
print('获取到第%d个' % self.index)
print(item['Rank'],item['Title'])
yield item
(3) middlewares.py
#在项目下创建了一个user_agent.py文件保存了user_agents池
#使用scrapy的UserAgentMiddleware模块获取user_agent
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
from DBMOVIE.user_agent import user_agents
import random
class RotateUserAgentMiddleware(UserAgentMiddleware):
def process_request(self, request, spider):
#随机选取一个user_agent,传入请求头
user_agent = random.choice(user_agents)
if user_agent:
print('**********user ug:%s***********' % user_agent)
request.headers['User-Agent'] = user_agent
return None
(4)pipelines.py
from scrapy.exporters import CsvItemExporter
import DBMOVIE.settings as setting
import urllib.request
import os
import pymongo
#将获取的数据保存到MongoDB数据库中
class DbmoviePipeline(object):
def open_spider(self,spider):
#连接服务器,使用默认地址端口
self.client = pymongo.MongoClient()
#创建/选择数据库
self.mydb = self.client['test']
#创建/选择表
self.collection = self.mydb['dbmovie']
def process_item(self, item, spider):
#插入数据
self.collection.insert(dict(item))
return item
#重写一个保存图片的管道
class DbmovieImgPipline(object):
def process_item(self,item,spider):
#设置保存图片的文件夹地址
dir_path = '%s/%s' % (setting.IMAGES_STORE,spider.name)
#若不存在则创建它
if not os.path.exists(dir_path):
os.makedirs(dir_path)
#获取图片url
img_url = item['Image_url']
#创建图片名称
file_name = item['Rank'] + item['Title'] + '.jpg'
#拼接文件夹地址和图片名称创建文件保存路径
file_path = '%s/%s' % (dir_path,file_name)
#去重
if os.path.exists(file_path):
print('重复,跳过',+img_url)
#保存图片
with open(file_path,'wb') as f:
print('正在下载图片',img_url)
#使用图片url发生请求获取到图片,保存到对应的路径中
conn = urllib.request.urlopen(img_url)
f.write(conn.read())
f.close()
return item
5)设置setting
一般写好一部分代码就开启相应的设置,以防忘记
BOT_NAME = 'DBMOVIE'
SPIDER_MODULES = ['DBMOVIE.spiders']
NEWSPIDER_MODULE = 'DBMOVIE.spiders'
LOG_FILE = 'douban.log'
LOG_LEVEL = 'WARNING'
#保存图片的文件地址
IMAGES_STORE = './img'
#不遵守robort协议
ROBOTSTXT_OBEY = False
#下载延迟
DOWNLOAD_DELAY = 3
#打开设置user_agent的下载中间件
DOWNLOADER_MIDDLEWARES = {
'DBMOVIE.middlewares.RotateUserAgentMiddleware': 543,
}
#打开保存数据和图片的管道
ITEM_PIPELINES = {
'DBMOVIE.pipelines.DbmoviePipeline': 300,
'DBMOVIE.pipelines.DbmovieImgPipline':350,
}
三、运行spider
(1)打开MongoDB服务器,启动客户端
sudo mongod
mongo
(2)运行spider
scrapy crawl maitian
四、完成以上几步即可以查看数据啦
如果需要可以对MongoDB中的数据CSV可视化处理