python抓取豆瓣热门电影

开始学习爬虫了,虽然很久一年前就断断续续开始看了,但一直没正式写过爬虫代码。今天开始实战!首先从豆瓣电影入手吧。 1、信息量大。 2、不用登陆就可以抓取。

豆瓣电影TOP250

用浏览器打开豆瓣电影TOP250页面,按F12开启开发者模式,分析页面结构。

  • 每页有25条电影,共有10页。
  • 电影列表在页面上的位置为一个class属性为grid_view的ol标签中。
  • 每条电影信息放在这个ol标签的一个li标签里。

具体方法参考此博文。 抓取结果在我的Github仓库里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<ol class="grid_view">
<li>
<div class="item">
<div class="pic">...</div>
<div class="info">
<div class="hd">
<a href="https://movie.douban.com/subject/1292052/" class="">
<span class="title">肖申克的救赎</span>
<span class="title">The Shawshank Redemption</span>
<span class="other">月黑高飞(港) / 刺激1995(台)</span>
</a>
</div>
<div class="bd">...</div>
</div>
</div>
</li>
<li>
...
</li>

热门分类电影

热门分类电影位于电影排行榜页面右侧的分类排行榜下,点击不同的分类,会发现生成页面的方式与[Top250]不同,列表信息并没有写入HTML源码中,而是动态传递的。

纪录片为例,网址为: https://movie.douban.com/typerank?type_name=%E7%BA%AA%E5%BD%95%E7%89%87&type=1&interval_id=100:90&action=。

可以看出他是通过GET方法传参,共四个属性:

  • type_name = 纪录片
  • type = 1
  • interval_id = 100:90 //获取好于100%~90%同类电影的电影
  • action = 空

查看网页代码,虽然可以在源码里找到电影信息,但通过爬虫获取该页面代码时,这部分却是空,选择开发者模式中的NetWork标签并刷新该页面,分析网络文件,发现疑似请求 https://movie.douban.com/j/chart/top_list?type=1&interval_id=100%3A90&action=&start=0&limit=20 ,此请求会返回Json结构的结果。

分析请求参数:

  • 地址 : https://movie.douban.com/j/chart/top_list
  • type = 1 //与[纪录片]类型一致
  • interval_id=100:90
  • action=空
  • start=0 //从第0项开始
  • limit=20 //一共20条

通过以上分析得知,如果我们获取[纪录片]类型的前100名,请求如下: https://movie.douban.com/j/chart/top_list?type=1&interval_id=100:90&action=&start=0&limit=100 。

抓取结果在我的GitHub仓库里。

获取Top250电影源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import requests
from bs4 import BeautifulSoup
import codecs

DOWNLOAD_URL = 'http://movie.douban.com/top250'

def download_page(url):
data = requests.get(url).content
return data

def getDoubanMovieT250():
url = DOWNLOAD_URL

with codecs.open('movie','wb',encoding='utf-8') as fp:
while url:
html = download_page(url)
movies,url = parse_html(html)
fp.write(u'{movies}\n'.format(movies='\n'.join(movies)))


def parse_html(html):
movie_name_list = []
soup = BeautifulSoup(html,"html.parser")
movie_list_soup = soup.find('ol',attrs={'class':'grid_view'})
print movie_list_soup.prettify().encode('utf-8')
for movie_li in movie_list_soup.find_all('li'):
detail = movie_li.find('div',attrs={'class':'hd'})
movie_name = detail.find('span',attrs={'class':'title'}).getText()
movie_name_list.append(movie_name)

next_page = soup.find('span', attrs={'class': 'next'}).find('a')
if next_page:
return movie_name_list, DOWNLOAD_URL + next_page['href']
return movie_name_list, None

if __name__ == '__main__':
getDoubanMovieT250()

获取热门分类电影源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# encoding=utf-8
import requests
from bs4 import BeautifulSoup
import codecs
import json

DOWNLOAD_URL = {
u'纪录片':u'https://movie.douban.com/j/chart/top_list?type=1&interval_id=100:90&action=&start=0&limit=100',
u'传记':u'https://movie.douban.com/j/chart/top_list?type=2&interval_id=100:90&action=&start=0&limit=100',
u'犯罪':u'https://movie.douban.com/j/chart/top_list?type=3&interval_id=100:90&action=&start=0&limit=100',
u'历史':u'https://movie.douban.com/j/chart/top_list?type=4&interval_id=100:90&action=&start=0&limit=100',
u'动作':u'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&start=0&limit=100',
u'情色':u'https://movie.douban.com/j/chart/top_list?type=6&interval_id=100:90&action=&start=0&limit=100',
u'歌舞':u'https://movie.douban.com/j/chart/top_list?type=7&interval_id=100:90&action=&start=0&limit=100',
u'儿童':u'https://movie.douban.com/j/chart/top_list?type=8&interval_id=100:90&action=&start=0&limit=100',
u'悬疑':u'https://movie.douban.com/j/chart/top_list?type=10&interval_id=100:90&action=&start=0&limit=100',
u'剧情':u'https://movie.douban.com/j/chart/top_list?type=11&interval_id=100:90&action=&start=0&limit=100',
u'灾难':u'https://movie.douban.com/j/chart/top_list?type=12&interval_id=100:90&action=&start=0&limit=100',
u'爱情':u'https://movie.douban.com/j/chart/top_list?type=13&interval_id=100:90&action=&start=0&limit=100',
u'音乐':u'https://movie.douban.com/j/chart/top_list?type=14&interval_id=100:90&action=&start=0&limit=100',
u'冒险':u'https://movie.douban.com/j/chart/top_list?type=15&interval_id=100:90&action=&start=0&limit=100',
u'奇幻':u'https://movie.douban.com/j/chart/top_list?type=16&interval_id=100:90&action=&start=0&limit=100',
u'科幻':u'https://movie.douban.com/j/chart/top_list?type=17&interval_id=100:90&action=&start=0&limit=100',
u'运动':u'https://movie.douban.com/j/chart/top_list?type=18&interval_id=100:90&action=&start=0&limit=100',
u'惊悚':u'https://movie.douban.com/j/chart/top_list?type=19&interval_id=100:90&action=&start=0&limit=100',
u'恐怖':u'https://movie.douban.com/j/chart/top_list?type=20&interval_id=100:90&action=&start=0&limit=100',
u'战争':u'https://movie.douban.com/j/chart/top_list?type=22&interval_id=100:90&action=&start=0&limit=100',
u'短片':u'https://movie.douban.com/j/chart/top_list?type=23&interval_id=100:90&action=&start=0&limit=100',
u'喜剧':u'https://movie.douban.com/j/chart/top_list?type=24&interval_id=100:90&action=&start=0&limit=100',
u'动画':u'https://movie.douban.com/j/chart/top_list?type=25&interval_id=100:90&action=&start=0&limit=100',
u'同性':u'https://movie.douban.com/j/chart/top_list?type=26&interval_id=100:90&action=&start=0&limit=100',
u'西部':u'https://movie.douban.com/j/chart/top_list?type=27&interval_id=100:90&action=&start=0&limit=100',
u'家庭':u'https://movie.douban.com/j/chart/top_list?type=28&interval_id=100:90&action=&start=0&limit=100',
u'武侠':u'https://movie.douban.com/j/chart/top_list?type=29&interval_id=100:90&action=&start=0&limit=100',
u'古装':u'https://movie.douban.com/j/chart/top_list?type=30&interval_id=100:90&action=&start=0&limit=100',
u'黑色电影':u'https://movie.douban.com/j/chart/top_list?type=31&interval_id=100:90&action=&start=0&limit=100'
}

def download_page(url):
data = requests.get(url).content
return data

def getDoubanMovieT250():
for title in DOWNLOAD_URL.keys():
url = DOWNLOAD_URL[title]
filename = title+'.txt'
with codecs.open(filename,'wb',encoding='utf-8') as fp:
while url:
html = download_page(url)
movies,url = parse_html(html)
for movie in movies:
fp.write(u'{movies_title} {movies_url}\n'.format(movies_title=movie['title'],movies_url=movie['url']))
#fp.write(html.decode('utf-8'))


def parse_html(html):
movie_name_list = []
json_data = json.loads(html)

for movie_list in json_data:
movie_name = {'title':movie_list['title'],
'url':movie_list['url']}
movie_name_list.append(movie_name)

return movie_name_list,None


if __name__ == '__main__':
getDoubanMovieT250()