标签(这里存放着电影的下载链接),这样我们就找到了我们所需要的全部数据了,是不是很简单啊。二、爬虫编码阶段
爬虫的程序,我一般习惯把它分成五个部分, 一是主函数,作为程序的入口,二是爬虫调度器,三是网络请求函数,四是网页解析函数,五是数据存储函数。
get_data :其参数是目标网页 url,这个函数可以模拟浏览器访问 url,获取并将网页的内容返回。
parse_data :其参数是网页的内容,这个函数主要是用来解析网页内容,筛选提取出关键的信息,并打包成列表返回。
save_data :其参数是数据的列表,这个函数用来将列表中的数据写入本地的文件中。
main :这个函数是爬虫程序的调度器,可以根据事先分析好的 url 的规则,不断的构造新的请求 url,并调用其他三个函数,获取数据并保存到本地,直到结束。
if __name__ == '__main__' :这是主程序的入口,在这里调用 main 函数,启动爬虫调度器即可。
# 我们用到的库
import requests
import bs4
import re
import pandas as pd
1. 网络请求函数 :get_data (url)
负责访问指定的 url 网页,并将网页的内容返回,此部分功能比较简单固定,一般不需要做修改(除非你要挂代理,或者自定义请求头等,可以做一些相应的调整)。
def get_data(url):
'''
功能:访问 url 的网页,获取网页内容并返回
参数:
url :目标网页的 url
返回:目标网页的 html 内容
'''
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
}
try:
r = requests.get(url, headers=headers)
r.raise_for_status()
return r.text
except requests.HTTPError as e:
print(e)
print("HTTPError")
except requests.RequestException as e:
print(e)
except:
print("Unknown Error !")
2. 网页解析函数:parse_data(html)
这个函数是整个爬虫程序的核心所在,整体思路在上一部分已经讲过了。我这里使用的库是 BeautifulSoup。
这部分的写法多种多样,有很多发挥的空间,也没有什么太多固定的模式,因为这部分的写法是要随着不同网站的页面结构来做调整的,比如说有的网站提供了数据的 api 接口,那么返回的数据就是 json 格式,我们只需要调用 json 库就可以完成数据解析,而大部分的网站只能通过从网页源代码中一层层筛选(筛选手段也多种多样,什么正则表达式,beautifulsoup等等)。
这里需要根据数据的形式来选择不同的筛选策略,所以,知道原理就可以了,习惯什么方法就用什么方法,反正最后能拿到数据就好了。
def parse_data(html):
'''
功能:提取 html 页面信息中的关键信息,并整合一个数组并返回
参数:html 根据 url 获取到的网页内容
返回:存储有 html 中提取出的关键信息的数组
'''
bsobj = bs4.BeautifulSoup(html,'html.parser')
info = []
# 获取电影列表
tbList = bsobj.find_all('table', attrs = {'class': 'tbspan'})
# 对电影列表中的每一部电影单独处理
for item in tbList:
movie = []
link = item.b.find_all('a')[1]
# 获取电影的名称
name = link["title"]
# 获取详情页面的 url
url = 'https://www.dy2018.com' + link["href"]
# 将数据存放到电影信息列表里
movie.append(name)
movie.append(url)
try:
# 访问电影的详情页面,查找电影下载的磁力链接
temp = bs4.BeautifulSoup(get_data(url),'html.parser')
tbody = temp.find_all('tbody')
# 下载链接有多个(也可能没有),这里将所有链接都放进来
for i in tbody:
download = i.a.text
movie.append(download)
#print(movie)
# 将此电影的信息加入到电影列表中
info.append(movie)
except Exception as e:
print(e)
return info
3. 数据存储函数:save_data(data)
这个函数目的是将数据存储到本地文件或数据库中,具体的写法要根据实际需要的存储形式来定,我这里是将数据存放在本地的 csv 文件中。
当然这个函数也并不只能做这些事儿,比如你可以在这里写一些简单的数据处理的操作,比如说:数据清洗,数据去重等操作。
def save_data(data):
'''
功能:将 data 中的信息输出到文件中/或数据库中。
参数:data 将要保存的数据
'''
filename = 'Data/电影天堂/动作片.csv'
dataframe = pd.DataFrame(data)
dataframe.to_csv(filename, mode='a', index=False, sep=',', header=False)
4. 爬虫调度器:main()
这个函数负责根据 url 生成规则,构造新的 url 请求,然后依次调用网络请求函数,网页解析函数,数据存储函数,爬取并保存该页数据。
所谓爬虫调度器,就是控制爬虫什么时候开始爬,多少只爬虫一起爬,爬哪个网页,爬多久休息一次,等等这些事儿。
def main():
# 循环爬取多页数据
for page in range(1, 114):
print('正在爬取:第' + str(page) + '页......')
# 根据之前分析的 URL 的组成结构,构造新的 url
if page == 1:
index = 'index'
else:
index = 'index_' + str(page)
url = 'https://www.dy2018.com/2/'+ index +'.html'
# 依次调用网络请求函数,网页解析函数,数据存储函数,爬取并保存该页数据
html = get_data(url)
movies = parse_data(html)
save_data(movies)
print('第' + str(page) + '页完成!')
5. 主函数:程序入口
主函数作为程序的入口,只负责启动爬虫调度器。
这里我一般习惯在 main() 函数前后输出一条语句,以此判断爬虫程序是否正常启动和结束。
if __name__ == '__main__':
print('爬虫启动成功!')
main()
print('爬虫执行完毕!')
三、程序运行结果
运行了两个小时左右吧,终于爬完了 113 页,共 3346 部动作片电影的数据(本来不止这些的,但是有一些电影没有提供下载链接,我在 excel 中排序后直接手动剔除了)。
然后想看什么电影的话,直接复制这些电影下载的磁力链接,到迅雷里面下载就好啦。
四、爬虫程序的一些小优化
1. 在网站提供的下载链接中,我试了一下,发现 magnet 开头的这类链接放在迅雷中可以直接下载,而 ftp 开头的链接在迅雷中总显示资源获取失败(我不知道是不是我打开的方式不对,反正就是下载不来),于是我对程序做了一些小的调整,使其只获取 magnet 这类的链接。
修改的方式也很简单,只需要调整 网页解析函数 即可(爬虫的五个部分是相对独立的,修改时只需调整相应的模块即可,其余部分无需修改)。
def parse_data(html):
'''
功能:提取 html 页面信息中的关键信息,并整合一个数组并返回
参数:html 根据 url 获取到的网页内容
返回:存储有 html 中提取出的关键信息的数组
'''
bsobj = bs4.BeautifulSoup(html,'html.parser')
info = []
# 获取表头信息
tbList = bsobj.find_all('table', attrs = {'class': 'tbspan'})
for item in tbList:
movie = []
link = item.b.find_all('a')[1]
name = link["title"]
url = 'https://www.dy2018.com' + link["href"]
try:
# 查找电影下载的磁力链接
temp = bs4.BeautifulSoup(get_data(url),'html.parser')
tbody = temp.find_all('tbody')
for i in tbody:
download = i.a.text
if 'magnet:?xt=urn:btih' in download:
movie.append(name)
movie.append(url)
movie.append(download)
#print(movie)
info.append(movie)
break
except Exception as e:
print(e)
return info
注意代码 26 行处,我加了一个 if 语句的判断,如果下载链接中包含 magnet:?xt=urn:btih 字符串,则视为有效链接,下载下来,否则跳过。
2. 我一直在想能不能有个办法让迅雷一键批量下载我们爬到的电影。使用 python 操纵第三方的软件,这其实挺难的。不过后来找到了一种方法,也算是解决了这个问题。
就是我们发现迅雷软件启动后,会自动检测我们的剪切板,只要我们复制了下载链接,它便会自动弹出下载的提示框。借助这个思路,我们可以使用代码,将下载的链接复制进入剪切板,等下载框自动出现后,手动确认开始下载(这是我目前想到的最好的办法了,不知道各位大佬有没有更好的思路,欢迎指导交流)。
import pyperclip
import os
import pandas as pd
imageData = pd.read_csv("Data/电影天堂/动作片2.csv",names=['name','link','download'],encoding = 'gbk')
# 获取电影的下载链接,并用换行符分隔
a_link = imageData['download']
links = '\n'.join(a_link)
# 复制到剪切板
pyperclip.copy(links);
print('已粘贴');
# 打开迅雷
thunder_path = r'D:\Program Files (x86)\Thunder Network\Thunder9\Program\Thunder.exe'
os.startfile(thunder_path)
以上是“Python如何爬取并下载电影天堂中的3千多部电影”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联成都网站设计公司行业资讯频道!
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
网站标题:Python如何爬取并下载电影天堂中的3千多部电影-创新互联
当前链接: