forked from xingag/spider_python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spider_dytt.py
211 lines (163 loc) · 5.72 KB
/
spider_dytt.py
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/usr/bin/env python
# encoding: utf-8
"""
@version: v1.0
@author: xag
@license: Apache Licence
@contact: [email protected]
@site: http://www.xingag.top
@software: PyCharm
@file: 4.dytt.py
@time: 2018/9/16 18:46
@description:爬电影天堂【 lxml + xpath + requests】【2018新片精品,包含更多】
"""
import requests
from lxml import etree
import time
# url = 'http://www.dytt8.net/html/gndy/dyzz/list_23_1.html'
# 主页地址
BASE_DOMAIN = 'http://www.dytt8.net'
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36',
}
def get_detail_urls(url):
"""
获取电影详情页面的url
:param url: 每一页电影列表的地址url
:return:
"""
response = requests.get(url, headers=HEADERS)
# 注意:右键查看源代码,charset=gb2312" 编码方式【网站编码不规范,解码必须用响应的编码方式进行解码】
# print(response.content.decode('gbk'))
# html_element = etree.HTML(response.content.decode('gbk'))
# 注意:电影天堂第3页使用默认的gbk会有乱码,这里使用默认的解码方式【href为英文,解析不会受影响】
html_element = etree.HTML(response.text)
# 【数据 - 字符串列表】详情页面地址
# 所有class为tbspan的table标签/子孙标签中的a标签的href属性
detail_urls = html_element.xpath('//table[@class="tbspan"]//a/@href')
# 深拷贝一份列表数据,实现一变遍历列表,一边删除列表数据
# 过滤掉【综合电影】导致的脏数据
detail_urls_new = detail_urls
for index, detail_url in enumerate(detail_urls_new):
if detail_url == '/html/gndy/jddy/index.html':
detail_urls.remove(detail_url)
# print(detail_urls)
# print(BASE_DOMAIN + detail_url)
# 组装详情页面的地址
detail_urls = map(lambda x: BASE_DOMAIN + x, detail_urls)
return detail_urls
def parse_detail_page(detail_url):
"""
解析电影详情页面
:param detail_url: 详情页面的地址
:return:
"""
response = requests.get(detail_url, headers=HEADERS)
text = response.content.decode('gbk')
html_element = etree.HTML(text)
# 【数据 - 电影标题】
title = html_element.xpath('//div[@class="title_all"]//font[@color="#07519a"]/text()')[0]
# 获取zoom标签
zoom_element = html_element.xpath('//div[@id="Zoom"]')[0]
# 【数据 - 电影封面和电影截图】
imgs = zoom_element.xpath(".//img/@src")
# 注意:为了避免脏数据导致应用挂掉,提前初始化
year, country, type, rating, duration, director, actors, cover, screen_shot, download_url = '', '', '', '', '', '', '', '', '', ''
if len(imgs) > 0:
cover = imgs[0]
# 【数据 - 电影截图】
if len(imgs) > 1:
screen_shot = imgs[1]
# 获取div[@id='zoom']标签下面的所有的文本数据【子孙所有的text文本数据】
infos = zoom_element.xpath('.//text()')
# 解析具体内容的函数
def parse_info(info, rule):
return info.replace(rule, '').strip()
# 遍历infos每一项去获取有用的数据
for key, info in enumerate(infos):
# print('遍历第{}项'.format(key))
# print(info)
# print('结束==================================================')
if info.startswith('◎年 代'):
# 年代
year = parse_info(info, '◎年 代')
elif info.startswith('◎产 地'):
# 产地
country = parse_info(info, '◎产 地')
elif info.startswith('◎类 别'):
# 类别
type = parse_info(info, '◎类 别')
elif info.startswith('◎豆瓣评分'):
# 豆瓣评分
rating = parse_info(info, '◎豆瓣评分')
elif info.startswith('◎片 长'):
# 片长
duration = parse_info(info, '◎片 长')
elif info.startswith('◎导 演'):
# 导演
director = parse_info(info, '◎导 演')
elif info.startswith('◎主 演'):
# 演员【第一个演员】
actor_first = parse_info(info, '◎主 演')
actors = [actor_first]
# 继续往下面遍历
for index in range(key + 1, len(infos)):
item = infos[index].strip()
if item.startswith('◎简 介'):
break
# 获取所有的演员
# print(item)
actors.append(item)
elif info.startswith('◎简 介'):
# desc = parse_info(info, '◎简 介')
for index in range(key + 1, len(infos)):
item = infos[index].strip()
if item.startswith('【下载地址】'):
break
desc = item
print(detail_url)
# 下载地址
if len(html_element.xpath('//td[@bgcolor="#fdfddf"]/a/text()')) > 0:
download_url = html_element.xpath('//td[@bgcolor="#fdfddf"]/a/text()')[0]
elif len(html_element.xpath('//td[@bgcolor="#fdfddf"]/text()')) > 0:
download_url = html_element.xpath('//td[@bgcolor="#fdfddf"]/text()')[0]
film = {
'title': title,
'cover': cover,
'screen_shot': screen_shot,
'year': year,
'country': country,
'type': type,
'rating': rating,
'duration': duration,
'director': director,
'actors': actors,
'desc': desc,
'download_url': download_url
}
return film
def spider():
"""
爬虫的入口
:return:
"""
base_url = 'http://www.dytt8.net/html/gndy/dyzz/list_23_{}.html'
films = []
# 1.获取第1-10页的数据
for index in range(1, 11):
print('开始爬第{}页'.format(index))
# 2.电影列表的地址url
url = base_url.format(index)
# 3.获取当前页面包含的所有电影【详情地址】
detail_urls = get_detail_urls(url)
# 4.解析每一项电影的详情页面
for key, detail_url in enumerate(detail_urls):
# print('索引:' + str(key) + ',地址:' + detail_url)
# print('解析详情页面:' + detail_url)
film = parse_detail_page(detail_url)
films.append(film)
# 5.每爬取一页,就休眠2秒钟
time.sleep(1)
print(films)
if __name__ == '__main__':
spider()