1. 任务分析及说明

目标网站:https://movie.douban.com/tag/#/

抓取豆瓣电影上,中国大陆地区,相关电影数据约1000条;数据包括:电影名称、导演、主演、评分、电影类型、语言、上映时间、短评top20等数据;

1.1 Fiddler抓包要点分析:

请求均为GET请求;拼接后的URL为是https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=电影&start=0

其中,range表示评分区间(0,10表示筛选评分在0-10之间的电影);

tags表示分类类别(电影?剧集?);

第一次请求默认返回20部电影相关信息,start=0;点击加载更多start=20,即每次点击一次加载更多,start增加20;

返回数据为json格式,数据包括电影名称、导演、电影详情的URL等信息;

从json数据中提取电影详情页的URL,访问并抓取详情信息;

抓取电影短评时,只抓取了最前面的20条,并利用//拼接成一个字符串,数据保存为excel形式。

2. 代码逻辑

2.1  项目创建

利用scrapy的基本命令创建项目、爬虫等,在此不细说,直接上命令。

scrapy startproject DoubanMovie  # 创建项目

cd DoubanMovie  # 进入项目目录

scrapy genspider douban douban.movie.com  # 创建爬虫

2.2 明确抓取字段

scrapy爬虫的套路都相似,创建项目后首先明确爬取字段;其次,编写爬虫逻辑;然后,编写数据保存逻辑;最后,做一些修修补补的工作,例如添加请求头啊,注册通道呀等等。

来到items.py文件中,明确要抓取的字段。

# -*- coding: utf-8 -*-
import scrapy class DoubanmoviesItem(scrapy.Item): # 电影名称
filmtitle = scrapy.Field()
# 电影评分
moviemark = scrapy.Field()
# 导演名称
moviedirt = scrapy.Field()
# 电影主演
movierole = scrapy.Field()
# 电影类型
movietype = scrapy.Field()
# 制片地区
moviearea = scrapy.Field()
# 语言类型
movielang = scrapy.Field()
# 上映时间
moviedate = scrapy.Field()
# 剧情简介
moviesyno = scrapy.Field()
# 电影短评
moviecoms = scrapy.Field()
# # 电影影评
# movierews = scrapy.Field()

2.3 爬虫逻辑

明确抓取字段后,开始到spiders文件夹下的douban.py中编写爬虫逻辑。豆瓣电影返回的数据为json格式,对json格式的数据进行解析,从中提取到电影详情页的url,访问并从中提取详细信息。

# -*- coding: utf-8 -*-
import re
import json
import scrapy from DoubanMovies.items import DoubanmoviesItem class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com']
# start_urls = ['http://movie.douban.com/'] start = 0 # 指定参数
formdata = {
'sort': 'U',
'range': '0, 10',
'tags': '电影',
'start': '',
'countries': '中国大陆' # 这里只抓取中国大陆地区,其他地区可做相应修改
} base_url = 'https://movie.douban.com/j/new_search_subjects' def start_requests(self): # 构造初始请求url
url = self.base_url + '?' + 'sort={}&range={}&tags={}&start={}&countries={}'.format(
self.formdata['sort'], self.formdata['range'], self.formdata['tags'],
self.formdata['start'], self.formdata['countries']
) # 发起请求
yield scrapy.Request(
url=url,
callback=self.parse,
meta={'formdata': self.formdata}
) def parse(self, response):
"""
豆瓣默认返回json格式的数据
:param response:
:return:
"""
formdata = response.meta['formdata'] # 将json格式的数据转化为字典
data_list = json.loads(response.body.decode())['data'] # 数据解析
for data in data_list: # 从json数据中解析基本信息
item = DoubanmoviesItem()
item['filmtitle'] = data['title']
item['moviemark'] = data['rate']
item['moviedirt'] = ' '.join(data['directors'])
item['movierole'] = ' '.join(data['casts']) # 拿到详情页链接,获取影评等信息
detail_url = data['url']
yield scrapy.Request(
url=detail_url,
callback=self.parse_detail,
meta={'item': item, 'formdata': formdata} # 传入item到parse_detail,继续解析数据
) if not self.start == 1000: # 抓取1020条数据
self.start += 20
formdata = self.formdata
formdata['start'] = str(self.start) url = self.base_url + '?' + 'sort={}&range={}&tags={}&start={}&countries={}'.format(
formdata['sort'], formdata['range'], formdata['tags'],
formdata['start'], formdata['countries']) yield scrapy.Request(
url=url,
callback=self.parse,
meta={'formdata': formdata}
) def parse_detail(self, response):
"""
从详情页解析其他信息
:param response:
:return:
"""
formdata = response.meta['formdata']
item = response.meta['item'] item['movietype'] = '/'.join(response.xpath("//div[@id='info']/span[@property='v:genre']/text()").extract())
item['moviearea'] = formdata['countries']
item['movielang'] = ''.join(re.findall('<span class="pl">语言:</span>(.*?)<br/>', response.body.decode()))
item['moviedate'] = '/'.join(response.xpath("//div[@id='info']/span[@property='v:initialReleaseDate']/text()").extract())
item['moviesyno'] = response.xpath("//div[@id='link-report']/span[1]/text()").extract_first().strip() # 新页面解析电影短评
coms_url = response.xpath("//div[@id='comments-section']/div[1]/h2/span/a/@href").extract_first()
yield scrapy.Request(
url=coms_url,
callback=self.parse_coms, # 在parse_coms中提取电影短评,这里只提取前20
meta={'item': item}
) def parse_coms(self, response):
"""
解析电影短评top20,将20条短评以//拼接成一个字符串
:param response:
:return:
"""
item = response.meta['item'] # 提取短评top20
coms_list = response.xpath("//div[@id='comments']/div[@class='comment-item']/div[@class='comment']/p/span/text()").extract()
item['moviecoms'] = '//'.join(coms_list) yield item

2.4 数据保存

编写完爬虫逻辑后,来到pipelines.py文件中编写保存数据逻辑。这里将数据保存为excel格式。

# -*- coding: utf-8 -*-
from openpyxl import Workbook class DoubanmoviesPipeline(object): def __init__(self): # 创建excel表格保存数据
self.workbook = Workbook()
self.booksheet = self.workbook.active
self.booksheet.append(['电影名称', '评分', '导演',
'主演', '电影类型', '制片地区',
'语言类型', '上映时间', '剧情简介',
'短评(top20)']) def process_item(self, item, spider): DATA = [
item['filmtitle'], item['moviemark'], item['moviedirt'],
item['movierole'], item['movietype'], item['moviearea'],
item['movielang'], item['moviedate'], item['moviesyno'],
item['moviecoms']]
self.booksheet.append(DATA)
self.workbook.save('./results.xls') return item

2.5 其他

1. 通道注册,包括下载中间件,pipelines等的注册,还有不遵循爬虫协议

2. 延时处理,在settings.py文件中添加

DOWNLOAD_DELAY = 5  # 每个请求延迟5秒

3. 添加请求头

在下载中间件(middlewares.py)中给每个请求添加请求头

# -*- coding: utf-8 -*-
from DoubanMovies.settings import USER_AGENTS as ua
import random class DoubanmoviesDownloaderMiddleware(object): def process_request(self, request, spider):
"""
给每一个请求随机分配一个代理
:param request:
:param spider:
:return:
"""
user_agent = random.choice(ua)
request.headers['User-Agent'] = user_agent

4. 将运行命令写在main.py文件中

from scrapy import cmdline

cmdline.execute('scrapy crawl douban'.split())

3. 完整代码

参见:https://github.com/zInPython/DoubanMovie

scrapy抓取豆瓣电影相关数据的更多相关文章

  1. Python小爬虫——抓取豆瓣电影Top250数据

    python抓取豆瓣电影Top250数据 1.豆瓣地址:https://movie.douban.com/top250?start=25&filter= 2.主要流程是抓取该网址下的Top25 ...

  2. python2.7抓取豆瓣电影top250

    利用python2.7抓取豆瓣电影top250 1.任务说明 抓取top100电影名称 依次打印输出 2.网页解析 要进行网络爬虫,利用工具(如浏览器)查看网页HTML文件的相关内容是很有必要,我使用 ...

  3. Python爬虫----抓取豆瓣电影Top250

    有了上次利用python爬虫抓取糗事百科的经验,这次自己动手写了个爬虫抓取豆瓣电影Top250的简要信息. 1.观察url 首先观察一下网址的结构 http://movie.douban.com/to ...

  4. 用python+selenium抓取豆瓣电影中的正在热映前12部电影并按评分排序

    抓取豆瓣电影(http://movie.douban.com/nowplaying/chengdu/)中的正在热映前12部电影,并按照评分排序,保存至txt文件 #coding=utf-8 from ...

  5. scrapy爬取豆瓣电影top250

    # -*- coding: utf-8 -*- # scrapy爬取豆瓣电影top250 import scrapy from douban.items import DoubanItem class ...

  6. Python:python抓取豆瓣电影top250

    一直对爬虫感兴趣,学了python后正好看到某篇关于爬取的文章,就心血来潮实战一把吧. 实现目标:抓取豆瓣电影top250,并输出到文件中 1.找到对应的url:https://movie.douba ...

  7. Python3 抓取豆瓣电影Top250

    利用 requests 抓取豆瓣电影 Top 250: import re import requests def main(url): global num headers = {"Use ...

  8. Python抓取豆瓣电影top250!

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:404notfound  一直对爬虫感兴趣,学了python后正好看到 ...

  9. python爬取豆瓣电影信息数据

    题外话+ 大家好啊,最近自己在做一个属于自己的博客网站(准备辞职回家养老了,明年再战)在家里 琐事也很多, 加上自己 一回到家就懒了(主要是家里冷啊! 广东十几度,老家几度,躲在被窝瑟瑟发抖,) 由于 ...

随机推荐

  1. oc基本控件

    (一)添加UIWindow UIWindow *window1=[[UIWindow alloc] init]; //window.frame=CGRectMake(10, 470, 100, 30) ...

  2. split分割文件与数据

    split主要用途:在之前计算机发展的时候,我们必须分割文件,才能将大量数据放入多张软盘中,而今我们分割文件有了其他的目的,比如提高可读性,生成日志以及发送有大小限制的E-mail附件. 工作原理:s ...

  3. accesskey附上一些实例

    HTML accesskey属性与web自定义键盘快捷访问 本文地址:http://www.zhangxinxu.com/wordpress/?p=6142 可能很多小伙伴都不知道,我们只要在HTML ...

  4. 这一次,彻底理解Promise源码思想

    关于Promise的源码实现,网上有太多答案,我也看过很多资料,但都不是很明白.直到有一天我学完函数式编程之函子的概念,才对Promise源码有了更深刻的认识.今天,就让我们来重新认识一下Promis ...

  5. 等距结点下的Newton插值多项式系数计算(向前差分)

    插值多项式的牛顿法 1.为何需要牛顿法? ​ 使用Lagrange插值法不具备继承性.当求好经过\(({x_0},{y_0})-({x_n},{y_n})\)共n+1个点的插值曲线时候,如果再增加一个 ...

  6. 【建站02】WordPress主题设置

    大家好,我是帝哥.相信很多朋友看了我上一篇文章的介绍之后已经可以搭建自己的个人网站了,但是网站的功能和美观程度都还是有所欠缺的,现在呢,再给大家大概的介绍一些如何美化自己的网站,当然了,这个过程也是很 ...

  7. Ubuntu13.10编译android源码中遇到的问题

    1. jdk的版本不对 我开始安装的是最新的jdk7,但是编译时会出现jdk的版本

  8. Asp.Net终于可以在龙芯服务器上运行啦:Jexus成功完成对国产系列CPU的适配

    为了确保我国信息化建设“安全可靠”,使用国产关键系统.关键应用.关键软硬件替代国外信息技术产品,已经在党政部门.国营企事业单位得到了进一步落实.过去运行于 Windows 服务器的 Web 应用程序, ...

  9. 『题解』洛谷P2357 守墓人

    Portal Portal1: Luogu Description 在一个荒凉的墓地上有一个令人尊敬的守墓人,他看守的墓地从来没有被盗过, 所以人们很放心的把自己的先人的墓安顿在他那守墓人能看好这片墓 ...

  10. 『题解』洛谷P3376 【模板】网络最大流

    Problem Portal Portal1:Luogu Description 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. Input 第一行包含四个正整数\(N,M,S,T\),分 ...