问题描述
帮同学做个作业,顺便记录一下,代码先放在下面了,有空补个解析
从 [电影天堂](https://www.dytt8.net.cn/)的某一个其中一个分类中爬取一页的数据,统计其中每一个电影的名称及演员。
网址:
https://www.dytt8.net.cn/index.php/vod/show/id/6.html
分析过程
-
打开网页,可以看到一大堆电影的图片和名字,但是我们所需要的数据需要点击图片来看详情(这里就不列图了,不懂为什么传不上来)。
-
按浏览器的F12,我这个是edge,Chrome的没记错在下面出现,选择elements,就可以看到网页的源代码了。
-
然后来分析一下每一个内容的详情在哪里,简单的看一下HTML,Edge在左侧网页端会在代码对应的界面位置产生 一些标记,所以可以很快捷地找到描述每一个电影的图片的代码在哪里,本网页的如下图所示。
-
随便打开这些标签为li的其中一个,可以看到其中的herf属性(即点击它的链接)如图所示,简单的观察一下其它的li,会发现也是一样的结构。
-
获取详情子网页列表,通过lxml中的etree库对HTML文件进行读取,通过其中的xpath进行解析,具体的解析格式可以参考下菜鸟教程 xpath语法的讲解,通过这一步可以获得各个详情页面的相对地址的列表,相对地址指相对网站主页的地址。
data = requests.get("https://www.dytt8.net.cn/index.php/vod/show/id/6.html")
s = etree.HTML(data.text)
detail_websites = s.xpath("//a[@class = 'stui-vodlist__thumb lazyload']/@href")
- 详情页的解析
进入详情页后,同样是对HTML网页进行分析,就不做过多的赘述了,通过分析HTML可以得到,题目是 class为‘stui-content_detail’的div中的第[0]个元素的第[0]个元素中的文字,具体位置要看一下HTML文件,如果数不清楚的话也可以试一试。同样方式得到了actors的内容。
title = d.xpath("//div[@class = 'stui-content__detail']")[0][0].xpath("text()")[0]
actors = [i.xpath("text()")[0] for i in d.xpath("//div[@class = 'stui-content__detail']")[0][4]]
- 简单的防反爬机制
网站偶尔会拦截一些请求,但是拦截的不是很严格,于是可以直接写一个循环,拒绝一次就多请求就好了(虽然这样其实是一种很流氓的行为),实际上可以通过sleep()等函数的方式略微让请求慢一点,减低服务器的压力,但亲测,这个网站就算给延迟也同样会报错,就采用如下的方式了。
while(1):
try:
data = requests.get("https://www.dytt8.net.cn/index.php/vod/show/id/6.html") # 根据网页的结构,会返回每一个电影的详情界面的链接,组成一个列表
break
except:
continue
完整代码
import requests
from lxml import etree
import time
def get_detail(d):
# 传入一个etree 解析出里面的电影名和人名 不同页面结构相同 所以直接索引
title = d.xpath("//div[@class = 'stui-content__detail']")[0][0].xpath("text()")[0]
actors = [i.xpath("text()")[0] for i in d.xpath("//div[@class = 'stui-content__detail']")[0][4]]
return title,actors
#主页网址 后面会用到
main_address = "https://www.dytt8.net.cn"
flag = 1 # 网站有防爬机制 这个作为未成功标志 继续获取
# 获取网页数据
while(1):
try:
data = requests.get("https://www.dytt8.net.cn/index.php/vod/show/id/6.html") # 根据网页的结构,会返回每一个电影的详情界面的链接,组成一个列表
break
except:
continue
# 获取到每一个电影详情的网址
s = etree.HTML(data.text)
detail_websites = s.xpath("//a[@class = 'stui-vodlist__thumb lazyload']/@href")
buffer = []
for num,i in enumerate(detail_websites):
# 获取数据
while(1):
try:
data_temp = requests.get(main_address + i)
break
except:
continue
# 数据解析
tree = etree.HTML(data_temp.text)
buffer.append(get_detail(tree))
print("已抓取%d个信息,标题为%s"%(num + 1, buffer[-1][0]))
data_temp.close()
# 保存数据
f = open("data.csv","w",encoding="utf-8")
for i,j in buffer:
f.write(i)
f.write("\t")
for i in j[1:-1]:
f.write(i)
f.write(",")
f.write(j[-1])
f.write("\n")
f.close()