“互联网电影资料库(英语: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 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')
|
电影详细信息可以保存我的另一篇博客: 传送门