xiaoyu's blog

Coding for a better life!

0%

Python爬取IMDB TOP 250 电影榜单

“互联网电影资料库(英语:Internet Movie Database,简称IMDb)是一个关于电影演员、电影、电视节目、电视艺人、电子游戏和电影制作小组的在线数据库。”

IMDB TOP 250收录了世界上排名最高的250部电影,接下来写一个爬虫把这些电影收录起来。

首选语言当然是用世界上最流行的编程语言—Python了。

我用到两个库:requests、openpyxl,前者主要用来处理网络请求,后者用来操作excel文件。

安装:

1
2
pip install requests
pip install openpyxl

这个页面就是top 250电影榜单了https://www.imdb.com/chart/top,

分析一下网页元素,可以把排名、电影名(英文)、上映年份这几项提取出来,写一个正则表达式:

1
pat = r'<td class="titleColumn">\s*(.*)..*\s*.*\s*title=".*" >(.*)</a>.*\s*<span class="secondaryInfo">\((.*)\)</span>'

预保存一下数据

1
res = find_all_by_pat(pat, imdb_doc)

拿到这几项之后还需要中文的电影名,资料来源我找的是豆瓣,下面这个地址可以得到一个非异步加载的页面,这样的话虽然比直接拿纯数据(通过网站的api拿纯数据有点麻烦,即使拿到了也很快就会被ban掉)慢一点,但是简单方便

1
url = 'https://www.douban.com/search?cat=1002&q=%s' % query_name

观察网页可以发现,影片名很容易出现在相关电影这一栏下的第一行,我试了一下不能保证100%正确,但在大多情况下是准确的,这个办法会出现匹配不了的情况,但这样情况不多,在接受范围之内,这样最起码比手动收集快了很多倍,分析一下源码,得到如下正则:

1
pat2 = r'qcat.*\s*.*>(.*?)\s*</a>'

接下来一边访问一边插入数据就行了

现在数据已经完整,最后一步,创建一个excel文件,简单设置一下样式

1
2
3
4
wb = Workbook()
sheet = wb.active
sheet.column_dimensions['B'].width = 60
sheet.column_dimensions['C'].width = 25

插入数据:

1
2
3
for i in range(len(res)):
for j in range(len(res[i])):
sheet.cell(row=i + 1, column=j + 1).value = res[i][j]

最后保存文件:

1
wb.save('imdb.xlsx')

打开文件,数据全部拿到了(^▽^)

附上完整代码:

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
70
71
72
73
74
75
76
import random
import re
import requests
from openpyxl import Workbook
from time import sleep


def find_all_by_pat(pat, string):
res = re.findall(pat, string)
return res


def get_html_doc(url):
pro = ['122.152.196.126', '114.215.174.227', '119.185.30.75']
head = {
'user-Agent': 'Mozilla/5.0(Windows NT 10.0;Win64 x64)AppleWebkit/537.36(KHTML,like Gecko) chrome/58.0.3029.110 Safari/537.36'
}
resopnse = requests.get(url, proxies={'http': random.choice(pro)}, headers=head)
resopnse.encoding = 'utf-8'
html_doc = resopnse.text
return html_doc


def get_douban_html(query_name):
url = 'https://www.douban.com/search?cat=1002&q=%s' % query_name
douban_search_res = get_html_doc(url)
return douban_search_res


def get_chinese_name(pat, doc):
res_list = find_all_by_pat(pat, doc)
try:
return res_list[1]
except:
return ' '


def get_director_name(pat, doc):
res = find_all_by_pat(pat, doc)
try:
return res[0].split('/')[1]
except:
return ' '


if __name__ == "__main__":
url = "https://www.imdb.com/chart/top"
imdb_doc = get_html_doc(url)
pat = r'<td class="titleColumn">\s*(.*)..*\s*.*\s*title=".*" >(.*)</a>.*\s*<span class="secondaryInfo">\((.*)\)</span>'
res = find_all_by_pat(pat, imdb_doc)

# pat1 = '>(.*)\s*</a>\s*<span class="ic-mark ic-movie-mark">可播放</span>'
pat2 = r'qcat.*\s*.*>(.*?)\s*</a>'
pat3 = '<span\s*class="subject-cast">(.*)</span>'
for i in range(len(res)):
doc = get_douban_html(res[i][1])
chinise_name = get_chinese_name(pat2, doc)

director_name = get_director_name(pat3, doc)

res[i] = list(res[i])

res[i].insert(1, chinise_name)
res[i].insert(3, director_name)

print(res[i])
sleep(random.random() * 1.2)

wb = Workbook()
sheet = wb.active
sheet.column_dimensions['B'].width = 60
sheet.column_dimensions['C'].width = 25
for i in range(len(res)):
for j in range(len(res[i])):
sheet.cell(row=i + 1, column=j + 1).value = res[i][j]
wb.save('imdb.xlsx')

电影详细信息可以保存我的另一篇博客: 传送门