当萌生一个好想法时,连饥饿都能一时忘却,因为这个中饭拖成了晚饭。对一个爱看电影的人来说,电影也算一大享受和兴趣,我打开平日喜欢去的电影天堂找电影看,首先让我不爽的就是广告了,然后才能找找哪些电影是自己想看的,点来点去还得自己手动复制,真的好繁琐。因此我想把一小部分链接信息抓下来,再写个简单方便的UI让我随时使用。
心中想起了 I CAN DO THIS
先把Python脚本写出来
1.分析网站信息
-
确定爬取栏目
爬取栏目.png -
分析栏目构成
分析链接.png 是否可爬
2.构建爬取流程
- 先爬取所有电影详情页连接
- 获取对应电影详情页信息
- 保留电影标题和下载实体链
- 根据电影栏目分别存放成json数据
3.开始写脚本
#coding=utf-8
import requests
import re
import os
import json
import time
class Getlinks(object):
def __init__(self, url):
self.url = url
self.headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36"
}
self.dir_path = os.path.dirname(os.path.abspath(__file__))
self.path = self.dir_path + '/json'
DirectoryisExists = os.path.exists(self.path)
# 创建目录
if not DirectoryisExists:
os.makedirs(self.path)
print("\t| 初始化完成")
# 解析url地址
def ParseUrl(self):
for i in self.url:
# 抓取电影链接
print("\t| 开始抓取页面跳转链接")
list_link = self.Graplinks(i)
print("\t| "+i['catgory']+"页面链接抓取完成")
print("\t| 开始抓取电影详细信息")
info_dict = self.Grapinfo(i['catgory'], list_link)
print("\t| "+i['catgory']+"页面抓取完成")
print("\t| 开始写入json文件")
self.Writetojson(info_dict, i['catgory_as'])
print("\t| 文件写入完成")
# 抓取详情页链接
def Graplinks(self, group):
name = group['catgory']
url = group['url']
count = group['count']
# 第一组url链接不规则做分步处理
if "400" in name:
return self.GetLinks(url, count, 1)
else:
return self.GetLinks(url, count)
# 获取所有链接
def GetLinks(self, url, count, flag=0):
# 延迟执行,爬的太猛对你对别人都不好
time.sleep(10)
totalurl = []
if flag == 1:
for i in range(1, count+1):
# time.sleep(1)
suffix = '.html' if i==1 else '_'+str(i)+'.html'
base_url = url + suffix
#抓取本页的超链接
try:
res = requests.get(base_url, headers=self.headers).text
links = re.findall(r'http[s]?://www.ygdy8.com/html/gndy/.*?.html', res, re.S)
# 去重
links = list(set(links))
totalurl += links
except Exception as E:
print('抓取失败的原因:'+ E)
return totalurl
else:
for i in range(1, count+1):
# time.sleep(1)
base_url = url + str(i) + '.html'
# 抓取本页的超链接
try:
res = requests.get(base_url, headers=self.headers).text
# 过滤其他文本
re_rule = 'class="co_content8"(.*?)</div>'
links_context = re.compile(re_rule, re.S).findall(res)[0]
links = re.findall(r'/html/gndy/dyzz.*?.html', links_context, re.S)
totalurl += links
except Exception as E:
print('抓取失败的原因:' + E)
for i in range(len(totalurl)):
totalurl[i] = 'https://www.dytt8.net' + totalurl[i]
return totalurl
# 抓取电影信息
def Grapinfo(self, catgroy, links):
info_json = {}
info_json["catgory"] = catgroy
info_json["count"] = len(links)
info_json["group"] = []
# 循环请求网页
for url in links:
temp = {}
try:
res = requests.get(url, headers=self.headers).text
title_re = '<div class="title_all">(.*?)</div>'
title = re.compile(title_re, re.S).findall(res)[0]
title = re.compile('#07519a>(.*?)</font></h1>', re.S).findall(title)[0]
title = title.encode('ISO-8859-1').decode('gbk')
filelink_re = '#fdfddf(.*?)</a>'
filelink = re.compile(filelink_re, re.S).findall(res)[0]
filelink = filelink.encode('ISO-8859-1').decode('gbk')
filelink = re.compile('<a href="(.*?)"', re.S).findall(filelink)[0]
print(title)
print(filelink)
# 添加纠错机制
if self.CheckVirtual(filelink) == False:
continue
temp["title"] = title
temp["filelink"] = filelink
info_json["group"].append(temp)
except Exception as E:
continue
return info_json
# 将数据存储在json文件中
def Writetojson(self, info_json, json_name):
json_name = json_name
# 将字典转换成json字符串
str_json = json.dumps(info_json, indent=4)
try:
with open('./json/' + json_name + '.json', 'w') as f:
f.write(str_json)
except Exception as E:
print("写入文件出错" + E)
f.close()
return
# 无效链接检查处理
def CheckVirtual(self, url):
return True if 'ftp' in url else False
if __name__ == '__main__':
# 初始化爬取栏目数据
base_url_list = [
{
"catgory" : "IMDB评分8分左右影片400多部",
"catgory_as" : "imdb",
"url" : "https://www.dytt8.net/html/gndy/jddy/20160320/50523",
"count" : 4
},
{
"catgory": "最新电影",
"catgory_as": "zuixin",
"url": "https://www.dytt8.net/html/gndy/dyzz/list_23_",
"count": 50
},
{
"catgory": "欧美电影",
"catgory_as": "oumei",
"url": "https://www.dytt8.net/html/gndy/oumei/list_7_",
"count": 50
},
{
"catgory": "国内电影",
"catgory_as": "china",
"url": "https://www.dytt8.net/html/gndy/china/list_4_",
"count": 50
},
{
"catgory": "日韩电影",
"catgory_as": "rihan",
"url": "https://www.dytt8.net/html/gndy/rihan/list_6_",
"count": 40
}
]
Context = Getlinks(base_url_list)
Context.ParseUrl()
# 联系作者:2910169601
4.遇到的主要问题
其中卡我时间最长的是编码问题,所爬取网页是GB2312编码的,爬取下来是乱码,不管怎么转码都不对。最后用encode('ISO-8859-1').decode('gbk')解决了乱码问题。
世间麻烦千千万,唯有编码独一道。
5.总结
遇到问题不要慌,先喝口水冷静冷静。
biubiubiu.gif