您的位置:首页 > 编程语言 > Python开发

Python 利用requests+BeautifulSoup4编写原生爬虫,爬取电影天堂最新电影,并打造最新电影下载及查询器

2019-01-28 23:48 921 查看

可能有许多人有这样的一种烦恼,当想要查看最近更新的电影时,不得不打开电影天堂的官网进行查询(当然如果你习惯用电影天堂下载电影的话/微笑),当点击了解电影详情的时候,网页往往就切换到了广告页面,很烦有没有,我是电影天堂迷,我每天习惯的去看一看有更新啥高分电影,所以花了一点时间写了一个下载及查询器,这样我就不用打开电脑浏览器便可进行查询和下载。

效果演示

首先进行一下效果的演示:

  1. 菜单显示

    这是操作界面,在后面我会给出具体的程序操作流程供简单了解!
  2. 最新电影显示
  3. 继续操作【YES】—>输入查询电影序号:


    最后询问是否下载,若是则选择所下载的电影序号下载,若否返回开始操作;

3.2若是刚才继续操作【NO】—>询问是否不看详情直接下载

最后询问是否下载,若是则下载,若否返回开始操作;

  1. 输入4直接查看电影详情,—>将显示电影列表供用户选择: —>选择查看电影序号:—>同样将询问用户是否下载:

  2. 页面切换,切换后可执行以上菜单中任意选项:

程序执行流程图:

程序代码:

import os
import sys
#import traceback#调试时使用

import re
from bs4 import BeautifulSoup
import requests

class GetMovieInfo():

"""获取每个电影的主题,url链接以及下载链接"""

def __init__(self,page=''):
self.headers = {
'User-Agent':''
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
self.url = 'https://www.dy2018.com/html/gndy/dyzz/index' + page +'.html'

def get_root_html(self):

"""获取主页面的html代码"""

self.response = requests.get(self.url,headers=self.headers)
self.response.encoding ='gb2312'#电影网页编码为gb2312
html = self.response.text
return html

def analysis_root_html(self):

"""分析主页面的html的代码,获取电影主题以及电影url"""

soup = BeautifulSoup(self.get_root_html(),'lxml-xml')#用lxml解析xml网页,该网页直接用lxml解析不全
html_part1 = soup.select('ul b a')#标准选择器选择
for part in html_part1:
root_url = part['href']
movie_title = part['title']
yield {
'title':movie_title,
'root_url':root_url
}

def get_movie_html(self):

"""获取每个电影的html代码"""

for item in self.analysis_root_html():
root_url = 'https://www.dy2018.com' + item['root_url']
html = requests.get(root_url)
html.encoding = 'gb2312'
html = html.text
yield html

def analysis_movie_html(self):

"""分析电影页面的html并获取下载链接"""

for item in self.get_movie_html():
soup = BeautifulSoup(item,'lxml')
html_part2 = soup.select('td a')
march = re.compile('<a.*?"(.*?)">',re.S)
download_url_list = re.findall(march,str(html_part2[0]))
download_url = download_url_list[0]
yield {
'download_url':download_url
}

def integration(self):

"""将主题,电影url以及下载链接合并为一个字典,并用生成器返回"""

for x,y in zip(self.analysis_root_html(),self.analysis_movie_
2b899
html()):
x.update(y)#字典合并
yield x

class Operation(GetMovieInfo):

"""操作、显示以及下载"""

def manu(self):

"""下载器菜单显示"""

print('=' * 50)
print(' ' * 7 + '最新电影下载器v1.0')
print(' ' * 10 + '1、首页最新电影查询')
print(' ' * 10 + '2、迅雷下载(推荐大文件下载)')
print(' ' * 10 + '3、普通下载(推荐小文件下载)')
print(' ' * 10 + '4、电影详情查询')
print(' ' * 10 + '5、下一页最新电影列表操作')
print(' ' * 10 + '6、上一页最新电影列表操作')
print(' ' * 10 + '7、退出下载器')
print('=' * 50)

def search_movie(self):

"""获取电影标题,用于电影查询"""

i = 1
for item in self.integration():
item['num'] = i
i += 1
yield item

def thunder_download(self,details=None,url=None):

"""迅雷下载"""

if details == None:
download_url = url
else:
download_url = details[0].get('download_url')
os.system(r"D:\软件安装\Program\Thunder.exe -StartType:DesktopIcon %s"%download_url )#################
return None

def common_download(self,url):

"""普通下载,并显示下载进度条"""

response = requests.get(url)
file = '{}\{}'.format('C:\\Users\\CUI-sir\\Desktop',url[url.rfind('/')+1:])
print(file)
total_size = int(response.headers['Content-Length'])
temp_size = 0
with open(file,'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
temp_size += len(chunk)
f.write(chunk)
f.flush()
q = (temp_size/total_size)*100
p = int((temp_size/total_size)*50)
sys.stdout.write('█'*p + '%.2f'%q + ' %')
print('')
print('下载完成')
def write_2_file(self):
pass

def search_movie_detail(self,num=None):

"""电影详情搜索"""

for item in self.search_movie():
items = []
if num == item.get('num'):
movie_url = 'https://www.dy2018.com' + item.get('root_url')
movie_html = requests.get(movie_url)
movie_html.encoding = 'gb2312'
movie_html = movie_html.text
soup = BeautifulSoup(movie_html,'lxml')
html_part1 = soup.select('#Zoom p')
for text in html_part1:
detail_infor = text.get_text()
items.append(detail_infor)
return item,items

def show(self,num=1,details=None):

"""各类操作显示"""

if num == 1:
print('最近更新电影如下:')
for item in self.search_movie():
title = item.get('title')
num = item.get('num')
print('< ' + str(num) + ' >' + '-----' + title)

if num == 2:
print('已转至迅雷下载')

if num == 3:
pass

elif num == 4:
for item in details[1]:
print(item)

def main(self):

"""入口方法,用与用户输入操作及控制"""

global i#定义全局变量用于控制页数,避免被初始化
try:
self.change_num = int(input('请输入操作序号:'))
if self.change_num == 1:
self.search_movie()
self.show(self.change_num)
order = input('是否进行电影详情操作[YES/NO]:')
if order.upper() == 'YES':
num = int(input('请输入想要查询的电影序号:'))
details = self.search_movie_detail(num)
self.show(4,details)
order2 = input('是否进行迅雷下载电影[YES/NO]:')
if order2.upper() == 'YES':
self.thunder_download(details)
self.show(2)
self.main()
else:
self.main()
else:
order2 = input('是否直接进行迅雷下载电影[YES/NO]:')
if order2.upper() == 'YES':
num = int(input('请输入想要直接下载的电影序号:'))
details = self.search_movie_detail(num)
self.thunder_download(details)
self.show(2)
self.main()
else:
self.main()

elif self.change_num == 2:
dowload_url = input('请复制下载地址(支持所有格式下载):')
self.thunder_download(url=dowload_url)
self.show(self.change_num)
self.main()

elif self.change_num == 3:
url = input('请输入下载地址(不支持第三方下载链接):')
self.common_download(url)
self.show(self.change_num)
self.main()

elif self.change_num == 4:
self.show(1)
num = int(input('请输入想要查询的电影序号:'))
details = self.search_movie_detail(num)
self.show(self.change_num,details)
order2 = input('是否进行迅雷下在电影[YES/NO]:')
if order2.upper() == 'YES':
self.thunder_download(details)
self.main()
else:
self.main()

elif self.change_num == 5:
i +=1
print('当前页数为第%d'%i)
page = '_' + str(i)
a = Operation(page)
a.main()

elif self.change_num == 6:
i -= 1
print('当前页数为第%d' % i)
if i == 1:
b = Operation()
b.main()
elif i >= 2:
page = '_' + str(i)
c = Operation(page)
c.main()
elif i<= 0:
print('此页是首页无法进行上一页操作!')
self.main()
i = 1

elif self.change_num == 7:
sys.exit()

except Exception:
#print(traceback.format_exc())#调试程序时使用,可以显示调试错误信息且不中断程序
print('请输入正确的操作号!')
self.main()

if __name__ == '__main__':#执行
i = 1
movie = Operation()#实例化
movie.manu()
movie.main()

彩蛋:

在程序里加了一些用户输入错误的判断,防止因为用户的输入不规范导致程序崩溃,同时在普通下载中加入了下载进度的显示,用于查看下载进度(效果如下):
最后,若有不足请多多包含,可以向我指出,我会改正滴,谢谢!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: