这是全栈数据工程师养成攻略系列教程的第九期:9 实战 爬取豆瓣电影数据。

掌握了爬虫的基本原理和代码实现,现在让我们通过实战项目巩固一下。

确定目标

在写爬虫之前应当想清楚:我需要哪方面的数据?需要包含哪些字段?这些数据需要以何种形式呈现?

很多网站往往都是大家爬取的对象,例如提供住房信息的链家网,提供书评和影评信息的豆瓣网,以及提供餐饮生活娱乐信息的大众点评网。当然,这些网站之所以能很容易地被我们爬取,也是因为它们采取了内容开放的运营态度,没有进行过多的反爬处理。

有一个挺有意思的名词叫做“三月爬虫”,即在三月份左右频繁出现的大量小规模爬虫。这些爬虫从何而来?因为在每年的这个时候,学生们都要做课设项目了,没有数据怎么办?嗯,靠爬!

其实爬虫和反爬虫之间就好比矛与盾的关系,我们可以花更多的心思、时间和成本去爬取数据,数据运营方同样可以花更多的技术、金钱和人力以保护数据。识别代码请求并禁止,我们可以伪装成浏览器;对IP频繁请求采取限制,我们可以使用IP代理池;要求登录并输入复杂的验证码,我们同样可以模拟登录以及想出相应的解决办法。总而言之,没有一定能爬到的数据,也没有一定爬不到的数据,无非是攻守双方的博弈,看谁下的功夫更深、投入成本更多。

当然,之前介绍的都是最基础的爬取方法,所针对的也是采取开放运营态度,或者暂未采取防爬措施的网站。方法虽简单,但依旧足以爬取相当多的网站,至于爬虫的进一步深入研究,则需要花费更多时间去学习,这也是为什么有专业的爬虫工程师这一方向了。

在这次的项目实战中,我们需要获取豆瓣电影上的电影数据,数量自然是越多越好,每条数据应当包含电影名称、导演、演员、类型、片长、语言、上映时间、上映地区、评分等信息,这样在获取数据并存储之后便可进行后续分析和展示。

通用思路

写爬虫时往往会遵循以下通用思路:首先得找到一个汇总页,以链家网为例,可以是首页或搜索页。在汇总页中是一条条房源,以列表形式依次排列,可能一页会安排几十条房源,看完之后可以通过翻页功能跳转至下一页,从而进行对全部房源的浏览;汇总页中的每一个链接都对应一条房源的详情页,点进去即可查看房源的详细信息。这些详情页都是用同样的模版渲染出来的,只不过渲染时使用了不同的数据,因此十分便于批量获取,只要对详情页的页面结构进行分析和提取即可。

当然,以上所提的二层结构是最理想的情况,实际问题中未必能找到这样一个能直接涵盖并通往全部详情页的汇总页,因此三层、四层乃至更复杂的结构也完全可能出现。例如从链家的首页开始,先下钻到城市,再深入到地区,接着按户型进行分类,最后才能找到所对应的房源。其实我们会发现,每一层结构都对应着最终详情页的一个字段,例如房源的城市、地区、户型等信息,多层结构无非只是对二层结构按照若干个字段进行了逐层聚合,所以只要理清楚网站数据的整理结构,接下来的代码工作都是类似的。

寻找链接

回到这次的项目实战上,我们首先访问一下豆瓣电影的首页,https://movie.douban.com/,探探路子,看看该如何去寻找之前提及的汇总页和详情页。

我们首先看到豆瓣提供了一个正在热映模块,展示当前正在上映的一些电影。由于我们希望尽可能多地获取电影数据,当然包括历史电影,所以这块忽略不计。

接下来的页面中有一个按电影分类进行筛选的模块,如下图所示,可以根据热门、最新、经典、可播放等标签显示相应的电影。按热度排序、按时间排序和按评价排序意义不大,希望我们希望获得尽可能多的电影数据全集,对排序则不关心。再往下有个加载更多的按钮,我们会发现每次点击之后,页面上就会出现更多对应类别的电影,说明网页相应地又向服务端请求了更多数据。

所以爬取的基本思路有了,首先获得全部的类别标签,然后针对每个标签不断地请求相应的电影数据,最后从每部电影的详情页获取所需的字段。让我们用Chrome开发者工具来找出应当请求哪些链接,打开开发者工具之后刷新豆瓣电影首页,我们会发现在Network的XHR中有这么个链接,https://movie.douban.com/j/search_tags?type=movie,从名字上来看似乎是返回电影标签,在浏览器中访问果不其然,得到了以下内容:

{"tags":["热门","最新","经典","可播放","豆瓣高分","冷门佳片","华语","欧美","韩国","日本","动作","喜剧","爱情","科幻","悬疑","恐怖","动画"]}

说明这是一个GET类型的API,返回一个json格式的字符串,如果在Python中加载成字典之后,则包含一个键tags,对应的值是一个列表,里面的每一项都是一个电影标签。

我们还顺便发现了另一个GET类API,https://movie.douban.com/j/search_subjects?type=movie&tag=热门&sort=recommend&page_limit=20&page_start=0,可以根据提供的标签、排序方法、每页数量、每页开始编号等参数返回相应的电影数据,这里是按推荐程度排名,从0号开始,返回热门标签下的20条电影数据。在浏览器中访问以上链接,得到的也是一个json格式字符串,同样转成Python字典再处理即可。如果点击加载更多按钮,会发现网页会继续请求这个API,不同的只是page_start不断增加,通过改变开始编号即可请求到新的数据。

设计下代码实现的过程:针对每个标签,使用以上第二个API不断请求数据,如果请求结果中包含数据,则将page_start增加20再继续,直到返回结果为空,说明这一标签下的电影数据已经全部拿到。

代码实现

我们已经掌握了如何用Python发起GET和POST请求,所以接下来的工作就是写代码实现。

# 加载库

import urllib

import urllib2

import json

from bs4 import BeautifulSoup

# 获取所有标签

tags = []

url = 'https://movie.douban.com/j/search_tags?type=movie'

request = urllib2.Request(url=url)

response = urllib2.urlopen(request, timeout=20)

result = response.read()

# 加载json为字典

result = json.loads(result)

tags = result['tags']

# 定义一个列表存储电影的基本信息

movies = []

# 处理每个tag

for tag in tags:

start = 0

# 不断请求,直到返回结果为空

while 1:

# 拼接需要请求的链接,包括标签和开始编号

url = 'https://movie.douban.com/j/search_subjects?type=movie&tag=' + tag + '&sort=recommend&page_limit=20&page_start=' + str(start)

print url

request = urllib2.Request(url=url)

response = urllib2.urlopen(request, timeout=20)

result = response.read()

result = json.loads(result)

# 先在浏览器中访问一下API,观察返回json的结构

# 然后在Python中取出需要的值

result = result['subjects']

# 返回结果为空,说明已经没有数据了

# 完成一个标签的处理,退出循环

if len(result) == 0:

break

# 将每一条数据都加入movies

for item in result:

movies.append(item)

# 使用循环记得修改条件

# 这里需要修改start

start += 20

# 看看一共获取了多少电影

print len(movies)

以上代码运行完毕之后,列表movies中即包含了全部的电影数据,其中的每一项都是一个字典,包含rate评分、title电影标题、url详情页链接、playable是否可播放、cover封面图片链接、id电影的豆瓣id、is_new是否为新电影等字段。

除了以上字段,我们还希望获取每部电影的更多信息,因此需要进一步爬取各部电影所对应的详情页。以下是《疯狂动物城》的豆瓣详情页,导演、编剧、主演、类型、语言、片长、简介等,都是值得进一步爬取的字段。

由于电影详情页的url类型属于Html,即访问后返回经浏览器渲染的网页内容,所以需要更加复杂的处理方法。BeautifulSoup包提供了解析html文本、查找和选择html元素、提取元素内容和属性等功能,但要求一些html和css语法基础。这里仅以详情页中的电影简介为例,展示下如何使用BeautifulSoup解析html文本,其他完整内容等后续章节介绍了相关基础后再回过头讲解。

import time

# 请求每部电影的详情页面

for x in xrange(0, len(movies)):

url = movies[x]['url']

request = urllib2.Request(url=url)

response = urllib2.urlopen(request, timeout=20)

result = response.read()

# 使用BeautifulSoup解析html

html = BeautifulSoup(result)

# 提取电影简介

# 捕捉异常,有的电影详情页中并没有简介

try:

description = html.find_all("span", attrs={"property": "v:summary"})[0].get_text()

except Exception, e:

# 没有提取到简介,则简介为空

movies[x]['description'] = ''

else:

# 将新获取的字段填入movies

movies[x]['description'] = description

finally:

pass

# 适当休息,避免请求频发被禁止,报403 Forbidden错误

time.sleep(0.5)

最后,可以将获取的电影数据写入txt文件,以便后续使用。

fw = open('douban_movies.txt', 'w')

# 写入一行表头,用于说明每个字段的意义

fw.write('title^rate^url^cover^id^description\n')

for item in movies:

# 用^作为分隔符

# 主要是为了避免中文里可能包含逗号发生冲突

fw.write(item['title'] + '^' + item['rate'] + '^' + item['url'] + '^' + item['cover'] + '^' + item['id'] + '^' + item['description'] + '\n')

fw.close()

其他内容

这次的实战其实是我一个Github项目的一部分,https://github.com/Honlan/data-visualize-chain。这个项目以豆瓣电影为例,展示了如何进行数据获取、清洗、存储、分析和可视化,和爬虫相关的代码都在spider文件夹下。所以如果希望了解更多,以及对BeautifulSoup用法感兴趣,可以进一步研究。

另外,以上代码最终获取了五千部左右的电影数据,明显少于豆瓣电影的总量,说明之前所使用的API能获取的数据量十分有限。那应该怎么办呢?在豆瓣电影的网站上找一找,会发现这么个链接,https://movie.douban.com/tag/,点进去之后简直是到了一个崭新的世界。在这个页面中提供了各种分类标签,每个标签下的电影数量也十分惊人,全部爬取一遍能收获的数据量必然相当可观。所以只要按照之前所讲的通用思路,类似地写代码爬取即可。

视频链接:

python实现爬虫探探_全栈 - 9 实战 爬取豆瓣电影数据相关推荐

  1. Python爬虫新手入门教学(一):爬取豆瓣电影排行信息

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

  2. 【爬虫实践】记一次Scrapy框架入门使用爬取豆瓣电影数据

    本次的学习分享主要是使用一次Scrapy框架,毕竟在很多次的时候,自己在提取一些或是需要实验数据的时候,数据量要求不大,很快便能通过简单的request等库进行调用,然后获取数据. 这次,则是想要使用 ...

  3. python3[爬虫基础入门实战] 爬取豆瓣电影排行top250

    先来张爬取结果的截图 再来份代码吧 # encoding=utf8 import requests import re from bs4 import BeautifulSoup from tkint ...

  4. 爬虫案例:ajax异步加载,爬取豆瓣电影排行榜

    from urllib.request import Request,urlopen from fake_useragent import UserAgent #导入相应的库 base_url ='h ...

  5. 小白都能看明白的Python网络爬虫、附上几个实用的爬虫小例子: 爬取豆瓣电影信息和爬取药监局

    文章目录 网络爬虫 爬虫的基础知识 爬虫分类 requests模块 爬虫的简单案例 简单的收集器 爬取豆瓣电影信息 爬取药监局 返回数据类型 数据解析 爬取糗事百科图片(正则表达式) xpath解析数 ...

  6. python爬虫豆瓣电影评价_使用爬虫爬取豆瓣电影影评数据Python版

    在 使用爬虫爬取豆瓣电影影评数据Java版 一文中已详细讲解了爬虫的实现细节,本篇仅为展示Python版本爬虫实现,所以直接上代码 完整代码 爬虫主程序 # 爬虫启动入口 from C02.data ...

  7. python爬取豆瓣电影信息_Python爬虫入门 | 爬取豆瓣电影信息

    这是一个适用于小白的Python爬虫免费教学课程,只有7节,让零基础的你初步了解爬虫,跟着课程内容能自己爬取资源.看着文章,打开电脑动手实践,平均45分钟就能学完一节,如果你愿意,今天内你就可以迈入爬 ...

  8. python爬取豆瓣电影top250_Python爬虫 - scrapy - 爬取豆瓣电影TOP250

    0.前言 新接触爬虫,经过一段时间的实践,写了几个简单爬虫,爬取豆瓣电影的爬虫例子网上有很多,但都很简单,大部分只介绍了请求页面和解析部分,对于新手而言,我希望能够有一个比较全面的实例.所以找了很多实 ...

  9. ChatGPT全栈开发实战:从需求分析到数据可视化,一站式指南助你快速构建全面应用

    <ChatGPT全栈开发实战:从需求分析到数据可视化,一站式指南助你快速构建全面应用>是一本旨在引领我们进入全栈开发世界的综合指南.通过结合强大的ChatGPT技术和全栈开发的实践,我们将 ...

最新文章

  1. BCH三小时缓慢出块——需要重视的小概率事件
  2. 如何在TortoiseGit中使用ssh-keygen生成的key
  3. IDA插件uEmu模拟执行
  4. ADB server didn't ACK
  5. svn命令行工具安装使用(windows)
  6. FineReport单行与数据库交互的方法
  7. 医药电商平台解决方案
  8. CSDN去广告,超清爽界面
  9. Java类加载机制,类加载过程,类加载器以及双亲委派详解
  10. 充电口 米兔积木机器人_米兔积木机器人怎么充电
  11. 【docker容器常用操作】
  12. alsa 麦克风采集音频
  13. 图扑软件与华为云共同构建新型智慧工厂
  14. VS2005得include,library,src等路径自动设置
  15. KEIL下写代码,怎样使{}括号回车时候自动对齐?
  16. 数据库导入excel文件失败
  17. 计算机二级C语言选择题综合考查
  18. 低压电缆载流量估算一览表
  19. c语言单向链表插入字符串,C语言之单向链表
  20. teamspeak搭建_在Windows下快速配置TeamSpeak服务器

热门文章

  1. SAP FICO CBS接口-银企直连联盟收款功能开发说明书(包括测试样例、程序代码仅作参考,不保证一定可以运行)
  2. 先学c 还是先学java_小白学编程语言一开始先学c还是java?
  3. DTT的生活就是对吃的一种细细品味
  4. 大型互联网公司如何防止黑客入侵?(下)
  5. 文本 去除重复行(sublime Text3 ,正则表达式)
  6. linux sed去除重复,删除文本中的重复行(sort+uniq/awk/sed)
  7. 高德地图定位、画线 基础功能
  8. 【Python模块】matplotlib 柱状图
  9. 掌握python和js_新华字典:掌_“掌”的意思,五笔,笔画,拼音,五行_HttpCN
  10. pandas读取csv文件UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xca in position 37: invalid contin